# HG changeset patch # User Chris Cannam # Date 1537189541 -3600 # Node ID 55d9bbf1fe45d8a30e0d66cd6361b020d6034f77 # Parent 246bdf94ef7bf3a8441468d01fdb9b013738a096# Parent c6728590731926239bdc3651ccc6acedb6f8da30 Merge from default branch diff -r 246bdf94ef7b -r 55d9bbf1fe45 .appveyor.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.appveyor.yml Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,18 @@ + +image: + - Visual Studio 2017 + +configuration: + - Release + +install: + - cinst --allow-empty-checksums smlnj + - ps: '"[hostfingerprints]" | Out-File -Encoding "ASCII" -Append $env:USERPROFILE\mercurial.ini' + - ps: '"code.soundsoftware.ac.uk = 66:ef:e2:0e:e3:55:93:9a:33:aa:2a:e9:fe:be:21:c2:a2:8d:4f:f1" | Out-File -Encoding "ASCII" -Append $env:USERPROFILE\mercurial.ini' + - ps: '"[hostsecurity]" | Out-File -Encoding "ASCII" -Append $env:USERPROFILE\mercurial.ini' + - ps: '"code.soundsoftware.ac.uk = code.soundsoftware.ac.uk:fingerprints=sha256:64:75:f6:47:15:de:b4:51:ea:96:e2:f4:8a:f5:53:a5:11:c8:dd:82:73:5d:bd:54:18:cb:c8:9d:10:37:28:85" | Out-File -Encoding "ASCII" -Append $env:USERPROFILE\mercurial.ini' + +build_script: + - deploy\win64\build-and-package.bat + + diff -r 246bdf94ef7b -r 55d9bbf1fe45 .hgignore --- a/.hgignore Mon Sep 17 13:53:25 2018 +0100 +++ b/.hgignore Mon Sep 17 14:05:41 2018 +0100 @@ -26,3 +26,34 @@ .DS_Store *.stash cov-int/* +*.deb +test-svcore-base +test-svcore-data-fileio +test-svcore-data-model +vamp-plugin-sdk +svcore +svgui +svapp +checker +piper +piper-cpp +dataquay +bqvec +bqfft +bqresample +bqaudioio +sv-dependency-builds +icons/scalable +vamp-plugin-load-checker +piper-vamp-simple-server +piper-convert +*.msi +*.user +glob:.vext* +glob:.repoint* +build_win32 +build_win64 +*.AppImage +*.AppDir +Dockerfile*.gen +squashfs-root diff -r 246bdf94ef7b -r 55d9bbf1fe45 .hgsub --- a/.hgsub Mon Sep 17 13:53:25 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -vamp-plugin-sdk = https://code.soundsoftware.ac.uk/hg/vamp-plugin-sdk -svcore = https://code.soundsoftware.ac.uk/hg/svcore -svgui = https://code.soundsoftware.ac.uk/hg/svgui -svapp = https://code.soundsoftware.ac.uk/hg/svapp -dataquay = https://bitbucket.org/breakfastquay/dataquay -bqvec = https://bitbucket.org/breakfastquay/bqvec -bqfft = https://bitbucket.org/breakfastquay/bqfft -bqresample = https://bitbucket.org/breakfastquay/bqresample -bqaudioio = https://bitbucket.org/breakfastquay/bqaudioio -sv-dependency-builds = https://code.soundsoftware.ac.uk/hg/sv-dependency-builds -icons/scalable = https://code.soundsoftware.ac.uk/hg/sv-iconset -checker = https://code.soundsoftware.ac.uk/hg/vamp-plugin-load-checker -piper-cpp = https://code.soundsoftware.ac.uk/hg/piper-cpp diff -r 246bdf94ef7b -r 55d9bbf1fe45 .hgsubstate --- a/.hgsubstate Mon Sep 17 13:53:25 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -e7ef7f547cac52afe4f3496040b9f5e7ca8247f5 bqaudioio -048fd8ba184040d217f33a9ea3cbdc5676a2876f bqfft -1735a488ded2bbd0f1a60cd33c4c26b3672e49a2 bqresample -9fd9745307e54a53cbd09cb67a4f9783d1b02ed2 bqvec -1eefc20919cd080b684b2bbbc0af7270b8facb54 checker -3768bdde6fdf866aa63fff5bde8d9fa64a8979ef dataquay -c37b5598a4beb570417716e30aa649c78312169f icons/scalable -0000000000000000000000000000000000000000 piper-cpp -5f67a29f0fc7f1b908f7cde4866173a7af337862 sv-dependency-builds -2683a8ca36ea55b90917713571b9cef6cc049b5f svapp -710e6250a4016c6057407814001f6f3ea8d843b5 svcore -13d9b422f7fef21a013329d081123e7191401824 svgui -0eebd22a081a824067bf3d5de65326696feab653 vamp-plugin-sdk diff -r 246bdf94ef7b -r 55d9bbf1fe45 .hgtags --- a/.hgtags Mon Sep 17 13:53:25 2018 +0100 +++ b/.hgtags Mon Sep 17 14:05:41 2018 +0100 @@ -50,3 +50,33 @@ 2868d5abf1a3baa37099c1b5d7e984bf8bb8177a sv_v2.4.1 94253fa113183075c8400fa64d0ccb0e81682f90 sv_v2.5 e206741df37ddfa3db28bfbbe4b79f2248b92695 sv_v2.5_osx_deploy +e6c7585863feeba4d278c770314e3455e0020bdb last_v2.5_on_default_branch +3173259cdcc67cb687fb9d62f6a945a86bc7ea77 sv_v3.0beta1 +7a8e909a15da99ff87928a0be0475f214a450d14 sv_v3.0beta2 +7a8e909a15da99ff87928a0be0475f214a450d14 sv_v3.0beta2 +b6f1052dbda12b33c5bc0ea4ae33d4764da10b31 sv_v3.0beta2 +881d7f99bba33a35852bd0dcfa19367f6b306e14 sv_v3.0beta3 +2f13bdee5cb541f22ac6567ba55faf2aa23277df sv_v3.0beta4 +2f13bdee5cb541f22ac6567ba55faf2aa23277df sv_v3.0beta4 +d739444d2c489f79572017902e9b5b4ec961cbbe sv_v3.0beta4 +811fbe905f5e4f3114a8024c0a8d45f9d4ff838d sv_v3.0rc1 +c3380c78811fbcaf1dae5f4b08d1a0db05bc2820 sv_v3.0 +cbaac283f47ea7f21e83612cf0931b26ea29c213 sv_v3.0.1 +cbaac283f47ea7f21e83612cf0931b26ea29c213 sv_v3.0.1 +96a5cf264033195f52613f6fce02398ae3efa020 sv_v3.0.1 +96a5cf264033195f52613f6fce02398ae3efa020 sv_v3.0.1 +fad5960ac61a2cead83ff1b57072cb0634bf6f4e sv_v3.0.1 +38c40fe5135b8220e39cf2a6ba52f43bd40168b9 sv_v3.0.2 +8d2d9a4f5d5264ed6c738ff7b36f3a9e1729d5aa sv_v3.0.3 +038f024c8390b1aa83b7f60af8319066f7794f79 sv_v3.1pre1 +643768964863741124a66a8d55002d1ff95d8c43 sv_v3.1pre2 +643768964863741124a66a8d55002d1ff95d8c43 sv_v3.1pre2 +1fda47827e0e12cd83c172de8384e8136d9c4ca2 sv_v3.1pre2 +a38a8c4746c27ad5eae055ffa3f141a816f9e7a2 sv_v3.1pre3 +2ea9537868d50ba1a4d4cd54ac3bdeb10b9f4de0 sv_v3.1pre4 +2ea9537868d50ba1a4d4cd54ac3bdeb10b9f4de0 sv_v3.1pre4 +b465eb7018bcc0add14886ac57d4f79f38401b8f sv_v3.1pre4 +f4d7c9522fcff88292ed2b91bc89b30eeaa6794c sv_v3.1 +4ff2193314d406c3a83c86b409414cf60a0b1406 sv_v3.1.1 +4ff2193314d406c3a83c86b409414cf60a0b1406 sv_v3.1.1 +690eaf241ad5f57e4ed59f09c0f4c1ce659b5571 sv_v3.1.1 diff -r 246bdf94ef7b -r 55d9bbf1fe45 .travis.yml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.travis.yml Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,33 @@ +language: + - cpp + +matrix: + include: + - os: osx + osx_image: xcode9 + - os: linux + dist: trusty + sudo: required + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libbz2-dev libfftw3-dev libfishsound1-dev libid3tag0-dev liblo-dev liblrdf0-dev libmad0-dev liboggz2-dev libpulse-dev libsamplerate-dev libsndfile-dev libsord-dev libxml2-utils portaudio19-dev qt5-default libqt5svg5-dev raptor-utils librubberband-dev autoconf libtool git mlton + +before_install: + - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then brew update ; fi + - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then brew install polyml ; fi + - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then brew install qt5 ; fi + - if [[ "$TRAVIS_OS_NAME" = "osx" ]] ; then export PATH=$PATH:/usr/local/opt/qt5/bin ; fi + - ( cd ../ ; git clone https://github.com/sandstorm-io/capnproto ) + - ( cd ../capnproto/ ; git checkout v0.6.1 ) + - ( cd ../capnproto/c++ ; autoreconf -i ) + - ( cd ../capnproto/c++ ; ./configure && make && sudo make install ) + +before_script: + - if [[ "$TRAVIS_OS_NAME" = "linux" ]] ; then ./configure ; else ./repoint install && qmake -r sonic-visualiser.pro ; fi + +script: + - make -j3 + - if [[ "$TRAVIS_OS_NAME" = "linux" ]] ; then ./deploy/linux/deploy-appimage.sh ; fi diff -r 246bdf94ef7b -r 55d9bbf1fe45 CHANGELOG --- a/CHANGELOG Mon Sep 17 13:53:25 2018 +0100 +++ b/CHANGELOG Mon Sep 17 14:05:41 2018 +0100 @@ -1,4 +1,157 @@ -Changes in Sonic Visualiser 2.5 since the previous release 2.4.1: + +Changes in Sonic Visualiser 3.2 since the previous release 3.1.1: + + - Add feature to convert and import audio from a CSV data file + + +Changes in Sonic Visualiser 3.1.1 (Aug 2018) since the previous release 3.1: + + - Fix failure to record correctly into an empty session with certain + audio drivers + + - Fix failure to run LADSPA plugins at all, except with some unusual + path layouts + + - Fix failure to silence sonified notes when rewinding backwards or + jumping back from a loop endpoint + + - Fix macOS .dmg image so as to use older HFS+ filesystem for compatibility + + +Changes in Sonic Visualiser 3.1 (July 2018) since the previous release 3.0.3: + + - Add Plugins tab to Preferences dialog, from which you can review + the plugin load paths and see which plugins were loaded from which + locations, and also customise load paths (though the various path + environment variables are still supported) + + - Stream the export of audio data and other CSV data so that + very large exports don't hang the UI or run us out of memory + (thanks to Lucas Thompson) + + - Ensure vertical scale appears for auto-align layers when there is + nothing else to auto-align them to + + - Fix another long-standing Windows-platform wide-char/utf8 + conversion problem, with environment variable naming and contents + + - Improve handling of incomplete session loads, i.e. situations where + the audio files referred to by a session could not be found - + previously the session could be re-saved immediately thus losing + the audio reference; now at least we disable Save (enabling only + Save As) and show a warning + + - Update pane and layer menu shortcuts so that the + waveform/spectrogram/etc shortcuts (Shift+G etc) operate on the + source model in the currently-selected pane rather than the main + model. This is a backward-incompatible change but is a far more + intuitive way for the function to work + + - Use dark background for bright colours in time-value/note/etc + layers as well as e.g. waveforms - this is how it was always + "intended to" work, but it is a backward-incompatible change + + - Make "Select All" select the whole span of everything that exists, + not just the main model + + - Add horizontal scale to Spectrum layer + + - Improve spacing and labelling of vertical log scales + + - Update build system for better Cap'n Proto version support and to + use Repoint for code management in the repository + + - Various other bug fixes + + +Changes in Sonic Visualiser 3.0.3 (May 2017) since the previous release 3.0.2: + + - Improve decisions about where and how to label vertical scales + + - Update build support material and documentation to reflect the + official release of Cap'n Proto 0.6 (which we can now use rather + than depending on git builds) + + +Changes in Sonic Visualiser 3.0.2 (Mar 2017) since the previous release 3.0.1: + + - Fix crash when changing parameters for spectrum view + + - Fix incorrect measure tool crosshairs in spectrum view + + - Update Russian and Czech UI translations (thanks to Alexandre Prokoudine + and Pavel Fric respectively) + + +Changes in Sonic Visualiser 3.0.1 (Mar 2017) since the previous release 3.0: + + - Fix crashes with MIDI devices and speedup/slowdown control on Windows + + - Update MIDI input driver layer + + +Changes in Sonic Visualiser 3.0 (Mar 2017) since the previous release 2.5: + + - Add ability to record audio, and ability to change the audio device + for playback or recording in the preferences + + - Add complete support for high-resolution (Hi-DPI or retina) + displays, including for layer data rendering as well as UI controls + and icons. This makes the biggest difference when using a retina + Mac, on which previous versions did not render layer data at retina + resolution, but it also improves scaling and rendering of UI + elements on Hi-DPI displays on Windows and Linux + + - Add ability to export scalable (SVG) image files + + - Run plugins in a separate process, so that if a plugin crashes, it + no longer brings down Sonic Visualiser with it. In every other + respect the behaviour should be unchanged + + - Scan plugins on startup in a separate process, and report on any + that crash or won't load + + - Add ability to open, display, and analyse very long audio files (of + more than 2^32 sample frames) + + - Change mp3 file loading so as to compensate for encoder/decoder + delay and padding (using "gapless playback" logic). While this is a + real improvement, unfortunately it does mean that the initial + padding in mp3 file load has changed from previous versions, which + may mean some sessions saved in previous versions are no longer + correctly aligned. It's not a great idea to use mp3 as a file + format of record, because of differences like this between + decoders. The previous behaviour is still available as a preference. + + - Add new Hybrid normalisation type for spectrogram and colour 3d + plot layers. This normalises each column to its peak value and then + scales the normalised values by the log of the peak in order to + restore some distinction in scale between columns with different + levels. It can provide quite visually clear results. + + - Add function to subdivide time instant layers into regular + intervals (and its inverse) + + - Add new preference for default colour scales + + - Add a basic ability to zoom (in the frequency axis) to the spectrum + + - Switch to using combined level/pan controls in layer property boxes + and for the main volume control + + - Make CSV file reader better able to handle files with varying + numbers of columns + + - Fix a number of problems on Windows with loading and saving some + file formats to filenames not representable in system codepage + + - Add "What's New" dialog + + - Finally switch the Windows build to 64-bit by default (with + adapters to run either 32- or 64-bit plugins) + + +Changes in Sonic Visualiser 2.5 (Oct 2015) since the previous release 2.4.1: - Add unit-converter dialog, for converting between various pitch and timing units @@ -13,11 +166,13 @@ - Fix failure to export last instant in a time-instant layer -Changes in Sonic Visualiser 2.4.1 since the previous release 2.4: + +Changes in Sonic Visualiser 2.4.1 (Oct 2014) since the previous release 2.4: - Fix a crash when rendering certain colour 3d plot layers -Changes in Sonic Visualiser 2.4 since the previous release 2.3: + +Changes in Sonic Visualiser 2.4 (Sep 2014) since the previous release 2.3: - Add support for left/right scrolling using a two-finger touchpad gesture (where available) @@ -71,7 +226,7 @@ platforms. -Changes in Sonic Visualiser 2.3 since the previous release 2.2: +Changes in Sonic Visualiser 2.3 (Dec 2013) since the previous release 2.2: - Add a startup welcome dialog that also explains what SV makes network connections for and allows user to forbid them @@ -97,7 +252,7 @@ build -Changes in Sonic Visualiser 2.2 since the previous release 2.1: +Changes in Sonic Visualiser 2.2 (July 2013) since the previous release 2.1: - Build with support for hidpi ("retina") text on OS/X @@ -114,7 +269,7 @@ a new session is started -Changes in Sonic Visualiser 2.1 since the previous release 2.0.1: +Changes in Sonic Visualiser 2.1 (May 2013) since the previous release 2.0.1: - Fix incorrect handling of FixedSampleRate outputs (Vamp SDK fix) @@ -132,7 +287,7 @@ - Fix incorrect samplerate in reading m4a files on OS/X -Changes in Sonic Visualiser 2.0 since the previous release 1.9: +Changes in Sonic Visualiser 2.0 (July 2012) since the previous release 1.9: - Support 64-bit builds on OS/X (using CoreAudio instead of obsolete QuickTime audio file reader) @@ -144,7 +299,7 @@ - Add a fullscreen mode on the F11 key -Changes in Sonic Visualiser 1.9 since the previous release 1.8: +Changes in Sonic Visualiser 1.9 (Oct 2011) since the previous release 1.8: - Add session templates; save session as template; apply template to session @@ -155,7 +310,7 @@ - Various bug fixes. -Changes in Sonic Visualiser 1.8 since the previous release 1.7.2: +Changes in Sonic Visualiser 1.8 (Apr 2011) since the previous release 1.7.2: - Sonic Visualiser now registers as a file type handler on OS/X, providing better integration with the desktop generally (Dan Stowell) @@ -185,7 +340,7 @@ - A Czech translation is now included (thanks to Pavel Fric). -Changes in Sonic Visualiser 1.7.2 since the previous release 1.7.1: +Changes in Sonic Visualiser 1.7.2 (May 2010) since the previous release 1.7.1: - The time-value layer now has an origin line and an option to show derivatives (change from one point to the next) rather than @@ -198,7 +353,7 @@ fixed -Changes in Sonic Visualiser 1.7.1 since the previous release 1.7: +Changes in Sonic Visualiser 1.7.1 (Oct 2009) since the previous release 1.7: - The RDF importer does a better job of assigning labels to layers, layers to panes, and values to labelled regions @@ -215,7 +370,7 @@ - The Russian translation has been updated (thanks Alexandre) -Changes in Sonic Visualiser 1.7 since the previous release 1.6: +Changes in Sonic Visualiser 1.7 (Sep 2009) since the previous release 1.6: - A new "Insert Item At Selection" function on the Edit menu can be used to create Note and Region layer items whose time @@ -230,7 +385,7 @@ - Time values throughout the display may optionally be shown in seconds and frames at various frame rates - + - A crash on exit in Windows has been fixed - A very unobtrusive user survey is now included @@ -238,7 +393,7 @@ - Various other bug fixes. -Changes in Sonic Visualiser 1.6 since the previous release 1.5: +Changes in Sonic Visualiser 1.6 (Jun 2009) since the previous release 1.5: - The Colour 3D Plot layer now supports logarithmic vertical scale and linear interpolation options. @@ -252,7 +407,7 @@ - Various other bug fixes. -Changes in Sonic Visualiser 1.5 since the previous version 1.4: +Changes in Sonic Visualiser 1.5 (Mar 2009) since the previous release 1.4: - You can now insert time instants, time values, and notes using a MIDI device during playback. If a time value or note layer is @@ -293,7 +448,7 @@ been fixed. -New features in Sonic Visualiser 1.4 since the previous version 1.3: +Changes in Sonic Visualiser 1.4 (Dec 2008) since the previous release 1.3: - SV now has a Region layer type, used for display of features with durations. It also supports Vamp v2.0 plugins that provide durations @@ -323,7 +478,7 @@ - Several crashes and other bugs have been fixed. -Changes in Sonic Visualiser 1.3 since the previous version 1.2: +Changes in Sonic Visualiser 1.3 (Jul 2008) since the previous release 1.2: - There is a new spreadsheet-style data viewer and editor for viewing and editing the data in some types of annotation layer. @@ -342,7 +497,7 @@ - Several other bug fixes. -New features in Sonic Visualiser 1.2, since the previous version 1.0: +Changes in Sonic Visualiser 1.2 (Feb 2008) since the previous release 1.0: - SV now supports time-alignment of multiple performances of a work loaded at the same time. This option is enabled when the MATCH Vamp diff -r 246bdf94ef7b -r 55d9bbf1fe45 INSTALL.txt --- a/INSTALL.txt Mon Sep 17 13:53:25 2018 +0100 +++ b/INSTALL.txt Mon Sep 17 14:05:41 2018 +0100 @@ -1,45 +1,77 @@ -To compile from source ----------------------- +To compile Sonic Visualiser from source +======================================= -To build on a Unix-like system, run +Windows +------- -$ ./configure && make +Use the Qt Creator IDE with either the MinGW compiler (for 32-bit +builds) or Visual C++ (for 64-bit builds). -The following additional libraries are required or optional when -building the SV core libraries: +For details, see the wiki page at -REQUIRED Qt v5 http://qt-project.org/ -REQUIRED Vamp Plugin SDK v2.x http://www.vamp-plugins.org/ -REQUIRED Rubber Band Library http://www.breakfastquay.com/rubberband/ -REQUIRED libsndfile http://www.mega-nerd.com/libsndfile/ -REQUIRED libsamplerate http://www.mega-nerd.com/SRC/ -REQUIRED FFTW3 http://www.fftw.org/ -REQUIRED bzip2 library http://www.bzip.org/ -REQUIRED Sord and Serd libraries http://drobilla.net/software/ +https://code.soundsoftware.ac.uk/projects/sonic-visualiser/wiki/WindowsBuild30 -Optional MAD mp3 decoder http://www.underbit.com/products/mad/ -Optional Oggz and fishsound http://xiph.org/oggz/ -Optional liblo OSC library http://www.plugin.org.uk/liblo/ -If you are going to build the rest of the SV libraries and the Sonic -Visualiser application, you will also need one or more of: +MacOS +----- -Optional JACK http://www.jackaudio.org/ -Optional PortAudio v19 http://www.portaudio.com/ -Optional PulseAudio http://www.pulseaudio.org/ +Build from the command line, but don't use the configure script. +Instead install Qt v5.x and run + +$ ./repoint install +$ qmake -r # you may need to use the full path to your Qt qmake here +$ make + + +Linux +----- + +$ ./configure && make && make install + +The following additional libraries are required or optional: + +REQUIRED Qt v5 http://qt-project.org/ +REQUIRED Vamp Plugin SDK v2.x http://www.vamp-plugins.org/ +REQUIRED Rubber Band Library http://www.breakfastquay.com/rubberband/ +REQUIRED libsndfile http://www.mega-nerd.com/libsndfile/ +REQUIRED libsamplerate http://www.mega-nerd.com/SRC/ +REQUIRED FFTW3 http://www.fftw.org/ +REQUIRED bzip2 library http://www.bzip.org/ +REQUIRED Sord and Serd libraries http://drobilla.net/software/ +REQUIRED Cap'n Proto http://capnproto.org/ + +Optional MAD mp3 decoder http://www.underbit.com/products/mad/ +Optional Oggz and fishsound http://xiph.org/oggz/ +Optional liblo OSC library http://www.plugin.org.uk/liblo/ +Optional JACK http://www.jackaudio.org/ +Optional PortAudio v19 http://www.portaudio.com/ +Optional PulseAudio http://www.pulseaudio.org/ Although JACK, PortAudio, and PulseAudio are individually optional, -you will need to have one or the other of them in order to get any -audio playback. Usually JACK is preferred on Linux, with PulseAudio -as a backup, and PortAudio is used elsewhere. +you will need to have at least one of them in order to get any audio +playback. Usually JACK is preferred on Linux, with PulseAudio as a +backup, and PortAudio is used elsewhere. On Linux, you will need the ALSA libraries (used for MIDI). -If you happen to be using a Debian-based Linux, you probably want to -apt-get install something like the following packages: qtbase5-dev -qt5-default libsndfile1-dev libsamplerate0-dev libfftw3-dev libbz2-dev -libjack-dev libjack0 libpulse-dev libmad0-dev libid3tag0-dev -liboggz2-dev libfishsound1-dev libasound2-dev liblo-dev liblrdf0-dev -libsord-dev libserd-dev vamp-plugin-sdk librubberband-dev. +For Cap'n Proto, currently you will need the v0.6 release which (if +not available as a package) can be obtained from the releases page on +Github. To build it, you might do something like +$ curl -L -o capnproto-v0.6.0.tar.gz https://github.com/sandstorm-io/capnproto/archive/v0.6.0.tar.gz +$ tar xf capnproto-v0.6.0.tar.gz +$ cd capnproto-0.6.0/c++ +$ autoreconf -i +$ ./configure --enable-static --disable-shared +$ make && make install + +For the rest, if you happen to be using a Debian-based Linux, you +probably want to apt install something like the following packages: + +build-essential libbz2-dev libfftw3-dev libfishsound1-dev +libid3tag0-dev liblo-dev liblrdf0-dev libmad0-dev liboggz2-dev +libpulse-dev libsamplerate-dev libsndfile-dev libsord-dev +libxml2-utils portaudio19-dev qt5-default libqt5svg5-dev raptor-utils +librubberband-dev git mercurial autoconf automake libtool + diff -r 246bdf94ef7b -r 55d9bbf1fe45 README --- a/README Mon Sep 17 13:53:25 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ - -Sonic Visualiser -================ - -Sonic Visualiser is a program for viewing and analysing the contents -of music audio files. - -With Sonic Visualiser you can: - - * Load audio files in various formats (WAV/AIFF, plus Ogg and mp3 -if compiled in) and view their waveforms - - * Look at audio visualisations such as spectrogram views, with -interactive adjustment of display parameters - - * Annotate audio data by adding labelled time points and defining -segments, point values and curves - - * Run feature-extraction plugins to calculate annotations -automatically, using algorithms such as beat trackers, pitch -detectors and so on (see http://vamp-plugins.org/) - - * Import annotation data from various text formats and MIDI files - - * Play back the original audio with synthesised annotations, taking -care to synchronise playback with the display position - - * Slow down and speed up playback and loop segments of interest, -including seamless looping of complex non-contiguous areas - - * Export annotations and audio selections to external files. - -Sonic Visualiser can also be controlled remotely using the Open Sound -Control (OSC) protocol (if support is compiled in). - - -Credits -------- - -Sonic Visualiser was developed at the Centre for Digital Music, -Queen Mary, University of London. - - http://c4dm.eecs.qmul.ac.uk/ - -Sonic Visualiser was written by Chris Cannam with contributions from -Christian Landone, Mathieu Barthet, Dan Stowell, Jesus Corral Garcia, -Matthias Mauch, and Craig Sapp. - -Code copyright 2005-2007 Chris Cannam and copyright 2006-2016 Queen -Mary, University of London, except where indicated in the individual -source files. - -This work was partially funded by the European Commission through the -SIMAC project IST-FP6-507142 and the EASAIER project IST-FP6-033902. - -This work was partially funded by the Arts and Humanities Research -Council through its Research Centre for the History and Analysis of -Recorded Music (CHARM). - -This work was partially funded by the Engineering and Physical -Sciences Research Council through the OMRAS2 project EP/E017614/1, the -Musicology for the Masses project EP/I001832/1, and the Sound Software -project EP/H043101/1. - -Sonic Visualiser is free software; you can redistribute it and/or modify -it under the terms of the 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 the file COPYING included with -this distribution for more information. - -Sonic Visualiser may also make use of the following libraries: - - * Qt5 -- Copyright Digia Oyj, distributed under the LGPL - * JACK -- Copyright Paul Davis, Jack O'Quin et al, under the LGPL - * PortAudio -- Copyright Ross Bencina, Phil Burk et al, BSD license - * Ogg decoder -- Copyright CSIRO Australia, BSD license - * MAD mp3 decoder -- Copyright Underbit Technologies Inc, GPL - * libsamplerate -- Copyright Erik de Castro Lopo, GPL - * libsndfile -- Copyright Erik de Castro Lopo, LGPL - * FFTW3 -- Copyright Matteo Frigo and MIT, GPL - * Rubber Band -- Copyright Chris Cannam, GPL - * Vamp plugin SDK -- Copyright Chris Cannam and QMUL, BSD license - * LADSPA plugin SDK -- Copyright Richard Furse et al, LGPL - * RtMIDI -- Copyright Gary P. Scavone, BSD license - * Dataquay -- Copyright Breakfast Quay, BSD license - * Sord and Serd -- Copyright David Robillard, BSD license - * Redland -- Copyright Dave Beckett and the University of Bristol, LGPL/Apache license - * liblo OSC library -- Copyright Steve Harris, GPL - -(Some distributions of Sonic Visualiser may have one or more of these -libraries statically linked.) Many thanks to their authors. - - -Compiling Sonic Visualiser --------------------------- - -If you are planning to compile Sonic Visualiser from source code, -please read the file INSTALL.txt. - - -More information ----------------- - -For more information about Sonic Visualiser, please go to - - http://www.sonicvisualiser.org/ - diff -r 246bdf94ef7b -r 55d9bbf1fe45 README.OSC --- a/README.OSC Mon Sep 17 13:53:25 2018 +0100 +++ b/README.OSC Mon Sep 17 14:05:41 2018 +0100 @@ -167,11 +167,10 @@ gain whose values are linear multipliers (i.e. 1.0 == unity gain). - speedup - takes a value of a percentage increase in playback - speed, so 0 is the default playback speed, 100 sets double - the default speed, and -100 sets half the default speed - (yes, I know, it's nonsense, sorry). + speed + takes a value of a percentage change in playback + speed, so 100 is the default playback speed, 200 sets + double the default speed, and 50 sets half the default. overlays controls the verbosity level of the text overlays on diff -r 246bdf94ef7b -r 55d9bbf1fe45 README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,121 @@ + +Sonic Visualiser +================ + +#### A program for viewing and analysing the contents of music audio files + +![Sonic Visualiser small screenshot](http://sonicvisualiser.org/images/sv-3.0-win-thumb.png) + +* Home page and downloads: http://sonicvisualiser.org/ +* Code project: https://code.soundsoftware.ac.uk/projects/sonic-visualiser + +With Sonic Visualiser you can: + + * Load audio files in various formats (WAV/AIFF, plus Ogg and mp3 +if compiled in) and view their waveforms + + * Look at audio visualisations such as spectrogram views, with +interactive adjustment of display parameters + + * Annotate audio data by adding labelled time points and defining +segments, point values and curves + + * Run feature-extraction plugins to calculate annotations +automatically, using algorithms such as beat trackers, pitch +detectors and so on (see http://vamp-plugins.org/) + + * Import annotation data from various text formats and MIDI files + + * Play back the original audio with synthesised annotations, taking +care to synchronise playback with the display position + + * Slow down and speed up playback and loop segments of interest, +including seamless looping of complex non-contiguous areas + + * Export annotations and audio selections to external files. + +Sonic Visualiser can also be controlled remotely using the Open Sound +Control (OSC) protocol (if support is compiled in). + + +Credits +------- + +Sonic Visualiser was developed at the Centre for Digital Music, +Queen Mary, University of London. + + http://c4dm.eecs.qmul.ac.uk/ + +Sonic Visualiser was written by Chris Cannam with contributions from +Christian Landone, Mathieu Barthet, Dan Stowell, Jesus Corral Garcia, +Matthias Mauch, and Craig Sapp. + +Code copyright 2005-2007 Chris Cannam and copyright 2006-2018 Queen +Mary, University of London, except where indicated in the individual +source files. + +Russian translation provided by Alexandre Prokoudine, copyright +2006-2018 Alexandre Prokoudine. + +Czech translation provided by Pavel Fric, copyright 2010-2018 Pavel +Fric. + +This work was partially funded by the European Commission through the +SIMAC project IST-FP6-507142 and the EASAIER project IST-FP6-033902. + +This work was partially funded by the Arts and Humanities Research +Council through its Research Centre for the History and Analysis of +Recorded Music (CHARM). + +This work was partially funded by the Engineering and Physical +Sciences Research Council through the OMRAS2 project EP/E017614/1, the +Musicology for the Masses project EP/I001832/1, and the Sound Software +project EP/H043101/1. + +Sonic Visualiser is free software; you can redistribute it and/or modify +it under the terms of the 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 the file COPYING included with +this distribution for more information. + +Sonic Visualiser may also make use of the following libraries: + + * Qt5 -- Copyright The Qt Company, distributed under the LGPL + * JACK -- Copyright Paul Davis, Jack O'Quin et al, under the LGPL + * PortAudio -- Copyright Ross Bencina, Phil Burk et al, BSD license + * Ogg decoder -- Copyright CSIRO Australia, BSD license + * MAD mp3 decoder -- Copyright Underbit Technologies Inc, GPL + * libsamplerate -- Copyright Erik de Castro Lopo, BSD license + * libsndfile -- Copyright Erik de Castro Lopo, LGPL + * FFTW3 -- Copyright Matteo Frigo and MIT, GPL + * Rubber Band -- Copyright Particular Programs Ltd, GPL + * Vamp plugin SDK -- Copyright Chris Cannam and QMUL, BSD license + * LADSPA plugin SDK -- Copyright Richard Furse et al, LGPL + * RtMIDI -- Copyright Gary P. Scavone, BSD license + * Dataquay -- Copyright Particular Programs Ltd, BSD license + * Sord and Serd -- Copyright David Robillard, BSD license + * Redland -- Copyright Dave Beckett and the University of Bristol, LGPL/Apache license + * liblo OSC library -- Copyright Steve Harris, GPL + * Cap'n Proto -- Copyright Sandstorm Development Group, Inc, BSD license + +(Some distributions of Sonic Visualiser may have one or more of these +libraries statically linked.) Many thanks to their authors. + + +Compiling Sonic Visualiser +-------------------------- + +If you are planning to compile Sonic Visualiser from source code, +please read the file INSTALL.txt. + + * Linux and macOS CI build: [![Build Status](https://travis-ci.org/sonic-visualiser/sonic-visualiser.svg?branch=master)](https://travis-ci.org/sonic-visualiser/sonic-visualiser) + * Windows CI build: [![Build status](https://ci.appveyor.com/api/projects/status/26pygienkigw39p7?svg=true)](https://ci.appveyor.com/project/cannam/sonic-visualiser) + + +More information +---------------- + +For more information about Sonic Visualiser, please go to + + http://www.sonicvisualiser.org/ + diff -r 246bdf94ef7b -r 55d9bbf1fe45 acinclude.m4 --- a/acinclude.m4 Mon Sep 17 13:53:25 2018 +0100 +++ b/acinclude.m4 Mon Sep 17 14:05:41 2018 +0100 @@ -261,3 +261,54 @@ fi ]) +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff -r 246bdf94ef7b -r 55d9bbf1fe45 base.pri --- a/base.pri Mon Sep 17 13:53:25 2018 +0100 +++ b/base.pri Mon Sep 17 14:05:41 2018 +0100 @@ -23,7 +23,7 @@ INCLUDEPATH += $$SV_INCLUDEPATH # Platform defines for RtMidi -linux*: DEFINES += __LINUX_ALSASEQ__ +linux*: DEFINES += __LINUX_ALSASEQ__ __LINUX_ALSA__ macx*: DEFINES += __MACOSX_CORE__ win*: DEFINES += __WINDOWS_MM__ solaris*: DEFINES += __RTMIDI_DUMMY_ONLY__ @@ -31,37 +31,5 @@ # Defines for Dataquay DEFINES += USE_SORD -CONFIG += qt thread warn_on stl rtti exceptions c++11 +CONFIG += qt thread warn_on stl rtti exceptions -include(bq-files.pri) -include(vamp-plugin-sdk-files.pri) -include(svcore/files.pri) - -DATAQUAY_SOURCES=$$fromfile(dataquay/lib.pro, SOURCES) -DATAQUAY_HEADERS=$$fromfile(dataquay/lib.pro, HEADERS) - -CHECKER_SOURCES=$$fromfile(checker/checker.pri, SOURCES) -CHECKER_HEADERS=$$fromfile(checker/checker.pri, HEADERS) - -CLIENT_HEADERS=$$fromfile(piper-cpp/vamp-client/client.pro, HEADERS) - -for (file, BQ_SOURCES) { SOURCES += $$file } -for (file, BQ_HEADERS) { HEADERS += $$file } - -for (file, VAMP_SOURCES) { SOURCES += $$file } -for (file, VAMP_HEADERS) { HEADERS += $$file } - -for (file, DATAQUAY_SOURCES) { SOURCES += $$sprintf("dataquay/%1", $$file) } -for (file, DATAQUAY_HEADERS) { HEADERS += $$sprintf("dataquay/%1", $$file) } - -for (file, CHECKER_SOURCES) { SOURCES += $$sprintf("checker/%1", $$file) } -for (file, CHECKER_HEADERS) { HEADERS += $$sprintf("checker/%1", $$file) } - -for (file, SVCORE_SOURCES) { SOURCES += $$sprintf("svcore/%1", $$file) } -for (file, SVCORE_HEADERS) { HEADERS += $$sprintf("svcore/%1", $$file) } - -for (file, CLIENT_HEADERS) { - HEADERS += $$sprintf("piper-cpp/vamp-client/%1", $$file) -} - -SOURCES += piper-cpp/vamp-capnp/piper-capnp.cpp diff -r 246bdf94ef7b -r 55d9bbf1fe45 base.pro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base.pro Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,60 @@ + +TEMPLATE = lib + +exists(config.pri) { + include(config.pri) +} + +!exists(config.pri) { + include(noconfig.pri) +} + +include(base.pri) + +CONFIG += staticlib +QT += network xml +QT -= gui + +TARGET = base + +OBJECTS_DIR = o +MOC_DIR = o + +exists(repoint.pri) { + include(repoint.pri) +} + +include(bq-files.pri) +include(vamp-plugin-sdk-files.pri) +include(svcore/files.pri) +include(capnp-regen.pri) + +DATAQUAY_SOURCES=$$fromfile(dataquay/lib.pro, SOURCES) +DATAQUAY_HEADERS=$$fromfile(dataquay/lib.pro, HEADERS) + +CHECKER_SOURCES=$$fromfile(checker/checker.pri, SOURCES) +CHECKER_HEADERS=$$fromfile(checker/checker.pri, HEADERS) + +CLIENT_HEADERS=$$fromfile(piper-cpp/vamp-client/qt/test.pro, HEADERS) + +for (file, BQ_SOURCES) { SOURCES += $$file } +for (file, BQ_HEADERS) { HEADERS += $$file } + +for (file, VAMP_SOURCES) { SOURCES += $$file } +for (file, VAMP_HEADERS) { HEADERS += $$file } + +for (file, DATAQUAY_SOURCES) { SOURCES += $$sprintf("dataquay/%1", $$file) } +for (file, DATAQUAY_HEADERS) { HEADERS += $$sprintf("dataquay/%1", $$file) } + +for (file, CHECKER_SOURCES) { SOURCES += $$sprintf("checker/%1", $$file) } +for (file, CHECKER_HEADERS) { HEADERS += $$sprintf("checker/%1", $$file) } + +for (file, SVCORE_SOURCES) { SOURCES += $$sprintf("svcore/%1", $$file) } +for (file, SVCORE_HEADERS) { HEADERS += $$sprintf("svcore/%1", $$file) } + +for (file, CLIENT_HEADERS) { + HEADERS += $$sprintf("piper-cpp/vamp-client/qt/%1", $$file) +} + +SOURCES += piper-cpp/vamp-capnp/piper-capnp.cpp + diff -r 246bdf94ef7b -r 55d9bbf1fe45 bq-files.pri --- a/bq-files.pri Mon Sep 17 13:53:25 2018 +0100 +++ b/bq-files.pri Mon Sep 17 14:05:41 2018 +0100 @@ -21,6 +21,7 @@ bqaudioio/bqaudioio/SystemRecordSource.h \ bqaudioio/src/DynamicJACK.h \ bqaudioio/src/JACKAudioIO.h \ + bqaudioio/src/Log.h \ bqaudioio/src/PortAudioIO.h \ bqaudioio/src/PulseAudioIO.h @@ -32,6 +33,7 @@ bqresample/src/Resampler.cpp \ bqaudioio/src/AudioFactory.cpp \ bqaudioio/src/JACKAudioIO.cpp \ + bqaudioio/src/Log.cpp \ bqaudioio/src/PortAudioIO.cpp \ bqaudioio/src/PulseAudioIO.cpp \ bqaudioio/src/ResamplerWrapper.cpp \ diff -r 246bdf94ef7b -r 55d9bbf1fe45 capnp-regen.pri --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/capnp-regen.pri Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,36 @@ + +capnpc.target = piper-cpp/vamp-capnp/piper.capnp.h +capnpc.depends = $$PWD/piper/capnp/piper.capnp + +capnpc.commands = capnp compile --src-prefix=$$PWD/piper/capnp -oc++:$$PWD/piper-cpp/vamp-capnp $$capnpc.depends + +macx* { + exists(sv-dependency-builds) { + capnpc.commands=$$PWD/sv-dependency-builds/osx/bin/capnp -I$$PWD/sv-dependency-builds/osx/include compile --src-prefix=$$PWD/piper/capnp -o$$PWD/sv-dependency-builds/osx/bin/capnpc-c++:$$PWD/piper-cpp/vamp-capnp $$capnpc.depends + } +} + +win32-g++ { + capnpc.commands=$$PWD/sv-dependency-builds/win32-mingw/bin/capnp -I$$PWD/sv-dependency-builds/win32-mingw/include compile --src-prefix=$$PWD/piper/capnp -o$$PWD/sv-dependency-builds/win32-mingw/bin/capnpc-c++:$$PWD/piper-cpp/vamp-capnp $$capnpc.depends +} + +win32-msvc* { + # This config is actually for 64-bit Windows builds -- see + # comments in noconfig.pri. + + # With MSVC2017 we have a problem that the header dependency is + # written out with the relative path from the build dir to the + # source dir (e.g. ..\sonic-visualiser\...) so if the header + # target path doesn't match that, the build fails before + # regenerating it. Not a problem with VC2015 for some reason. + # I hope using the relative path as target should fix it without + # breaking the VC2015 build. + + capnpc.target = ../$$basename(PWD)/piper-cpp/vamp-capnp/piper.capnp.h + capnpc.commands=$$PWD/sv-dependency-builds/win64-msvc/bin/capnp -I$$PWD/sv-dependency-builds/win64-msvc/include compile --src-prefix=$$PWD/piper/capnp -o$$PWD/sv-dependency-builds/win64-msvc/bin/capnpc-c++:$$PWD/piper-cpp/vamp-capnp $$capnpc.depends +} + +QMAKE_EXTRA_TARGETS += capnpc +PRE_TARGETDEPS += $$capnpc.target +QMAKE_CLEAN += $$capnpc.target + diff -r 246bdf94ef7b -r 55d9bbf1fe45 config.pri.in --- a/config.pri.in Mon Sep 17 13:53:25 2018 +0100 +++ b/config.pri.in Mon Sep 17 14:05:41 2018 +0100 @@ -1,6 +1,8 @@ CONFIG += @QMAKE_CONFIG@ +PREFIX_PATH = @prefix@ + DEFINES += @HAVES@ QMAKE_CC = @CC@ @@ -11,12 +13,15 @@ QMAKE_CXXFLAGS += @CXXFLAGS@ QMAKE_LFLAGS += @LDFLAGS@ -linux*:LIBS += -lasound -ldl +CONFIG += @CXXSTANDARD@ + +linux*:LIBS += -L$$PWD -lbase -lasound -ldl macx*:DEFINES += HAVE_COREAUDIO macx*:LIBS += -framework CoreAudio -framework CoreMidi -framework AudioUnit -framework AudioToolbox -framework CoreFoundation -framework CoreServices LIBS += @LIBS@ -DEFINES += HAVE_PIPER HAVE_PLUGIN_CHECKER_HELPER +linux*:LIBS -= -ljack +DEFINES += HAVE_PIPER HAVE_PLUGIN_CHECKER_HELPER DYNAMIC_JACK diff -r 246bdf94ef7b -r 55d9bbf1fe45 configure --- a/configure Mon Sep 17 13:53:25 2018 +0100 +++ b/configure Mon Sep 17 14:05:41 2018 +0100 @@ -624,6 +624,7 @@ LIBOBJS QMAKE_CONFIG HAVES +CXXSTANDARD CXXFLAGS_MINIMAL CUT SHA1SUM @@ -650,8 +651,6 @@ portaudio_CFLAGS liblo_LIBS liblo_CFLAGS -kj_LIBS -kj_CFLAGS capnp_LIBS capnp_CFLAGS serd_LIBS @@ -768,8 +767,6 @@ serd_LIBS capnp_CFLAGS capnp_LIBS -kj_CFLAGS -kj_LIBS liblo_CFLAGS liblo_LIBS portaudio_CFLAGS @@ -1442,8 +1439,6 @@ capnp_CFLAGS C compiler flags for capnp, overriding pkg-config capnp_LIBS linker flags for capnp, overriding pkg-config - kj_CFLAGS C compiler flags for kj, overriding pkg-config - kj_LIBS linker flags for kj, overriding pkg-config liblo_CFLAGS C compiler flags for liblo, overriding pkg-config liblo_LIBS linker flags for liblo, overriding pkg-config @@ -4417,7 +4412,7 @@ SV_DEFINES_DEBUG="-DDEBUG -DBUILD_DEBUG -DWANT_TIMING" -SV_DEFINES_RELEASE="-DNDEBUG -DBUILD_RELEASE -DWANT_TIMING" # -DNO_TIMING" +SV_DEFINES_RELEASE="-DNDEBUG -DBUILD_RELEASE -DNO_TIMING -DNO_HIT_COUNTS" SV_DEFINES_MINIMAL="$SV_DEFINES_RELEASE" # Now we have: USER_CXXFLAGS contains any flags the user set @@ -4428,12 +4423,53 @@ CXXFLAGS_DEBUG="$AUTOCONF_CXXFLAGS" CXXFLAGS_RELEASE="$AUTOCONF_CXXFLAGS" CXXFLAGS_MINIMAL="$AUTOCONF_CXXFLAGS" +CXXSTANDARD=c++14 if test "x$GCC" = "xyes"; then - CXXFLAGS_ANY="-Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe" - CXXFLAGS_DEBUG="$CXXFLAGS_ANY -g -Werror" - CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O2" + CXXFLAGS_ANY="-fpic -Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe" + CXXFLAGS_DEBUG="$CXXFLAGS_ANY -g -O2 -Werror" + CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O3 -ffast-math" CXXFLAGS_MINIMAL="$CXXFLAGS_ANY -g0 -O0" + LIBS_DEBUG="$LIBS" + as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags__--std=$CXXSTANDARD" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts --std=$CXXSTANDARD" >&5 +$as_echo_n "checking whether C++ compiler accepts --std=$CXXSTANDARD... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CXXFLAGS + CXXFLAGS="$CXXFLAGS --std=$CXXSTANDARD" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CXXFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : + : +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Compiler does not appear to support $CXXSTANDARD, falling back to c++11" >&5 +$as_echo "$as_me: Compiler does not appear to support $CXXSTANDARD, falling back to c++11" >&6;} + CXXSTANDARD=c++11 +fi + fi CXXFLAGS_BUILD="$CXXFLAGS_RELEASE" @@ -4448,6 +4484,7 @@ QMAKE_CONFIG="debug" CXXFLAGS_BUILD="$CXXFLAGS_DEBUG" SV_DEFINES_BUILD="$SV_DEFINES_DEBUG" +LIBS="$LIBS_DEBUG" fi @@ -5688,24 +5725,9 @@ fi -SV_MODULE_MODULE=capnp -SV_MODULE_VERSION_TEST="capnp >= 0.6" -SV_MODULE_HEADER=capnp/common.h -SV_MODULE_LIB=capnp -SV_MODULE_FUNC= -SV_MODULE_HAVE=HAVE_$(echo capnp | tr 'a-z' 'A-Z') -SV_MODULE_FAILED=1 -if test -n "$capnp_LIBS" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $capnp_CFLAGS" - LIBS="$LIBS $capnp_LIBS" - SV_MODULE_FAILED="" -fi -if test -z "$SV_MODULE_VERSION_TEST" ; then - SV_MODULE_VERSION_TEST=$SV_MODULE_MODULE -fi -if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then +# We need a Cap'n Proto version with the expectedSizeInWordsFromPrefix +# function, which appeared in v0.6. If we can't find at least that +# version with pkg-config, we check for the symbol with the compiler. pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for capnp" >&5 @@ -5715,12 +5737,124 @@ pkg_cv_capnp_CFLAGS="$capnp_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"capnp >= 0.6\""; } >&5 + ($PKG_CONFIG --exists --print-errors "capnp >= 0.6") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_capnp_CFLAGS=`$PKG_CONFIG --cflags "capnp >= 0.6" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$capnp_LIBS"; then + pkg_cv_capnp_LIBS="$capnp_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"capnp >= 0.6\""; } >&5 + ($PKG_CONFIG --exists --print-errors "capnp >= 0.6") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_capnp_LIBS=`$PKG_CONFIG --libs "capnp >= 0.6" 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 + capnp_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "capnp >= 0.6" 2>&1` + else + capnp_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "capnp >= 0.6" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$capnp_PKG_ERRORS" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find required module capnp using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find required module capnp using pkg-config, trying again by old-fashioned means" >&6;} +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}: Failed to find required module capnp using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find required module capnp using pkg-config, trying again by old-fashioned means" >&6;} +else + capnp_CFLAGS=$pkg_cv_capnp_CFLAGS + capnp_LIBS=$pkg_cv_capnp_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVES="$HAVES HAVE_CAPNP";CXXFLAGS="$CXXFLAGS $capnp_CFLAGS";LIBS="$LIBS $capnp_LIBS" +fi +if test -z "$capnp_LIBS" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + int main() { + kj::Array prefix; + return capnp::expectedSizeInWordsFromPrefix(prefix.asPtr()); + } +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + HAVES="$HAVES HAVE_CAPNP";LIBS="$LIBS -lcapnp -lkj" +else + as_fn_error $? "Failed to find appropriate capnp library" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + + +SV_MODULE_MODULE=liblo +SV_MODULE_VERSION_TEST="" +SV_MODULE_HEADER=lo/lo.h +SV_MODULE_LIB=lo +SV_MODULE_FUNC=lo_address_new +SV_MODULE_HAVE=HAVE_$(echo liblo | tr 'a-z' 'A-Z') +SV_MODULE_FAILED=1 +if test -n "$liblo_LIBS" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 +$as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} + CXXFLAGS="$CXXFLAGS $liblo_CFLAGS" + LIBS="$LIBS $liblo_LIBS" + SV_MODULE_FAILED="" +fi +if test -z "$SV_MODULE_VERSION_TEST" ; then + SV_MODULE_VERSION_TEST=$SV_MODULE_MODULE +fi +if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblo" >&5 +$as_echo_n "checking for liblo... " >&6; } + +if test -n "$liblo_CFLAGS"; then + pkg_cv_liblo_CFLAGS="$liblo_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 ($PKG_CONFIG --exists --print-errors "$SV_MODULE_VERSION_TEST") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_capnp_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_liblo_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5728,8 +5862,8 @@ else pkg_failed=untried fi -if test -n "$capnp_LIBS"; then - pkg_cv_capnp_LIBS="$capnp_LIBS" +if test -n "$liblo_LIBS"; then + pkg_cv_liblo_LIBS="$liblo_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -5737,7 +5871,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_capnp_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_liblo_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5758,40 +5892,42 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - capnp_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + liblo_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - capnp_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + liblo_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$capnp_PKG_ERRORS" >&5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} + echo "$liblo_PKG_ERRORS" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} 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}: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -else - capnp_CFLAGS=$pkg_cv_capnp_CFLAGS - capnp_LIBS=$pkg_cv_capnp_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} +else + liblo_CFLAGS=$pkg_cv_liblo_CFLAGS + liblo_LIBS=$pkg_cv_liblo_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $capnp_CFLAGS";LIBS="$LIBS $capnp_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $liblo_CFLAGS";LIBS="$LIBS $liblo_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then as_ac_Header=`$as_echo "ac_cv_header_$SV_MODULE_HEADER" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$SV_MODULE_HEADER" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - HAVES="$HAVES $SV_MODULE_HAVE" -else - as_fn_error $? "Failed to find header $SV_MODULE_HEADER for required module $SV_MODULE_MODULE" "$LINENO" 5 -fi - - - if test -n "$SV_MODULE_LIB"; then - as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` + HAVES="$HAVES $SV_MODULE_HAVE";SV_MODULE_FAILED="" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&5 +$as_echo "$as_me: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&6;} +fi + + + if test -z "$SV_MODULE_FAILED"; then + if test -n "$SV_MODULE_LIB"; then + as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB" >&5 $as_echo_n "checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB... " >&6; } if eval \${$as_ac_Lib+:} false; then : @@ -5832,25 +5968,27 @@ if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : LIBS="$LIBS -l$SV_MODULE_LIB" else - as_fn_error $? "Failed to find library $SV_MODULE_LIB for required module $SV_MODULE_MODULE" "$LINENO" 5 -fi - + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&5 +$as_echo "$as_me: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&6;} +fi + + fi fi fi -SV_MODULE_MODULE=kj -SV_MODULE_VERSION_TEST="kj >= 0.6" -SV_MODULE_HEADER=kj/common.h -SV_MODULE_LIB=kj -SV_MODULE_FUNC= -SV_MODULE_HAVE=HAVE_$(echo kj | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=portaudio +SV_MODULE_VERSION_TEST="portaudio-2.0 >= 19" +SV_MODULE_HEADER=portaudio.h +SV_MODULE_LIB=portaudio +SV_MODULE_FUNC=Pa_IsFormatSupported +SV_MODULE_HAVE=HAVE_$(echo portaudio | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$kj_LIBS" ; then +if test -n "$portaudio_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $kj_CFLAGS" - LIBS="$LIBS $kj_LIBS" + CXXFLAGS="$CXXFLAGS $portaudio_CFLAGS" + LIBS="$LIBS $portaudio_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -5859,11 +5997,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for kj" >&5 -$as_echo_n "checking for kj... " >&6; } - -if test -n "$kj_CFLAGS"; then - pkg_cv_kj_CFLAGS="$kj_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for portaudio" >&5 +$as_echo_n "checking for portaudio... " >&6; } + +if test -n "$portaudio_CFLAGS"; then + pkg_cv_portaudio_CFLAGS="$portaudio_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -5871,7 +6009,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_kj_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_portaudio_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5879,8 +6017,8 @@ else pkg_failed=untried fi -if test -n "$kj_LIBS"; then - pkg_cv_kj_LIBS="$kj_LIBS" +if test -n "$portaudio_LIBS"; then + pkg_cv_portaudio_LIBS="$portaudio_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -5888,7 +6026,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_kj_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_portaudio_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -5909,40 +6047,42 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - kj_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + portaudio_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - kj_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + portaudio_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$kj_PKG_ERRORS" >&5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} + echo "$portaudio_PKG_ERRORS" >&5 + + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} 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}: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find required module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -else - kj_CFLAGS=$pkg_cv_kj_CFLAGS - kj_LIBS=$pkg_cv_kj_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 +$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} +else + portaudio_CFLAGS=$pkg_cv_portaudio_CFLAGS + portaudio_LIBS=$pkg_cv_portaudio_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $kj_CFLAGS";LIBS="$LIBS $kj_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $portaudio_CFLAGS";LIBS="$LIBS $portaudio_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then as_ac_Header=`$as_echo "ac_cv_header_$SV_MODULE_HEADER" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$SV_MODULE_HEADER" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - HAVES="$HAVES $SV_MODULE_HAVE" -else - as_fn_error $? "Failed to find header $SV_MODULE_HEADER for required module $SV_MODULE_MODULE" "$LINENO" 5 -fi - - - if test -n "$SV_MODULE_LIB"; then - as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` + HAVES="$HAVES $SV_MODULE_HAVE";SV_MODULE_FAILED="" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&5 +$as_echo "$as_me: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&6;} +fi + + + if test -z "$SV_MODULE_FAILED"; then + if test -n "$SV_MODULE_LIB"; then + as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB" >&5 $as_echo_n "checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB... " >&6; } if eval \${$as_ac_Lib+:} false; then : @@ -5983,26 +6123,27 @@ if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : LIBS="$LIBS -l$SV_MODULE_LIB" else - as_fn_error $? "Failed to find library $SV_MODULE_LIB for required module $SV_MODULE_MODULE" "$LINENO" 5 -fi - + { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&5 +$as_echo "$as_me: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&6;} +fi + + fi fi fi - -SV_MODULE_MODULE=liblo -SV_MODULE_VERSION_TEST="" -SV_MODULE_HEADER=lo/lo.h -SV_MODULE_LIB=lo -SV_MODULE_FUNC=lo_address_new -SV_MODULE_HAVE=HAVE_$(echo liblo | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=JACK +SV_MODULE_VERSION_TEST="jack >= 0.100" +SV_MODULE_HEADER=jack/jack.h +SV_MODULE_LIB=jack +SV_MODULE_FUNC=jack_client_open +SV_MODULE_HAVE=HAVE_$(echo JACK | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$liblo_LIBS" ; then +if test -n "$JACK_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $liblo_CFLAGS" - LIBS="$LIBS $liblo_LIBS" + CXXFLAGS="$CXXFLAGS $JACK_CFLAGS" + LIBS="$LIBS $JACK_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6011,11 +6152,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblo" >&5 -$as_echo_n "checking for liblo... " >&6; } - -if test -n "$liblo_CFLAGS"; then - pkg_cv_liblo_CFLAGS="$liblo_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JACK" >&5 +$as_echo_n "checking for JACK... " >&6; } + +if test -n "$JACK_CFLAGS"; then + pkg_cv_JACK_CFLAGS="$JACK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6023,7 +6164,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_liblo_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_JACK_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6031,8 +6172,8 @@ else pkg_failed=untried fi -if test -n "$liblo_LIBS"; then - pkg_cv_liblo_LIBS="$liblo_LIBS" +if test -n "$JACK_LIBS"; then + pkg_cv_JACK_LIBS="$JACK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6040,7 +6181,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_liblo_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_JACK_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6061,12 +6202,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - liblo_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + JACK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - liblo_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + JACK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$liblo_PKG_ERRORS" >&5 + echo "$JACK_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6076,11 +6217,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - liblo_CFLAGS=$pkg_cv_liblo_CFLAGS - liblo_LIBS=$pkg_cv_liblo_LIBS + JACK_CFLAGS=$pkg_cv_JACK_CFLAGS + JACK_LIBS=$pkg_cv_JACK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $liblo_CFLAGS";LIBS="$LIBS $liblo_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $JACK_CFLAGS";LIBS="$LIBS $JACK_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6146,18 +6287,18 @@ fi -SV_MODULE_MODULE=portaudio -SV_MODULE_VERSION_TEST="portaudio-2.0 >= 19" -SV_MODULE_HEADER=portaudio.h -SV_MODULE_LIB=portaudio -SV_MODULE_FUNC=Pa_IsFormatSupported -SV_MODULE_HAVE=HAVE_$(echo portaudio | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=libpulse +SV_MODULE_VERSION_TEST="libpulse >= 0.9" +SV_MODULE_HEADER=pulse/pulseaudio.h +SV_MODULE_LIB=pulse +SV_MODULE_FUNC=pa_stream_new +SV_MODULE_HAVE=HAVE_$(echo libpulse | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$portaudio_LIBS" ; then +if test -n "$libpulse_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $portaudio_CFLAGS" - LIBS="$LIBS $portaudio_LIBS" + CXXFLAGS="$CXXFLAGS $libpulse_CFLAGS" + LIBS="$LIBS $libpulse_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6166,11 +6307,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for portaudio" >&5 -$as_echo_n "checking for portaudio... " >&6; } - -if test -n "$portaudio_CFLAGS"; then - pkg_cv_portaudio_CFLAGS="$portaudio_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpulse" >&5 +$as_echo_n "checking for libpulse... " >&6; } + +if test -n "$libpulse_CFLAGS"; then + pkg_cv_libpulse_CFLAGS="$libpulse_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6178,7 +6319,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_portaudio_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_libpulse_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6186,8 +6327,8 @@ else pkg_failed=untried fi -if test -n "$portaudio_LIBS"; then - pkg_cv_portaudio_LIBS="$portaudio_LIBS" +if test -n "$libpulse_LIBS"; then + pkg_cv_libpulse_LIBS="$libpulse_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6195,7 +6336,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_portaudio_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_libpulse_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6216,12 +6357,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - portaudio_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + libpulse_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - portaudio_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + libpulse_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$portaudio_PKG_ERRORS" >&5 + echo "$libpulse_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6231,11 +6372,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - portaudio_CFLAGS=$pkg_cv_portaudio_CFLAGS - portaudio_LIBS=$pkg_cv_portaudio_LIBS + libpulse_CFLAGS=$pkg_cv_libpulse_CFLAGS + libpulse_LIBS=$pkg_cv_libpulse_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $portaudio_CFLAGS";LIBS="$LIBS $portaudio_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $libpulse_CFLAGS";LIBS="$LIBS $libpulse_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6301,18 +6442,18 @@ fi -SV_MODULE_MODULE=JACK -SV_MODULE_VERSION_TEST="jack >= 0.100" -SV_MODULE_HEADER=jack/jack.h -SV_MODULE_LIB=jack -SV_MODULE_FUNC=jack_client_open -SV_MODULE_HAVE=HAVE_$(echo JACK | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=lrdf +SV_MODULE_VERSION_TEST="lrdf >= 0.2" +SV_MODULE_HEADER=lrdf.h +SV_MODULE_LIB=lrdf +SV_MODULE_FUNC=lrdf_init +SV_MODULE_HAVE=HAVE_$(echo lrdf | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$JACK_LIBS" ; then +if test -n "$lrdf_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $JACK_CFLAGS" - LIBS="$LIBS $JACK_LIBS" + CXXFLAGS="$CXXFLAGS $lrdf_CFLAGS" + LIBS="$LIBS $lrdf_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6321,11 +6462,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JACK" >&5 -$as_echo_n "checking for JACK... " >&6; } - -if test -n "$JACK_CFLAGS"; then - pkg_cv_JACK_CFLAGS="$JACK_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lrdf" >&5 +$as_echo_n "checking for lrdf... " >&6; } + +if test -n "$lrdf_CFLAGS"; then + pkg_cv_lrdf_CFLAGS="$lrdf_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6333,7 +6474,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_JACK_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_lrdf_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6341,8 +6482,8 @@ else pkg_failed=untried fi -if test -n "$JACK_LIBS"; then - pkg_cv_JACK_LIBS="$JACK_LIBS" +if test -n "$lrdf_LIBS"; then + pkg_cv_lrdf_LIBS="$lrdf_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6350,7 +6491,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_JACK_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_lrdf_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6371,12 +6512,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - JACK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + lrdf_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - JACK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + lrdf_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$JACK_PKG_ERRORS" >&5 + echo "$lrdf_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6386,11 +6527,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - JACK_CFLAGS=$pkg_cv_JACK_CFLAGS - JACK_LIBS=$pkg_cv_JACK_LIBS + lrdf_CFLAGS=$pkg_cv_lrdf_CFLAGS + lrdf_LIBS=$pkg_cv_lrdf_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $JACK_CFLAGS";LIBS="$LIBS $JACK_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $lrdf_CFLAGS";LIBS="$LIBS $lrdf_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6456,18 +6597,18 @@ fi -SV_MODULE_MODULE=libpulse -SV_MODULE_VERSION_TEST="libpulse >= 0.9" -SV_MODULE_HEADER=pulse/pulseaudio.h -SV_MODULE_LIB=pulse -SV_MODULE_FUNC=pa_stream_new -SV_MODULE_HAVE=HAVE_$(echo libpulse | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=oggz +SV_MODULE_VERSION_TEST="oggz >= 1.0.0" +SV_MODULE_HEADER=oggz/oggz.h +SV_MODULE_LIB=oggz +SV_MODULE_FUNC=oggz_run +SV_MODULE_HAVE=HAVE_$(echo oggz | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$libpulse_LIBS" ; then +if test -n "$oggz_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $libpulse_CFLAGS" - LIBS="$LIBS $libpulse_LIBS" + CXXFLAGS="$CXXFLAGS $oggz_CFLAGS" + LIBS="$LIBS $oggz_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6476,11 +6617,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libpulse" >&5 -$as_echo_n "checking for libpulse... " >&6; } - -if test -n "$libpulse_CFLAGS"; then - pkg_cv_libpulse_CFLAGS="$libpulse_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for oggz" >&5 +$as_echo_n "checking for oggz... " >&6; } + +if test -n "$oggz_CFLAGS"; then + pkg_cv_oggz_CFLAGS="$oggz_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6488,7 +6629,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_libpulse_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_oggz_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6496,8 +6637,8 @@ else pkg_failed=untried fi -if test -n "$libpulse_LIBS"; then - pkg_cv_libpulse_LIBS="$libpulse_LIBS" +if test -n "$oggz_LIBS"; then + pkg_cv_oggz_LIBS="$oggz_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6505,7 +6646,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_libpulse_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_oggz_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6526,12 +6667,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - libpulse_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + oggz_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - libpulse_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + oggz_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$libpulse_PKG_ERRORS" >&5 + echo "$oggz_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6541,11 +6682,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - libpulse_CFLAGS=$pkg_cv_libpulse_CFLAGS - libpulse_LIBS=$pkg_cv_libpulse_LIBS + oggz_CFLAGS=$pkg_cv_oggz_CFLAGS + oggz_LIBS=$pkg_cv_oggz_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $libpulse_CFLAGS";LIBS="$LIBS $libpulse_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $oggz_CFLAGS";LIBS="$LIBS $oggz_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6611,18 +6752,18 @@ fi -SV_MODULE_MODULE=lrdf -SV_MODULE_VERSION_TEST="lrdf >= 0.2" -SV_MODULE_HEADER=lrdf.h -SV_MODULE_LIB=lrdf -SV_MODULE_FUNC=lrdf_init -SV_MODULE_HAVE=HAVE_$(echo lrdf | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=fishsound +SV_MODULE_VERSION_TEST="fishsound >= 1.0.0" +SV_MODULE_HEADER=fishsound/fishsound.h +SV_MODULE_LIB=fishsound +SV_MODULE_FUNC=fish_sound_new +SV_MODULE_HAVE=HAVE_$(echo fishsound | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$lrdf_LIBS" ; then +if test -n "$fishsound_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $lrdf_CFLAGS" - LIBS="$LIBS $lrdf_LIBS" + CXXFLAGS="$CXXFLAGS $fishsound_CFLAGS" + LIBS="$LIBS $fishsound_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6631,11 +6772,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lrdf" >&5 -$as_echo_n "checking for lrdf... " >&6; } - -if test -n "$lrdf_CFLAGS"; then - pkg_cv_lrdf_CFLAGS="$lrdf_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fishsound" >&5 +$as_echo_n "checking for fishsound... " >&6; } + +if test -n "$fishsound_CFLAGS"; then + pkg_cv_fishsound_CFLAGS="$fishsound_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6643,7 +6784,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_lrdf_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_fishsound_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6651,8 +6792,8 @@ else pkg_failed=untried fi -if test -n "$lrdf_LIBS"; then - pkg_cv_lrdf_LIBS="$lrdf_LIBS" +if test -n "$fishsound_LIBS"; then + pkg_cv_fishsound_LIBS="$fishsound_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6660,7 +6801,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_lrdf_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_fishsound_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6681,12 +6822,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - lrdf_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + fishsound_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - lrdf_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + fishsound_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$lrdf_PKG_ERRORS" >&5 + echo "$fishsound_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6696,11 +6837,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - lrdf_CFLAGS=$pkg_cv_lrdf_CFLAGS - lrdf_LIBS=$pkg_cv_lrdf_LIBS + fishsound_CFLAGS=$pkg_cv_fishsound_CFLAGS + fishsound_LIBS=$pkg_cv_fishsound_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $lrdf_CFLAGS";LIBS="$LIBS $lrdf_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $fishsound_CFLAGS";LIBS="$LIBS $fishsound_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6766,18 +6907,18 @@ fi -SV_MODULE_MODULE=oggz -SV_MODULE_VERSION_TEST="oggz >= 1.0.0" -SV_MODULE_HEADER=oggz/oggz.h -SV_MODULE_LIB=oggz -SV_MODULE_FUNC=oggz_run -SV_MODULE_HAVE=HAVE_$(echo oggz | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=mad +SV_MODULE_VERSION_TEST="mad >= 0.15.0" +SV_MODULE_HEADER=mad.h +SV_MODULE_LIB=mad +SV_MODULE_FUNC=mad_decoder_init +SV_MODULE_HAVE=HAVE_$(echo mad | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$oggz_LIBS" ; then +if test -n "$mad_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $oggz_CFLAGS" - LIBS="$LIBS $oggz_LIBS" + CXXFLAGS="$CXXFLAGS $mad_CFLAGS" + LIBS="$LIBS $mad_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6786,11 +6927,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for oggz" >&5 -$as_echo_n "checking for oggz... " >&6; } - -if test -n "$oggz_CFLAGS"; then - pkg_cv_oggz_CFLAGS="$oggz_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mad" >&5 +$as_echo_n "checking for mad... " >&6; } + +if test -n "$mad_CFLAGS"; then + pkg_cv_mad_CFLAGS="$mad_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6798,7 +6939,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_oggz_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_mad_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6806,8 +6947,8 @@ else pkg_failed=untried fi -if test -n "$oggz_LIBS"; then - pkg_cv_oggz_LIBS="$oggz_LIBS" +if test -n "$mad_LIBS"; then + pkg_cv_mad_LIBS="$mad_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6815,7 +6956,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_oggz_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_mad_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6836,12 +6977,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - oggz_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + mad_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - oggz_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + mad_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$oggz_PKG_ERRORS" >&5 + echo "$mad_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -6851,11 +6992,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - oggz_CFLAGS=$pkg_cv_oggz_CFLAGS - oggz_LIBS=$pkg_cv_oggz_LIBS + mad_CFLAGS=$pkg_cv_mad_CFLAGS + mad_LIBS=$pkg_cv_mad_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $oggz_CFLAGS";LIBS="$LIBS $oggz_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $mad_CFLAGS";LIBS="$LIBS $mad_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -6921,18 +7062,18 @@ fi -SV_MODULE_MODULE=fishsound -SV_MODULE_VERSION_TEST="fishsound >= 1.0.0" -SV_MODULE_HEADER=fishsound/fishsound.h -SV_MODULE_LIB=fishsound -SV_MODULE_FUNC=fish_sound_new -SV_MODULE_HAVE=HAVE_$(echo fishsound | tr 'a-z' 'A-Z') +SV_MODULE_MODULE=id3tag +SV_MODULE_VERSION_TEST="id3tag >= 0.15.0" +SV_MODULE_HEADER=id3tag.h +SV_MODULE_LIB=id3tag +SV_MODULE_FUNC=id3_tag_new +SV_MODULE_HAVE=HAVE_$(echo id3tag | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$fishsound_LIBS" ; then +if test -n "$id3tag_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $fishsound_CFLAGS" - LIBS="$LIBS $fishsound_LIBS" + CXXFLAGS="$CXXFLAGS $id3tag_CFLAGS" + LIBS="$LIBS $id3tag_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -6941,11 +7082,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fishsound" >&5 -$as_echo_n "checking for fishsound... " >&6; } - -if test -n "$fishsound_CFLAGS"; then - pkg_cv_fishsound_CFLAGS="$fishsound_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for id3tag" >&5 +$as_echo_n "checking for id3tag... " >&6; } + +if test -n "$id3tag_CFLAGS"; then + pkg_cv_id3tag_CFLAGS="$id3tag_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6953,7 +7094,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_fishsound_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_id3tag_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6961,8 +7102,8 @@ else pkg_failed=untried fi -if test -n "$fishsound_LIBS"; then - pkg_cv_fishsound_LIBS="$fishsound_LIBS" +if test -n "$id3tag_LIBS"; then + pkg_cv_id3tag_LIBS="$id3tag_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -6970,7 +7111,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_fishsound_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_id3tag_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -6991,12 +7132,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - fishsound_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + id3tag_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - fishsound_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + id3tag_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$fishsound_PKG_ERRORS" >&5 + echo "$id3tag_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -7006,11 +7147,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - fishsound_CFLAGS=$pkg_cv_fishsound_CFLAGS - fishsound_LIBS=$pkg_cv_fishsound_LIBS + id3tag_CFLAGS=$pkg_cv_id3tag_CFLAGS + id3tag_LIBS=$pkg_cv_id3tag_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $fishsound_CFLAGS";LIBS="$LIBS $fishsound_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $id3tag_CFLAGS";LIBS="$LIBS $id3tag_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -7076,18 +7217,20 @@ fi -SV_MODULE_MODULE=mad -SV_MODULE_VERSION_TEST="mad >= 0.15.0" -SV_MODULE_HEADER=mad.h -SV_MODULE_LIB=mad -SV_MODULE_FUNC=mad_decoder_init -SV_MODULE_HAVE=HAVE_$(echo mad | tr 'a-z' 'A-Z') +# Link in -lX11 if it exists -- this is for the X error handler + +SV_MODULE_MODULE=X11 +SV_MODULE_VERSION_TEST="x11 >= 1.0.0" +SV_MODULE_HEADER=X11/X.h +SV_MODULE_LIB=x11 +SV_MODULE_FUNC=XGetErrorText +SV_MODULE_HAVE=HAVE_$(echo X11 | tr 'a-z' 'A-Z') SV_MODULE_FAILED=1 -if test -n "$mad_LIBS" ; then +if test -n "$X11_LIBS" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 $as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $mad_CFLAGS" - LIBS="$LIBS $mad_LIBS" + CXXFLAGS="$CXXFLAGS $X11_CFLAGS" + LIBS="$LIBS $X11_LIBS" SV_MODULE_FAILED="" fi if test -z "$SV_MODULE_VERSION_TEST" ; then @@ -7096,11 +7239,11 @@ if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mad" >&5 -$as_echo_n "checking for mad... " >&6; } - -if test -n "$mad_CFLAGS"; then - pkg_cv_mad_CFLAGS="$mad_CFLAGS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +$as_echo_n "checking for X11... " >&6; } + +if test -n "$X11_CFLAGS"; then + pkg_cv_X11_CFLAGS="$X11_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -7108,7 +7251,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_mad_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7116,8 +7259,8 @@ else pkg_failed=untried fi -if test -n "$mad_LIBS"; then - pkg_cv_mad_LIBS="$mad_LIBS" +if test -n "$X11_LIBS"; then + pkg_cv_X11_LIBS="$X11_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 @@ -7125,7 +7268,7 @@ ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_mad_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` + pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -7146,12 +7289,12 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - mad_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` else - mad_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` + X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$mad_PKG_ERRORS" >&5 + echo "$X11_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} @@ -7161,11 +7304,11 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 $as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} else - mad_CFLAGS=$pkg_cv_mad_CFLAGS - mad_LIBS=$pkg_cv_mad_LIBS + X11_CFLAGS=$pkg_cv_X11_CFLAGS + X11_LIBS=$pkg_cv_X11_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $mad_CFLAGS";LIBS="$LIBS $mad_LIBS";SV_MODULE_FAILED="" + HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $X11_CFLAGS";LIBS="$LIBS $X11_LIBS";SV_MODULE_FAILED="" fi fi if test -n "$SV_MODULE_FAILED"; then @@ -7231,316 +7374,7 @@ fi -SV_MODULE_MODULE=id3tag -SV_MODULE_VERSION_TEST="id3tag >= 0.15.0" -SV_MODULE_HEADER=id3tag.h -SV_MODULE_LIB=id3tag -SV_MODULE_FUNC=id3_tag_new -SV_MODULE_HAVE=HAVE_$(echo id3tag | tr 'a-z' 'A-Z') -SV_MODULE_FAILED=1 -if test -n "$id3tag_LIBS" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $id3tag_CFLAGS" - LIBS="$LIBS $id3tag_LIBS" - SV_MODULE_FAILED="" -fi -if test -z "$SV_MODULE_VERSION_TEST" ; then - SV_MODULE_VERSION_TEST=$SV_MODULE_MODULE -fi -if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for id3tag" >&5 -$as_echo_n "checking for id3tag... " >&6; } - -if test -n "$id3tag_CFLAGS"; then - pkg_cv_id3tag_CFLAGS="$id3tag_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$SV_MODULE_VERSION_TEST") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_id3tag_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$id3tag_LIBS"; then - pkg_cv_id3tag_LIBS="$id3tag_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$SV_MODULE_VERSION_TEST") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_id3tag_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 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 - id3tag_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` - else - id3tag_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$id3tag_PKG_ERRORS" >&5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -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}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -else - id3tag_CFLAGS=$pkg_cv_id3tag_CFLAGS - id3tag_LIBS=$pkg_cv_id3tag_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $id3tag_CFLAGS";LIBS="$LIBS $id3tag_LIBS";SV_MODULE_FAILED="" -fi -fi -if test -n "$SV_MODULE_FAILED"; then - as_ac_Header=`$as_echo "ac_cv_header_$SV_MODULE_HEADER" | $as_tr_sh` -ac_fn_cxx_check_header_mongrel "$LINENO" "$SV_MODULE_HEADER" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - HAVES="$HAVES $SV_MODULE_HAVE";SV_MODULE_FAILED="" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&6;} -fi - - - if test -z "$SV_MODULE_FAILED"; then - if test -n "$SV_MODULE_LIB"; then - as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB" >&5 -$as_echo_n "checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$SV_MODULE_LIB $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 $SV_MODULE_FUNC (); -int -main () -{ -return $SV_MODULE_FUNC (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : - LIBS="$LIBS -l$SV_MODULE_LIB" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&6;} -fi - - fi - fi -fi - - -# Link in -lX11 if it exists -- this is for the X error handler - -SV_MODULE_MODULE=X11 -SV_MODULE_VERSION_TEST="x11 >= 1.0.0" -SV_MODULE_HEADER=X11/X.h -SV_MODULE_LIB=x11 -SV_MODULE_FUNC=XGetErrorText -SV_MODULE_HAVE=HAVE_$(echo X11 | tr 'a-z' 'A-Z') -SV_MODULE_FAILED=1 -if test -n "$X11_LIBS" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: User set ${SV_MODULE_MODULE}_LIBS explicitly, skipping test for $SV_MODULE_MODULE" >&6;} - CXXFLAGS="$CXXFLAGS $X11_CFLAGS" - LIBS="$LIBS $X11_LIBS" - SV_MODULE_FAILED="" -fi -if test -z "$SV_MODULE_VERSION_TEST" ; then - SV_MODULE_VERSION_TEST=$SV_MODULE_MODULE -fi -if test -n "$SV_MODULE_FAILED" && test -n "$PKG_CONFIG"; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 -$as_echo_n "checking for X11... " >&6; } - -if test -n "$X11_CFLAGS"; then - pkg_cv_X11_CFLAGS="$X11_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$SV_MODULE_VERSION_TEST") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "$SV_MODULE_VERSION_TEST" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$X11_LIBS"; then - pkg_cv_X11_LIBS="$X11_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$SV_MODULE_VERSION_TEST\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$SV_MODULE_VERSION_TEST") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "$SV_MODULE_VERSION_TEST" 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 - X11_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` - else - X11_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$SV_MODULE_VERSION_TEST" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$X11_PKG_ERRORS" >&5 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -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}: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&5 -$as_echo "$as_me: Failed to find optional module $SV_MODULE_MODULE using pkg-config, trying again by old-fashioned means" >&6;} -else - X11_CFLAGS=$pkg_cv_X11_CFLAGS - X11_LIBS=$pkg_cv_X11_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - HAVES="$HAVES $SV_MODULE_HAVE";CXXFLAGS="$CXXFLAGS $X11_CFLAGS";LIBS="$LIBS $X11_LIBS";SV_MODULE_FAILED="" -fi -fi -if test -n "$SV_MODULE_FAILED"; then - as_ac_Header=`$as_echo "ac_cv_header_$SV_MODULE_HEADER" | $as_tr_sh` -ac_fn_cxx_check_header_mongrel "$LINENO" "$SV_MODULE_HEADER" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - HAVES="$HAVES $SV_MODULE_HAVE";SV_MODULE_FAILED="" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: Failed to find header $SV_MODULE_HEADER for optional module $SV_MODULE_MODULE" >&6;} -fi - - - if test -z "$SV_MODULE_FAILED"; then - if test -n "$SV_MODULE_LIB"; then - as_ac_Lib=`$as_echo "ac_cv_lib_$SV_MODULE_LIB''_$SV_MODULE_FUNC" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB" >&5 -$as_echo_n "checking for $SV_MODULE_FUNC in -l$SV_MODULE_LIB... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-l$SV_MODULE_LIB $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 $SV_MODULE_FUNC (); -int -main () -{ -return $SV_MODULE_FUNC (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : - LIBS="$LIBS -l$SV_MODULE_LIB" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&5 -$as_echo "$as_me: Failed to find library $SV_MODULE_LIB for optional module $SV_MODULE_MODULE" >&6;} -fi - - fi - fi -fi + @@ -8733,6 +8567,28 @@ fi +if test -x repoint ; then + if test -d .hg -o -d .git ; then + if ! ./repoint install; then + as_fn_error $? "Repoint failed; please fix any reported errors and try again" "$LINENO" 5 + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: Repoint executable found but not in an Hg or Git working-copy: not running it" >&5 +$as_echo "$as_me: Repoint executable found but not in an Hg or Git working-copy: not running it" >&6;} + if ! test -d vamp-plugin-sdk ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No vamp-plugin-sdk directory present, so external libraries might not have been updated" >&5 +$as_echo "$as_me: WARNING: No vamp-plugin-sdk directory present, so external libraries might not have been updated" >&2;} + fi + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: No Repoint executable found: assuming external libraries are already here" >&5 +$as_echo "$as_me: No Repoint executable found: assuming external libraries are already here" >&6;} + if ! test -d vamp-plugin-sdk ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No vamp-plugin-sdk directory present, so external libraries might not have been updated" >&5 +$as_echo "$as_me: WARNING: No vamp-plugin-sdk directory present, so external libraries might not have been updated" >&2;} + fi +fi + if ! $QMAKE -r sonic-visualiser.pro; then as_fn_error $? "qmake failed: Command was \"$QMAKE -r\"" "$LINENO" 5 fi diff -r 246bdf94ef7b -r 55d9bbf1fe45 configure.ac --- a/configure.ac Mon Sep 17 13:53:25 2018 +0100 +++ b/configure.ac Mon Sep 17 14:05:41 2018 +0100 @@ -40,7 +40,7 @@ SV_CHECK_QT SV_DEFINES_DEBUG="-DDEBUG -DBUILD_DEBUG -DWANT_TIMING" -SV_DEFINES_RELEASE="-DNDEBUG -DBUILD_RELEASE -DWANT_TIMING" # -DNO_TIMING" +SV_DEFINES_RELEASE="-DNDEBUG -DBUILD_RELEASE -DNO_TIMING -DNO_HIT_COUNTS" SV_DEFINES_MINIMAL="$SV_DEFINES_RELEASE" # Now we have: USER_CXXFLAGS contains any flags the user set @@ -51,12 +51,16 @@ CXXFLAGS_DEBUG="$AUTOCONF_CXXFLAGS" CXXFLAGS_RELEASE="$AUTOCONF_CXXFLAGS" CXXFLAGS_MINIMAL="$AUTOCONF_CXXFLAGS" +CXXSTANDARD=c++14 if test "x$GCC" = "xyes"; then - CXXFLAGS_ANY="-Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe" - CXXFLAGS_DEBUG="$CXXFLAGS_ANY -g -Werror" - CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O2" + CXXFLAGS_ANY="-fpic -Wall -Wextra -Woverloaded-virtual -Wformat-nonliteral -Wformat-security -Winit-self -Wswitch-enum -Wconversion -pipe" + CXXFLAGS_DEBUG="$CXXFLAGS_ANY -g -O2 -Werror" + CXXFLAGS_RELEASE="$CXXFLAGS_ANY -g0 -O3 -ffast-math" CXXFLAGS_MINIMAL="$CXXFLAGS_ANY -g0 -O0" + LIBS_DEBUG="$LIBS" + AX_CHECK_COMPILE_FLAG(--std=$CXXSTANDARD, [], [AC_MSG_NOTICE([Compiler does not appear to support $CXXSTANDARD, falling back to c++11]) + CXXSTANDARD=c++11]) fi CXXFLAGS_BUILD="$CXXFLAGS_RELEASE" @@ -67,7 +71,8 @@ AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug],[enable debug support [default=no]])],[AC_MSG_NOTICE([enabling debug build]) QMAKE_CONFIG="debug" CXXFLAGS_BUILD="$CXXFLAGS_DEBUG" -SV_DEFINES_BUILD="$SV_DEFINES_DEBUG"]) +SV_DEFINES_BUILD="$SV_DEFINES_DEBUG" +LIBS="$LIBS_DEBUG"]) if test x"$USER_CXXFLAGS" != x; then AC_MSG_NOTICE([The CXXFLAGS environment variable is set to "$USER_CXXFLAGS".]) @@ -86,8 +91,23 @@ SV_MODULE_REQUIRED([rubberband],[rubberband],[rubberband/RubberBandStretcher.h],[rubberband],[rubberband_new]) SV_MODULE_REQUIRED([sord],[sord-0 >= 0.5],[sord/sord.h],[sord-0],[sord_world_new]) SV_MODULE_REQUIRED([serd],[serd-0 >= 0.5],[serd/serd.h],[serd-0],[serd_reader_read_file]) -SV_MODULE_REQUIRED([capnp],[capnp >= 0.6],[capnp/common.h],[capnp],[]) -SV_MODULE_REQUIRED([kj],[kj >= 0.6],[kj/common.h],[kj],[]) + +# We need a Cap'n Proto version with the expectedSizeInWordsFromPrefix +# function, which appeared in v0.6. If we can't find at least that +# version with pkg-config, we check for the symbol with the compiler. +PKG_CHECK_MODULES([capnp],[capnp >= 0.6],[HAVES="$HAVES HAVE_CAPNP";CXXFLAGS="$CXXFLAGS $capnp_CFLAGS";LIBS="$LIBS $capnp_LIBS"],[AC_MSG_NOTICE([Failed to find required module capnp using pkg-config, trying again by old-fashioned means])]) +if test -z "$capnp_LIBS" ; then + AC_COMPILE_IFELSE([ + AC_LANG_SOURCE([[ + #include + int main() { + kj::Array prefix; + return capnp::expectedSizeInWordsFromPrefix(prefix.asPtr()); + }]])], + [HAVES="$HAVES HAVE_CAPNP";LIBS="$LIBS -lcapnp -lkj"], + [AC_MSG_ERROR([Failed to find appropriate capnp library])] + ) +fi SV_MODULE_OPTIONAL([liblo],[],[lo/lo.h],[lo],[lo_address_new]) SV_MODULE_OPTIONAL([portaudio],[portaudio-2.0 >= 19],[portaudio.h],[portaudio],[Pa_IsFormatSupported]) @@ -111,6 +131,7 @@ AC_SUBST(CFLAGS) AC_SUBST(CXXFLAGS) AC_SUBST(CXXFLAGS_MINIMAL) +AC_SUBST(CXXSTANDARD) AC_SUBST(LDFLAGS) AC_SUBST(HAVES) AC_SUBST(LIBS) @@ -118,12 +139,32 @@ AC_SUBST(CC) AC_SUBST(CXX) +AC_SUBST(prefix) + AC_SUBST(QMAKE_CONFIG) AC_CONFIG_FILES([config.pri]) AC_OUTPUT +if test -x repoint ; then + if test -d .hg -o -d .git ; then + if ! ./repoint install; then + AC_MSG_ERROR([Repoint failed; please fix any reported errors and try again]) + fi + else + AC_MSG_NOTICE([Repoint executable found but not in an Hg or Git working-copy: not running it]) + if ! test -d vamp-plugin-sdk ; then + AC_MSG_WARN([No vamp-plugin-sdk directory present, so external libraries might not have been updated]) + fi + fi +else + AC_MSG_NOTICE([No Repoint executable found: assuming external libraries are already here]) + if ! test -d vamp-plugin-sdk ; then + AC_MSG_WARN([No vamp-plugin-sdk directory present, so external libraries might not have been updated]) + fi +fi + if ! $QMAKE -r sonic-visualiser.pro; then AC_MSG_ERROR([qmake failed: Command was "$QMAKE -r"]) fi diff -r 246bdf94ef7b -r 55d9bbf1fe45 convert.pro --- a/convert.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/convert.pro Mon Sep 17 14:05:41 2018 +0100 @@ -1,7 +1,7 @@ TEMPLATE = app -CONFIG += stl c++11 exceptions console warn_on +CONFIG += stl exceptions console warn_on CONFIG -= qt @@ -31,7 +31,7 @@ OBJECTS_DIR = o MOC_DIR = o -INCLUDEPATH += piper-cpp vamp-plugin-sdk +INCLUDEPATH += piper-cpp piper-cpp/ext vamp-plugin-sdk include(vamp-plugin-sdk-files.pri) @@ -44,5 +44,5 @@ SOURCES += \ piper-cpp/vamp-capnp/piper-capnp.cpp \ - piper-cpp/json11/json11.cpp \ + piper-cpp/ext/json11/json11.cpp \ piper-cpp/vamp-server/convert.cpp diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/bintray.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/bintray.json Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,28 @@ +{ + "package": { + "name": "sonic-visualiser", + "repo": "sonic-visualiser", + "subject": "sonic-visualiser", + "desc": "Sonic Visualiser", + "website_url": "https://sonicvisualiser.org/", + "vcs_url": "https://code.soundsoftware.ac.uk/hg/sonic-visualiser", + "licenses": ["GPL-2.0"], + "public_download_numbers": false, + "public_stats": false + }, + + "version": { + "name": "Continuous", + "desc": "Uploaded from continuous integration server" + }, + + "files": [ + { + "includePattern": "\./(SonicVisualiser-.*-x86_64\\.AppImage)", + "uploadPattern": "$1", + "matrixParams": { "override": 1 } + } + ], + + "publish": true +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/build-and-test-appimage.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/build-and-test-appimage.sh Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,41 @@ +#!/bin/bash +# +# Docker required + +set -eu + +current=$(hg id | awk '{ print $1; }') + +case "$current" in + *+) echo "ERROR: Current working copy has been modified - unmodified copy required so we know we can check it out separately and obtain the same contents"; exit 2;; + *);; +esac + +echo +echo "Building appimage from revision $current..." + +dockerdir=deploy/linux/docker + +cat "$dockerdir"/Dockerfile_appimage.in | \ + perl -p -e "s/\[\[REVISION\]\]/$current/g" > \ + "$dockerdir"/Dockerfile_appimage.gen + +cat "$dockerdir"/Dockerfile_test_appimage.in | \ + perl -p -e "s/\[\[REVISION\]\]/$current/g" > \ + "$dockerdir"/Dockerfile_test_appimage.gen + +dockertag="cannam/sonic-visualiser-appimage-$current" + +sudo docker build -t "$dockertag" -f "$dockerdir"/Dockerfile_appimage.gen "$dockerdir" + +outdir="$dockerdir/output" +mkdir -p "$outdir" + +container=$(sudo docker create "$dockertag") + +sudo docker cp "$container":output.tar "$outdir" +sudo docker rm "$container" + +( cd "$outdir" ; tar xf output.tar && rm -f output.tar ) + +sudo docker build -f "$dockerdir"/Dockerfile_test_appimage.gen "$dockerdir" diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/deb-skeleton/usr/share/applications/sonic-visualiser.desktop --- a/deploy/linux/deb-skeleton/usr/share/applications/sonic-visualiser.desktop Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/linux/deb-skeleton/usr/share/applications/sonic-visualiser.desktop Mon Sep 17 14:05:41 2018 +0100 @@ -1,5 +1,7 @@ [Desktop Entry] Name=Sonic Visualiser +Comment=Viewing and analysing the contents of music audio files +Comment[fr]=Affichage et analyse des contenus des fichiers audio de musique Exec=sonic-visualiser %U Keywords=audio; sound; visualiser; sonic; Terminal=false diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/deploy-appimage.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/deploy-appimage.sh Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,117 @@ +#!/bin/bash + +set -eu + +program=sonic-visualiser +checker=vamp-plugin-load-checker +piper=piper-vamp-simple-server + +get_id() { + if [ -d .hg ]; then + hg id | sed 's/[+ ].*$//' + elif [ -d .git ]; then + git rev-parse --short HEAD + else + echo "WARNING: can't figure out revision from VCS metadata" 1>&2 + echo "unknown" + fi +} + +version=$(get_id) + +targetdir="${program}.AppDir" + +echo "Target dir is $targetdir" + +if [ -d "$targetdir" ]; then + echo "Target directory exists, not overwriting" + exit +fi + +mkdir "$targetdir" + +mkdir -p "$targetdir"/usr/bin +mkdir -p "$targetdir"/usr/lib + +cp "$program" "$checker" "$piper" "$targetdir"/usr/bin/ + +ldd /usr/lib/x86_64-linux-gnu/libpulse.so.0 || true + +add_dependencies() { + + local binary="$1" + + echo "ldd $binary yields:" + ldd "$binary" + + for lib in $(ldd "$binary" | grep '=> [^ ]*/lib/' | \ + sed 's/^.*=> //' | sed 's/ .*$//'); do + + base=$(basename "$lib") + if grep -v '^#' sv-dependency-builds/linux/appimage/excludelist | + grep -q "^$base$" ; then + echo "excluding: $lib" + continue + fi + + target="$targetdir/usr/lib/$(basename $lib)" + + mkdir -p "$(dirname $target)" + + if [ ! -f "$target" ]; then + + cp -Lv "$lib" "$target" + chmod +x "$target" + + add_dependencies "$lib" + + fi + done +} + +add_dependencies "$program" +add_dependencies "$checker" +add_dependencies "$piper" + +qtplugins="gif icns ico jpeg tga tiff wbmp webp cocoa minimal offscreen xcb" +qtlibdirs="/usr/lib/x86_64-linux-gnu/qt5 /usr/lib/x86_64-linux-gnu/qt /usr/lib/qt5 /usr/lib/qt" + +QTDIR=${QTDIR:-} +if [ -n "$QTDIR" ]; then + qtlibdirs="$QTDIR $qtlibdirs" +fi + +for plug in $qtplugins; do + for libdir in $qtlibdirs; do + lib=$(find $libdir/plugins -name libq$plug.so -print 2>/dev/null || true) + if [ -n "$lib" ]; then + if [ -f "$lib" ]; then + subdir=$(basename $(dirname $lib)) + if [ t"$subdir" = t"plugins" ]; then + subdir="" + fi + target="$targetdir/usr/lib/qt5/plugins/$subdir/$(basename $lib)" + mkdir -p "$(dirname $target)" + cp -v "$lib" "$target" + chmod +x "$target" + add_dependencies "$lib" + break + fi + fi + done +done + +cp "$program.desktop" "$targetdir/" + +cp "icons/sv-icon.svg" "$targetdir/" +cp "icons/sonic-visualiser.svg" "$targetdir/" + +cp sv-dependency-builds/linux/appimage/AppRun-x86_64 "$targetdir/AppRun" +chmod +x "$targetdir/AppRun" + +# Do this with a separate extraction step, so as to make it work even +# in situations where FUSE is unavailable like in a Docker container +export ARCH=x86_64 +sv-dependency-builds/linux/appimage/appimagetool-x86_64.AppImage --appimage-extract +./squashfs-root/AppRun "$targetdir" "SonicVisualiser-$version-x86_64.AppImage" + diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/deploy-deb.sh --- a/deploy/linux/deploy-deb.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/linux/deploy-deb.sh Mon Sep 17 14:05:41 2018 +0100 @@ -1,6 +1,6 @@ #!/bin/bash # -# Run this from the build root +# Run this from the build root (with sudo, I think) usage() { echo @@ -20,7 +20,11 @@ usage fi +set -eu + program=sonic-visualiser +checker=vamp-plugin-load-checker +piper=piper-vamp-simple-server depdir=deploy/linux targetdir="${program}_${version}_${arch}" @@ -38,7 +42,7 @@ mkdir -p "$targetdir"/usr/bin "$targetdir"/usr/share/pixmaps -cp "$program" "$targetdir"/usr/bin/ +cp "$program" "$checker" "$piper" "$targetdir"/usr/bin/ cp icons/sv-icon*.svg "$targetdir"/usr/share/pixmaps/ cp "$program".desktop "$targetdir"/usr/share/applications/ @@ -56,5 +60,5 @@ bash "$depdir"/fix-lintian-bits.sh "$targetdir" -sudo dpkg-deb --build "$targetdir" && lintian "$targetdir".deb +dpkg-deb --build "$targetdir" && lintian "$targetdir".deb diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_appimage.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_appimage.in Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,69 @@ +# This pulls the latest versions of capnp & SV from repos - so you +# will need to defeat the Docker cache by destroying the container +# each time you want to update it +# +FROM ubuntu:14.04 +MAINTAINER Chris Cannam +RUN apt-get update && \ + apt-get install -y \ + software-properties-common \ + build-essential \ + libbz2-dev \ + libfftw3-dev \ + libfishsound1-dev \ + libid3tag0-dev \ + liblo-dev \ + liblrdf0-dev \ + libmad0-dev \ + liboggz2-dev \ + libpulse-dev \ + libasound2-dev \ + libjack-dev \ + libsamplerate-dev \ + libsndfile-dev \ + libsord-dev \ + libxml2-utils \ + libgl1-mesa-dev \ + raptor-utils \ + librubberband-dev \ + git \ + mercurial \ + curl wget \ + mlton \ + autoconf automake libtool lintian + +# NB we do not install portaudio. We don't want to end up including it +# in the bundle, because it comes with a dependency on the JACK +# library which we don't want to bundle and can't assume people will +# have. However, we do install JACK because the Dynamic JACK mechanism +# should ensure we can detect, configure, and use that without +# actually linking against it. We also have Pulse as the default I/O. + +RUN apt-add-repository -y ppa:beineri/opt-qt-5.10.1-trusty +RUN apt-get update && \ + apt-get install -y \ + qt510base \ + qt510svg +RUN apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +RUN hg clone -r[[REVISION]] https://code.soundsoftware.ac.uk/hg/sonic-visualiser + +RUN git clone https://github.com/sandstorm-io/capnproto +WORKDIR capnproto +RUN git checkout v0.6.1 +WORKDIR c++ +RUN autoreconf -i && ./configure && make -j3 && make install + +WORKDIR ../../sonic-visualiser +ENV QTDIR /opt/qt510 +ENV PATH /opt/qt510/bin:$PATH +RUN ./configure +RUN make -j3 + +RUN deploy/linux/deploy-appimage.sh +RUN tar cvf output.tar *.AppImage && cp output.tar .. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_test_appimage.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_test_appimage.in Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,8 @@ +FROM centos:7 +RUN yum update +RUN yum -y groupinstall "X Window System" +RUN yum -y install wget +ADD output/SonicVisualiser-[[REVISION]]-x86_64.AppImage SV.AppImage +RUN chmod +x SV.AppImage +RUN ./SV.AppImage --appimage-extract +RUN ./squashfs-root/AppRun diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_v3.0.1_ubuntu1604 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_v3.0.1_ubuntu1604 Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,43 @@ +FROM ubuntu:16.04 +MAINTAINER Chris Cannam +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + libbz2-dev \ + libfftw3-dev \ + libfishsound1-dev \ + libid3tag0-dev \ + liblo-dev \ + liblrdf0-dev \ + libmad0-dev \ + liboggz2-dev \ + libpulse-dev \ + libsamplerate-dev \ + libsndfile-dev \ + libsord-dev \ + libxml2-utils \ + portaudio19-dev \ + qt5-default libqt5svg5-dev \ + raptor-utils \ + librubberband-dev \ + git \ + mercurial \ + curl wget \ + autoconf automake libtool lintian +RUN apt-get clean && rm -rf /var/lib/apt/lists/* +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 +RUN git clone https://github.com/sandstorm-io/capnproto +WORKDIR capnproto/c++ +RUN ./setup-autotools.sh && autoreconf -i +RUN ./configure --enable-static --disable-shared +RUN make && make install +WORKDIR ../.. +RUN hg clone -rsv_v3.0.1 https://code.soundsoftware.ac.uk/hg/sonic-visualiser +WORKDIR sonic-visualiser +RUN ./configure +RUN make -j3 +RUN deploy/linux/deploy-deb.sh 3.0.1 amd64 +RUN tar cvf output.tar *.deb && cp output.tar .. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_v3.0.2_ubuntu1604 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_v3.0.2_ubuntu1604 Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,43 @@ +FROM ubuntu:16.04 +MAINTAINER Chris Cannam +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + libbz2-dev \ + libfftw3-dev \ + libfishsound1-dev \ + libid3tag0-dev \ + liblo-dev \ + liblrdf0-dev \ + libmad0-dev \ + liboggz2-dev \ + libpulse-dev \ + libsamplerate-dev \ + libsndfile-dev \ + libsord-dev \ + libxml2-utils \ + portaudio19-dev \ + qt5-default libqt5svg5-dev \ + raptor-utils \ + librubberband-dev \ + git \ + mercurial \ + curl wget \ + autoconf automake libtool lintian +RUN apt-get clean && rm -rf /var/lib/apt/lists/* +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 +RUN git clone https://github.com/sandstorm-io/capnproto +WORKDIR capnproto/c++ +RUN ./setup-autotools.sh && autoreconf -i +RUN ./configure --enable-static --disable-shared +RUN make && make install +WORKDIR ../.. +RUN hg clone -rsv_v3.0.2 https://code.soundsoftware.ac.uk/hg/sonic-visualiser +WORKDIR sonic-visualiser +RUN ./configure +RUN make -j3 +RUN deploy/linux/deploy-deb.sh 3.0.2 amd64 +RUN tar cvf output.tar *.deb && cp output.tar .. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_v3.0.3_ubuntu1604 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_v3.0.3_ubuntu1604 Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,44 @@ +FROM ubuntu:16.04 +MAINTAINER Chris Cannam +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + libbz2-dev \ + libfftw3-dev \ + libfishsound1-dev \ + libid3tag0-dev \ + liblo-dev \ + liblrdf0-dev \ + libmad0-dev \ + liboggz2-dev \ + libpulse-dev \ + libsamplerate-dev \ + libsndfile-dev \ + libsord-dev \ + libxml2-utils \ + portaudio19-dev \ + qt5-default libqt5svg5-dev \ + raptor-utils \ + librubberband-dev \ + git \ + mercurial \ + curl wget \ + autoconf automake libtool lintian +RUN apt-get clean && rm -rf /var/lib/apt/lists/* +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 +RUN curl -L -o capnproto-v0.6.0.tar.gz https://github.com/sandstorm-io/capnproto/archive/v0.6.0.tar.gz +RUN tar xf capnproto-v0.6.0.tar.gz +WORKDIR capnproto-0.6.0/c++ +RUN autoreconf -i +RUN ./configure --enable-static --disable-shared +RUN make && make install +WORKDIR ../.. +RUN hg clone -rsv_v3.0.3 https://code.soundsoftware.ac.uk/hg/sonic-visualiser +WORKDIR sonic-visualiser +RUN ./configure +RUN make -j3 +RUN deploy/linux/deploy-deb.sh 3.0.3 amd64 +RUN tar cvf output.tar *.deb && cp output.tar .. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/Dockerfile_v3.0_ubuntu1604 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/Dockerfile_v3.0_ubuntu1604 Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,43 @@ +FROM ubuntu:16.04 +MAINTAINER Chris Cannam +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + libbz2-dev \ + libfftw3-dev \ + libfishsound1-dev \ + libid3tag0-dev \ + liblo-dev \ + liblrdf0-dev \ + libmad0-dev \ + liboggz2-dev \ + libpulse-dev \ + libsamplerate-dev \ + libsndfile-dev \ + libsord-dev \ + libxml2-utils \ + portaudio19-dev \ + qt5-default libqt5svg5-dev \ + raptor-utils \ + librubberband-dev \ + git \ + mercurial \ + curl wget \ + autoconf automake libtool lintian +RUN apt-get clean && rm -rf /var/lib/apt/lists/* +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 +RUN git clone https://github.com/sandstorm-io/capnproto +WORKDIR capnproto/c++ +RUN ./setup-autotools.sh && autoreconf -i +RUN ./configure --enable-static --disable-shared +RUN make && make install +WORKDIR ../.. +RUN hg clone -rsv_v3.0 https://code.soundsoftware.ac.uk/hg/sonic-visualiser +WORKDIR sonic-visualiser +RUN ./configure +RUN make -j3 +RUN deploy/linux/deploy-deb.sh 3.0 amd64 +RUN tar cvf output.tar *.deb && cp output.tar .. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/docker/build.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/linux/docker/build.sh Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,48 @@ +#!/bin/bash + +version=$(perl -p -e 's/^[^"]*"([^"]*)".*$/$1/' version.h | sed 's/-//g') + +dockerdir=./deploy/linux/docker +if [ ! -d "$dockerdir" ]; then + echo "Run this script from the build root" + exit 2 +fi + +platform="$1" + +if [ -z "$platform" ] || [ -n "$2" ]; then + echo "Usage: $0 " + echo "where matches the suffix of the Docker file, e.g. ubuntu1604" + exit 2 +fi + +set -eu + +echo "Building for version $version, platform $platform" +dockerfile="Dockerfile_v${version}_${platform}" + +if [ ! -f "$dockerdir/$dockerfile" ]; then + echo "No matching docker file $dockerfile found in $dockerdir, trying again without version" + dockerfile="Dockerfile_${platform}" + if [ ! -f "$dockerdir/$dockerfile" ]; then + echo "No matching docker file $dockerfile found in $dockerdir either" + exit 1 + fi +fi + +dockertag="cannam/sonic-visualiser-$platform" + +sudo docker build -t "$dockertag" -f "$dockerdir/$dockerfile" "$dockerdir" + +outdir="$dockerdir/output" +mkdir -p "$outdir" + +container=$(sudo docker create "$dockertag") +sudo docker cp "$container":output.tar "$outdir" +sudo docker rm "$container" + +( cd "$outdir" ; tar xf output.tar && rm -f output.tar ) + +echo +echo "Done, output directory contains:" +ls -ltr "$outdir" diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/linux/fix-lintian-bits.sh --- a/deploy/linux/fix-lintian-bits.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/linux/fix-lintian-bits.sh Mon Sep 17 14:05:41 2018 +0100 @@ -4,6 +4,8 @@ [ -d "$dir" ] || exit 1 +set -eu + strip "$dir"/usr/bin/* sz=`du -sx --exclude DEBIAN "$dir" | awk '{ print $1; }'` @@ -11,6 +13,6 @@ find "$dir" -name \*~ -exec rm \{\} \; -sudo chown -R root.root "$dir"/* +chown -R root.root "$dir"/* -sudo chmod -R g-w "$dir"/* +chmod -R g-w "$dir"/* diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/osx/copy-qt.sh --- a/deploy/osx/copy-qt.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/osx/copy-qt.sh Mon Sep 17 14:05:41 2018 +0100 @@ -11,7 +11,7 @@ frameworks="QtCore QtNetwork QtGui QtXml QtSvg QtWidgets QtPrintSupport QtDBus" -plugins="dds gif icns ico jpeg tga tiff wbmp webp cocoa minimal offscreen" +plugins="gif icns ico jpeg tga tiff wbmp webp cocoa minimal offscreen macstyle" qtdir=$(grep "Command:" Makefile | head -1 | awk '{ print $3; }' | sed s,/bin/.*,,) @@ -29,6 +29,12 @@ echo echo "Copying frameworks..." for fwk in $frameworks; do + if [ ! -d "$qtdir/lib/$fwk.framework" ]; then + if [ "$fwk" = "QtDBus" ]; then + echo "QtDBus.framework not found, assuming Qt was built without DBus support" + continue + fi + fi cp -v "$qtdir/lib/$fwk.framework/$fwk" "$fdir" || exit 2 done diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/osx/deploy.sh --- a/deploy/osx/deploy.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/osx/deploy.sh Mon Sep 17 14:05:41 2018 +0100 @@ -22,9 +22,10 @@ version=`perl -p -e 's/^[^"]*"([^"]*)".*$/$1/' version.h` stem=${version%%-*} +stem=${stem%%pre*} case "$stem" in - [0-9].[0-9]) bundleVersion="$version".0 ;; - [0-9].[0-9].[0-9]) bundleVersion="$version" ;; + [0-9].[0-9]) bundleVersion="$stem".0 ;; + [0-9].[0-9].[0-9]) bundleVersion="$stem" ;; *) echo "Error: Version stem $stem (of version $version) is neither two- nor three-part number" ;; esac @@ -45,8 +46,8 @@ cp deploy/osx/qt.conf "$source"/Contents/Resources/qt.conf echo -echo "Copying in plugin load checker helper." -cp checker/plugin-checker-helper "$source"/Contents/MacOS/ +echo "Copying in plugin load checker." +cp checker/vamp-plugin-load-checker "$source"/Contents/MacOS/ echo echo "Copying in plugin server." @@ -71,9 +72,16 @@ mkdir "$volume" || exit 1 ln -s /Applications "$volume"/Applications -cp README README.OSC COPYING CHANGELOG "$volume/" +cp README.md "$volume/README.txt" +cp README.OSC "$volume/README-OSC.txt" +cp COPYING "$volume/COPYING.txt" +cp CHANGELOG "$volume/CHANGELOG.txt" +cp CITATION "$volume/CITATION.txt" cp -rp "$source" "$target" +# update file timestamps so as to make the build date apparent +find "$volume" -exec touch \{\} \; + echo "Done" echo @@ -86,7 +94,7 @@ echo echo "Making dmg..." -hdiutil create -srcfolder "$volume" "$dmg" -volname "$volume" && +hdiutil create -srcfolder "$volume" "$dmg" -volname "$volume" -fs HFS+ && rm -r "$volume" echo "Done" diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/osx/sign.sh --- a/deploy/osx/sign.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/osx/sign.sh Mon Sep 17 14:05:41 2018 +0100 @@ -13,15 +13,16 @@ exit 2 fi for app in "$dir"/*.app; do - find "$app" -name Qt\* -print | while read fr; do - codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" - done - find "$app" -name \*.dylib -print | while read fr; do - codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" - done - find "$app/Contents/MacOS" -type f -print | while read fr; do - codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" - done + codesign -s "Developer ID Application: Chris Cannam" -fv --deep "$app" +# find "$app" -name Qt\* -print | while read fr; do +# codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" +# done +# find "$app" -name \*.dylib -print | while read fr; do +# codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" +# done +# find "$app/Contents/MacOS" -type f -print | while read fr; do +# codesign -s "Developer ID Application: Chris Cannam" -fv "$fr" +# done codesign -s "Developer ID Application: Chris Cannam" -fv \ --requirements '=designated => identifier "org.sonicvisualiser.SonicVisualiser" and ( (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] ) or (anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] and certificate leaf[field.1.2.840.113635.100.6.1.13] and certificate leaf[subject.OU] = "M2H8666U82"))' \ "$app" diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/src/archive-tip.sh --- a/deploy/src/archive-tip.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/src/archive-tip.sh Mon Sep 17 14:05:41 2018 +0100 @@ -1,8 +1,18 @@ #!/bin/bash -tag=`hg id | awk '{ print $1; }'` +id=`hg id | awk '{ print $1; }'` -echo "Packaging from tag $tag..." +case "$id" in + *+) echo "ERROR: Current working copy has been modified - unmodified copy required"; exit 2;; + *);; +esac -hg archive -r"$tag" --subrepos --exclude sv-dependency-builds /tmp/sonic-visualiser-"$tag".tar.gz +echo "Packaging from id $id..." +hg update -r"$id" + +./repoint archive /tmp/sonic-visualiser-"$id".tar.gz --exclude sv-dependency-builds repoint.pri + +echo Done +echo + diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/src/archive.sh --- a/deploy/src/archive.sh Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/src/archive.sh Mon Sep 17 14:05:41 2018 +0100 @@ -6,10 +6,21 @@ v=`echo "$tag" | sed 's/sv_v//' | sed 's/_.*$//'` +current=$(hg id | awk '{ print $1; }') + +case "$current" in + *+) echo "ERROR: Current working copy has been modified - unmodified copy required so we can update to tag and back again safely"; exit 2;; + *);; +esac + echo echo -n "Packaging up version $v from tag $tag... " -hg archive -r"$tag" --subrepos --exclude sv-dependency-builds /tmp/sonic-visualiser-"$v".tar.gz +hg update -r"$tag" + +./repoint archive /tmp/sonic-visualiser-"$v".tar.gz --exclude sv-dependency-builds repoint.pri + +hg update -r"$current" echo Done echo @@ -23,5 +34,7 @@ echo "*** WARNING: Documentation URL returns a 404:" echo "*** $doc_url" echo "*** Please fix this before release!" + echo "*** And remember to update the link from" + echo " http://www.sonicvisualiser.org/documentation.html !" echo fi diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win32/README-Vamp.txt --- a/deploy/win32/README-Vamp.txt Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/win32/README-Vamp.txt Mon Sep 17 14:05:41 2018 +0100 @@ -1,5 +1,5 @@ -To add Vamp audio analysis plugins to the Transform menu in -Sonic Visualiser, unpack them into this directory. +To add 32-bit Vamp audio analysis plugins to the Transform menu in +Sonic Visualiser, unpack and copy them into this directory. See http://vamp-plugins.org/ for more information. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win32/build.cmd --- a/deploy/win32/build.cmd Mon Sep 17 13:53:25 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -@ECHO OFF -SET WIXPATH="C:\Program Files (x86)\WiX Toolset v3.9\bin" -IF NOT EXIST %WIXPATH% ( - SET WIXPATH="C:\Program Files\WiX Toolset v3.9\bin" -) -DEL sonic-visualiser.msi -%WIXPATH%\candle.exe -v sonic-visualiser.wxs -%WIXPATH%\light.exe -b ..\.. -ext WixUIExtension -v sonic-visualiser.wixobj -PAUSE -DEL sonic-visualiser.wixobj -DEL sonic-visualiser.wixpdb diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win32/main.bmp Binary file deploy/win32/main.bmp has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win32/sonic-visualiser.wxs --- a/deploy/win32/sonic-visualiser.wxs Mon Sep 17 13:53:25 2018 +0100 +++ b/deploy/win32/sonic-visualiser.wxs Mon Sep 17 14:05:41 2018 +0100 @@ -5,15 +5,15 @@ Id="*" Language="1033" Codepage="1252" - Version="2.5.0" + Version="3.2" UpgradeCode="D476941E-65F3-4962-9E72-B40FAAE5DBD0" Manufacturer="Queen Mary, University of London"> + - - - + + + - - - + - + - - + - - - + + - - - - + + + + + + + - - + + - - - - - + + + + + + + + + + + + + + + + + + + + + - + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - + + + + + + + @@ -209,18 +228,21 @@ + Id="Complete" + Title="Required files" + Description="Installs the required files for running Sonic Visualiser." + AllowAdvertise="no" + Absent="disallow" + ConfigurableDirectory="APPLICATIONFOLDER" + Level="1"> + + + @@ -233,11 +255,14 @@ - + - + - + + + + diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win32/top.bmp Binary file deploy/win32/top.bmp has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/License.rtf Binary file deploy/win64/License.rtf has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/README-Vamp.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/README-Vamp.txt Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,8 @@ + +To add 64-bit Vamp audio analysis plugins to the Transform menu in +Sonic Visualiser, unpack and copy them into this directory. + +(For 32-bit plugins, put them in "C:\Program Files (x86)\Vamp Plugins" +instead, or the equivalent in your local language edition of Windows.) + +See http://vamp-plugins.org/ for more information. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/README-Vamp32.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/README-Vamp32.txt Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,8 @@ + +To add 32-bit Vamp audio analysis plugins to the Transform menu in +Sonic Visualiser, unpack and copy them into this directory. + +(For 64-bit plugins, put them in "C:\Program Files\Vamp Plugins" +instead, or the equivalent in your local language edition of Windows.) + +See http://vamp-plugins.org/ for more information. diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/build-32.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/build-32.bat Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,55 @@ +rem Run this from within the top-level SV dir: deploy\win64\build-32.bat +rem To build from clean, delete the folder build_win32 + +set STARTPWD=%CD% + +set QTDIR=C:\Qt\5.11.1\mingw53_32 +if not exist %QTDIR% ( +@ echo Could not find 32-bit Qt +@ exit /b 2 +) + +set ORIGINALPATH=%PATH% +set PATH=%PATH%;C:\Program Files (x86)\SMLNJ\bin;%QTDIR%\bin;C:\Qt\Tools\QtCreator\bin;C:\Qt\Tools\mingw530_32\bin + +cd %STARTPWD% + +call .\repoint install +if %errorlevel% neq 0 exit /b %errorlevel% + +sv-dependency-builds\win32-mingw\bin\capnp -Isv-dependency-builds/win32-mingw/include compile --src-prefix=piper/capnp -osv-dependency-builds/win32-mingw/bin/capnpc-c++:piper-cpp/vamp-capnp piper/capnp/piper.capnp +if %errorlevel% neq 0 exit /b %errorlevel% + +mkdir build_win32 +cd build_win32 + +qmake -spec win32-g++ -r ..\sonic-visualiser.pro +if %errorlevel% neq 0 exit /b %errorlevel% + +mingw32-make +if %errorlevel% neq 0 exit /b %errorlevel% + +copy .\checker\release\vamp-plugin-load-checker.exe .\release + +copy %QTDIR%\bin\Qt5Core.dll .\release +copy %QTDIR%\bin\Qt5Gui.dll .\release +copy %QTDIR%\bin\Qt5Widgets.dll .\release +copy %QTDIR%\bin\Qt5Network.dll .\release +copy %QTDIR%\bin\Qt5Xml.dll .\release +copy %QTDIR%\bin\Qt5Svg.dll .\release +copy %QTDIR%\bin\Qt5Test.dll .\release +copy %QTDIR%\bin\libgcc_s_dw2-1.dll .\release +copy %QTDIR%\bin\"libstdc++-6.dll" .\release +copy %QTDIR%\bin\libwinpthread-1.dll .\release +copy %QTDIR%\plugins\platforms\qminimal.dll .\release +copy %QTDIR%\plugins\platforms\qwindows.dll .\release +copy %QTDIR%\plugins\styles\qwindowsvistastyle.dll .\release + +rem some of these expect to be run from the project root +cd .. +build_win32\release\test-svcore-base +build_win32\release\test-svcore-system +build_win32\release\test-svcore-data-fileio +build_win32\release\test-svcore-data-model + +set PATH=%ORIGINALPATH% diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/build-64.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/build-64.bat Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,62 @@ +rem Run this from within the top-level SV dir: deploy\win64\build-64.bat +rem To build from clean, delete the folder build_win64 first + +echo on + +set STARTPWD=%CD% + +set QTDIR=C:\Qt\5.11.1\msvc2017_64 +if not exist %QTDIR% ( +@ echo Could not find 64-bit Qt +@ exit /b 2 +) + +if not exist "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" ( +@ echo "Could not find MSVC vars batch file" +@ exit /b 2 +) + +call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 + +set ORIGINALPATH=%PATH% +set PATH=%PATH%;C:\Program Files (x86)\SMLNJ\bin;%QTDIR%\bin + +cd %STARTPWD% + +call .\repoint install +if %errorlevel% neq 0 exit /b %errorlevel% + +sv-dependency-builds\win64-msvc\bin\capnp -Isv-dependency-builds/win64-msvc/include compile --src-prefix=piper/capnp -osv-dependency-builds/win64-msvc/bin/capnpc-c++:piper-cpp/vamp-capnp piper/capnp/piper.capnp +if %errorlevel% neq 0 exit /b %errorlevel% + +mkdir build_win64 +cd build_win64 + +qmake -spec win32-msvc -r -tp vc ..\sonic-visualiser.pro +if %errorlevel% neq 0 exit /b %errorlevel% + +msbuild sonic-visualiser.sln /t:Build /p:Configuration=Release +if %errorlevel% neq 0 exit /b %errorlevel% + +copy .\checker\release\vamp-plugin-load-checker.exe .\release + +copy %QTDIR%\bin\Qt5Core.dll .\release +copy %QTDIR%\bin\Qt5Gui.dll .\release +copy %QTDIR%\bin\Qt5Widgets.dll .\release +copy %QTDIR%\bin\Qt5Network.dll .\release +copy %QTDIR%\bin\Qt5Xml.dll .\release +copy %QTDIR%\bin\Qt5Svg.dll .\release +copy %QTDIR%\bin\Qt5Test.dll .\release +copy %QTDIR%\plugins\platforms\qminimal.dll .\release +copy %QTDIR%\plugins\platforms\qwindows.dll .\release +copy %QTDIR%\plugins\styles\qwindowsvistastyle.dll .\release +copy ..\sv-dependency-builds\win64-msvc\lib\libsndfile-1.dll .\release + +rem some of these expect to be run from the project root +cd .. +build_win64\release\test-svcore-base +build_win64\release\test-svcore-system +build_win64\release\test-svcore-data-fileio +build_win64\release\test-svcore-data-model + +set PATH=%ORIGINALPATH% diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/build-and-package.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/build-and-package.bat Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,52 @@ +rem Run this from within the top-level SV dir: deploy\win64\build-and-package.bat + +set STARTPWD=%CD% + +if not exist "C:\Program Files (x86)\SMLNJ\bin" ( +@ echo Could not find SML/NJ, required for Repoint +@ exit /b 2 +) + +if not exist "C:\Program Files (x86)\WiX Toolset v3.11\bin" ( +@ echo Could not find WiX Toolset +@ exit /b 2 +) + +@echo Rebuilding 32-bit + +cd %STARTPWD% +del /q /s build_win32 +call .\deploy\win64\build-32.bat +if %errorlevel% neq 0 exit /b %errorlevel% + +@echo Rebuilding 64-bit + +cd %STARTPWD% +del /q /s build_win64 +call .\deploy\win64\build-64.bat +if %errorlevel% neq 0 exit /b %errorlevel% + +set PATH=%PATH%;"C:\Program Files (x86)\WiX Toolset v3.11\bin" + +@echo Packaging 32-bit + +cd %STARTPWD%\build_win32 +del sonic-visualiser.msi +candle -v ..\deploy\win32\sonic-visualiser.wxs +light -b . -ext WixUIExtension -ext WixUtilExtension -v sonic-visualiser.wixobj +if %errorlevel% neq 0 exit /b %errorlevel% +del sonic-visualiser.wixobj +del sonic-visualiser.wixpdb + +@echo Packaging 64-bit + +cd %STARTPWD%\build_win64 +del sonic-visualiser.msi +candle -v ..\deploy\win64\sonic-visualiser.wxs +light -b . -ext WixUIExtension -ext WixUtilExtension -v sonic-visualiser.wixobj +if %errorlevel% neq 0 exit /b %errorlevel% +del sonic-visualiser.wixobj +del sonic-visualiser.wixpdb + +@echo Done + diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/sonic-visualiser.wxs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/sonic-visualiser.wxs Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 246bdf94ef7b -r 55d9bbf1fe45 deploy/win64/store-notes.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/deploy/win64/store-notes.txt Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,62 @@ + +Notes on the Desktop Bridge for Windows Store packaging +======================================================= + +* Main page + + https://developer.microsoft.com/en-us/windows/bridges/desktop + +* Introductory tutorial + + https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-run-desktop-app-converter + +* Desktop App Converter is the helper application that does the + conversion; Desktop Bridge is, apparently, the technology, which can + be used without using the Desktop App Converter. Here's a page about + doing the conversion manually: + + https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-manual-conversion + +* Note about C++ runtime dependency + + https://support.microsoft.com/en-gb/help/3176696/c-runtime-framework-packages-for-desktop-bridge + + but see also + + https://social.msdn.microsoft.com/Forums/windowsapps/en-US/3f1d9bdd-2fa0-463f-b4f9-02e9bf33ed1a/uwp-desktop-bridge-cant-install-app-even-after-signing-the-certificates-with-signtool?forum=wpdevelop + + "If you submit the app to the store, customers downloading it from the + store will automatically also download the framework package. + + "If you want your customers to sideload the app, then yes, they'll + first have to install the framework package." + + +Preparation +----------- + +* Set up Desktop App Converter as described in https://docs.microsoft.com/en-us/windows/uwp/porting/desktop-to-uwp-run-desktop-app-converter +* Install VC140 runtime dependency (for developer installation of package) from link at https://blogs.msdn.microsoft.com/vcblog/2016/07/07/using-visual-c-runtime-in-centennial-project/ +* Start PowerShell as administrator +* cd C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0\Appx\Retail\x64 +* Run Add-AppxPackage on the one package in that dir + +Invocation +---------- + +* Start PowerShell as administrator +* Run e.g.: DesktopAppConverter.exe -Installer C:\Users\Chris\Documents\sonic-visualiser\deploy\win64\sonic-visualiser.msi -Destination . -PackageName "SonicVisualiser" -Publisher CN="sonicvisualiser.org" -Version 3.0.3.0 -MakeAppx -Sign -Verify -Verbose +* Locate the self-signed certificate file "auto-generated.cer" in Explorer, double-click, Install Certificate, pick Local Machine and the Trusted People store +* Double click on SonicVisualiser.appx to install + +Command based on actual Store data: + +DesktopAppConverter.exe -Installer C:\Users\Chris\Documents\sonic-visualiser\deploy\win64\sonic-visualiser-3.0.3-win64.msi -Destination . -PackageName "27750sonicvisualiser.org.SonicVisualiser" -AppId "SonicVisualiser" -AppDisplayName "Sonic Visualiser" -PackageDisplayName "Sonic Visualiser" -Publisher CN="55F5913E-18B3-470B-9056-D601FF241EB2" -PackagePublisherDisplayName "sonicvisualiser.org" -Version 3.0.3.0 -AppFileTypes "'.sv','.svl','.wav'" -MakeAppx -Sign -Verify -Verbose + +NB the last digit (revision) of the version number must be 0 for store +submission. + +Can't submit Desktop Bridge apps through just any store account -- it +has to be approved first via form at +https://developer.microsoft.com/en-us/windows/projects/campaigns/desktop-bridge +-- still waiting for this. diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_cs_CZ.qm Binary file i18n/sonic-visualiser_cs_CZ.qm has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_cs_CZ.ts --- a/i18n/sonic-visualiser_cs_CZ.ts Mon Sep 17 13:53:25 2018 +0100 +++ b/i18n/sonic-visualiser_cs_CZ.ts Mon Sep 17 14:05:41 2018 +0100 @@ -38,6 +38,13 @@ + AlignmentView + + AlignmentView + Pohled na zarovnání + + + AudioCallbackPlaySource Stop at %1 @@ -53,6 +60,17 @@ + AudioCallbackRecordTarget + + recorded-%1.wav + nahráno-%1.wav + + + Recorded %1 + Nahráno %1 + + + AudioDial %2%3 @@ -82,6 +100,10 @@ New value for %1, from %2 to %3 %4: Nová hodnota pro %1, od %2 do %3 %4: + + %1: %2 + %1: %2 + AudioTargetFactory @@ -164,6 +186,14 @@ Failed to open file for reading Otevření souboru pro čtení se nezdařilo + + Failed to open file handle for writing + Otevření manipulátoru souboru pro zápis se nezdařilo + + + Failed to open file handle for reading + Otevření manipulátoru souboru pro čtení se nezdařilo + BundleCommand @@ -255,11 +285,11 @@ Pitch - Výška tónu + Výška tónu Explicitly, in milliseconds - + Otevřeně, v milisekundách @@ -294,11 +324,11 @@ Normalize Columns - Normalizovat sloupce + Normalizovat sloupce Normalize Visible Area - Normalizovat viditelnou oblast + Normalizovat viditelnou oblast Colour @@ -336,12 +366,51 @@ Invert Vertical Scale Obrátit svislou stupnici + + Normalization + Normalizace + + + None + Žádný + + + Col + Barva + + + View + Pohled + + + Hybrid + Smíšený + + + + ColourComboBox + + Name New Colour + Pojmenovat novou barvu + + + Enter a name for the new colour: + Zadejte název pro novou barvu: + + + Prefer black background for this colour + Upřednostňovat černé pozadí pro tuto barvu + + + Add New Colour... + Přidat novou barvu... + ColourMapper Black on White - Černá na bílé + Černá na bílé Yellow on Black @@ -349,19 +418,19 @@ Banded - Pruhovaný + Pruhovaný <unknown> - <neznámý> + <neznámý> Sunset - Západ slunce + Západ slunce Fruit Salad - Ovocný salát + Ovocný salát Red on Blue @@ -369,7 +438,7 @@ Printer - Tiskárna + Tiskárna Blue on Black @@ -381,31 +450,19 @@ High Gain - Zesílení výšek + Zesílení výšek Highlight - Zvýraznění + Zvýraznění White on Black - Bílá na černé + Bílá na černé Green - Zelená - - - Cherry - - - - Wasp - - - - Ice - + Zelená @@ -470,7 +527,7 @@ DecodingWavFileReader Decoding %1... - Dekóduje se %1... + Dekóduje se %1... @@ -590,7 +647,7 @@ Transforms supplied to a single FeatureExtractionModelTransformer instance must be similar in every respect except plugin output - + Proměny poskytnuté jedné instanci FeatureExtractionModelTransformer musí být podobné v každém ohledu vyjma výstupu přídavného modulu @@ -636,62 +693,62 @@ FlexiNoteLayer New Point - Nový bod + Nový bod Vertical Scale - Svislá stupnice + Svislá stupnice Scale Units - Jednotky stupnice + Jednotky stupnice Scale - Stupnice + Stupnice Auto-Align - Automatické zarovnání + Automatické zarovnání Linear - + Lineární Log - Zápis + Záznam MIDI Notes - Noty MIDI + Noty MIDI In progress - Probíhá + Probíhá No local points - Žádné místní body + Žádné místní body %1 (%2, %3 Hz) - %1 (%2, %3 Hz) + %1 (%2, %3 Hz) %1 Hz (%2, %3) - %1 Hz (%2, %3) + %1 Hz (%2, %3) %1 %2 - %1 %2 + %1 %2 Time: %1 Pitch: %2 Duration: %3 No label - Čas: %1 + Čas: %1 Výška: %2 Doba trvání: %3 Žádný štítek @@ -701,113 +758,113 @@ Pitch: %2 Duration: %3 Label: %4 - Čas: %1 + Čas: %1 Výška: %2 Doba trvání: %3 Štítek: %4 Draw Point - Nakreslit bod + Nakreslit bod Erase Point - Vymazat bod + Vymazat bod Drag Point - + Táhnout bod Edit Point - Upravit bod + Upravit bod Relocate Point - Přemístit bod + Přemístit bod Change Point Value - Změnit hodnotu bodu + Změnit hodnotu bodu Add Point - Přidat bod + Přidat bod Snap Notes - + Přichytit poznámky Merge Notes - + Sloučit poznámky Drag Selection - Táhnout výběr + Táhnout výběr Resize Selection - Změnit velikost výběru + Změnit velikost výběru Delete Selected Points - Smazat vybrané body + Smazat vybrané body Re-align pasted items? - Zarovnat vložené položky znovu? + Zarovnat vložené položky znovu? The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - Položky, které vkládáte, přišly z vrstvy s odlišným zdrojovým materiálem, než má tento. Chcete je zarovnat znovu v čase, aby se hodily ke zdrojovému materiálu pro tuto vrstvu? + Položky, které vkládáte, přišly z vrstvy s odlišným zdrojovým materiálem, než má tento. Chcete je zarovnat znovu v čase, aby se hodily ke zdrojovému materiálu pro tuto vrstvu? Paste - Vložit + Vložit Record FlexiNote - + Nahrát FlexiNote FlexiNoteModel FlexiNote - + FlexiNote Time - Čas + Čas Frame - + Snímek Pitch - Výška tónu + Výška tónu Duration - Doba trvání + Doba trvání Level - Úroveň + Úroveň Label - Štítek + Štítek Unknown - Neznámý + Neznámý Edit Data - Upravit data + Upravit data @@ -1178,7 +1235,9 @@ %1 session files (*.%1) RDF files (%3) All files (*.*) - + %1 soubory sezení (*.%1) +Soubory RDF (%3) +Všechny soubory (*.*) All supported files (%1 %2) @@ -1189,7 +1248,14 @@ MIDI files (*.mid) Text files (*.txt) All files (*.*) - + Všechny podporované soubory (%1 %2) +Čárkou oddělené datové soubory (*.csv) +Soubory XML Sonic Visualiser Layer (*.svl) +Mezerou oddělené soubory .lab (*.lab) +Soubory RDF (%2) +Soubory MIDI (*.mid) +Textové soubory (*.txt) +Všechny soubory (*.*) All supported files (%1 %2) @@ -1199,7 +1265,13 @@ RDF files (%2) Text files (*.txt) All files (*.*) - + Všechny podporované soubory (%1 %2) +Čárkou oddělené datové soubory (*.csv) +Soubory XML Sonic Visualiser Layer (*.svl) +Mezerou oddělené soubory .lab (*.lab) +Soubory RDF (%2) +Textové soubory (*.txt) +Všechny soubory (*.*) All supported files (*.sv %1 %2) @@ -1207,14 +1279,21 @@ Audio files (%2) RDF files (%1) All files (*.*) - + Všechny podporované soubory (*.sv %1 %2) +%3 soubory sezení (*.%4) +Zvukové soubory (%2) +Soubory RDF (%1) +Všechny soubory (*.*) Comma-separated data files (*.csv) Space-separated .lab files (*.lab) Text files (*.txt) All files (*.*) - + Čárkou oddělené datové soubory (*.csv) +Mezerou oddělené soubory .lab (*.lab) +Textové soubory (*.txt) +Všechny soubory (*.*) All supported files (*.sv %1 %2 %3) @@ -1223,12 +1302,18 @@ Layer files (%2) RDF files (%3) All files (*.*) - + Všechny podporované soubory (*.sv %1 %2 %3) +%4 soubory sezení (*.%5) +Zvukové soubory (%1) +Soubory vrstev (%2) +Soubory RDF (%3) +Všechny soubory (*.*) %1 session files (*.%2) All files (*.*) - + %1 soubory sezení (*.%2) +Všechny soubory (*.*) Comma-separated data files (*.csv) @@ -1237,7 +1322,12 @@ MIDI files (*.mid) Text files (*.txt) All files (*.*) - + Čárkou oddělené datové soubory (*.csv) +Soubory XML Sonic Visualiser Layer (*.svl) +Soubory RDF/Turtle (%1) +Soubory MIDI (*.mid) +Textové soubory (*.txt) +Všechny soubory (*.*) Comma-separated data files (*.csv) @@ -1245,13 +1335,25 @@ RDF/Turtle files (%1) Text files (*.txt) All files (*.*) - + Čárkou oddělené datové soubory (*.csv) +Soubory XML Sonic Visualiser Layer (*.svl) +Soubory RDF/Turtle (%1) +Textové soubory (*.txt) +Všechny soubory (*.*) Comma-separated data files (*.csv) Text files (*.txt) All files (*.*) - + Čárkou oddělené datové soubory (*.csv) +Textové soubory (*.txt) +Všechny soubory (*.*) + + + Scalable Vector Graphics files (*.svg) +All files (*.*) + Soubory SVG (Scalable Vector Graphics) (*.svg) +Všechny soubory (*.*) @@ -1325,7 +1427,7 @@ %1: Key and Mouse Reference - + %1: Klávesové zkratky a myš @@ -1405,6 +1507,14 @@ Cyclical counter Cyklické počítadlo + + Subdivide Points + Rozdělit body na menší části + + + Winnow Points + Protřídit body + Layer @@ -1470,11 +1580,11 @@ Flexible Notes - + Pružné poznámky Unknown Layer - + Neznámá vrstva @@ -1512,6 +1622,20 @@ + LevelPanToolButton + + Click to adjust level and pan + Klepněte pro přizpůsobení úrovně a vyvážení + + + + LevelPanWidget + + Drag vertically to adjust level, horizontally to adjust pan + Táhněte svisle pro přizpůsobení úrovně, vodorovného pro přizpůsobení vyvážení + + + MIDIFileImportDialog <b>Select track to import</b><p>You can only import this file as a single annotation layer, but the file contains more than one track, or notes on more than one channel.<p>Please select the track or merged tracks you wish to import: @@ -1895,7 +2019,8 @@ Space - Mezerník + This text is a shortcut label referring to the space-bar on the keyboard. It probably should not be translated, and certainly should not be translated as if referring to an empty void or to the extra-terrestrial universe. + Add a new layer showing a waveform view @@ -1907,7 +2032,7 @@ With - S + S Scroll the current pane to the left without moving the playback cursor or other panes @@ -2087,7 +2212,7 @@ <br>With Rubber Band &copy; Chris Cannam - <br>Gumička (Rubber Band) &copy; Chris Cannam + <br>Gumička (Rubber Band) &copy; Chris Cannam Erase items from layer @@ -2123,7 +2248,7 @@ <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment using transform "%1":<p>%2 - <b>Spočítání zarovnání se nezdařilo</b><p>Zarovnání zvuku se spočítat s pomocí "%1" nepodařilo:<p>%2 + <b>Spočítání zarovnání se nezdařilo</b><p>Zarovnání zvuku se spočítat s pomocí "%1" nepodařilo:<p>%2 Show Acti&vity Log @@ -2383,7 +2508,7 @@ Adjust the master playback level - Přizpůsobit hlavní úroveň přehrávání + Přizpůsobit hlavní úroveň přehrávání <p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.<br><a href="http://www.sonicvisualiser.org/">http://www.sonicvisualiser.org/</a></p> @@ -2479,7 +2604,7 @@ <br>With Rubber Band v%1 &copy; Chris Cannam - <br>Gumička (Rubber Band) v%1 &copy; Chris Cannam + <br>Gumička (Rubber Band) v%1 &copy; Chris Cannam Show centre indicator, frame times and scale @@ -2491,7 +2616,7 @@ Using - + Find a Transform... @@ -2647,7 +2772,7 @@ With Qt v%1 &copy; Nokia Corporation - S Qt v%1 &copy; Nokia Corporation + S Qt v%1 &copy; Nokia Corporation Add a new layer showing a time ruler @@ -2699,7 +2824,7 @@ About Sonic Visualiser - O programu Sonic Visualiser + O programu Sonic Visualiser Restore non-time-stretched playback @@ -2763,7 +2888,7 @@ Navigate - Navádět + Navedení Import an extra audio file into a new pane @@ -2919,7 +3044,7 @@ Ctrl+Shift+Enter - Ctrl+Shift+Enter + Ctrl+Shift+Enter Audio processing overload @@ -3339,7 +3464,7 @@ <p><small>%1 : %2 configuration</small></p> - <p><small>%1 : %2 nastavení</small></p> + <p><small>%1 : %2 nastavení</small></p> <b>Template file exists</b><p>The template "%1" already exists.<br>Overwrite it? @@ -3407,7 +3532,7 @@ <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam - <br>Podpora pro přídavné moduly Vamp (API v%1, host SDK v%2) &copy; Chris Cannam + <br>Podpora pro přídavné moduly Vamp (API v%1, host SDK v%2) &copy; Chris Cannam Unclassified @@ -3575,7 +3700,7 @@ <br>With Dataquay Qt/RDF library &copy; Chris Cannam - <br>Knihovna Dataquay Qt/RDF &copy; Chris Cannam + <br>Knihovna Dataquay Qt/RDF &copy; Chris Cannam Export audio from selection into a data file @@ -3591,220 +3716,380 @@ Playback Speed + Rychlost přehrávání + + + Export Audio Data... + Vyvést zvuková data... + + + Export Annotation La&yer... + Vyvést poznámkovou &vrstvu... + + + Ctrl+Y + Ctrl+Y + + + Browse Recorded Audio Folder + Procházet složku s nahraným zvukem + + + Open the Recorded Audio folder in the system file browser + Otevřít složku s nahraným zvukem v systémovém prohlížeči souborů + + + Ctrl+Shift+Return + Ctrl+Shift+Enter + + + Show &Unit Converter + Ukázat převodník &jednotek + + + Open a window of pitch and timing conversion utilities + Otevřít okno s nástroji na převádění výšek tónů a časování + + + Switch to Previous Layer + Přepnout na předchozí vrstvu + + + { + { + + + Make the previous layer in the pane current + Udělat předchozí vrstvu v tabulce nynější + + + Switch to Next Layer + Přepnout na další vrstvu + + + } + } + + + Make the next layer in the pane current + Udělat další vrstvu v tabulce nynější + + + Record + Nahrát + + + Ctrl+Space + Ctrl+Mezerník + + + Record a new audio file + Nahrát nový zvukový soubor + + + Navigate Tool Mouse Actions + Činnosti nástroje pro navedení prováděné myší + + + Click left button and drag to move around + Klepněte levým tlačítkem a táhněte pro přesouvání + + + Zoom to Area + Přiblížit oblast + + + Shift-click left button and drag to zoom to a rectangular area + Shift a klepněte levým tlačítkem a táhněte pro přiblížení obdélníkové oblasti + + + Relocate + Přemístit + + + Double-Click Left + Dvakrát klepněte levým + + + Double-click left button to jump to clicked location + Dvakrát klepněte levým tlačítkem pro skok na klepnuté místo + + + Double-click left button on an item to edit it + Dvakrát klepněte levým tlačítkem na položce pro její upravení + + + Select Tool Mouse Actions + Činnosti nástroje výběru prováděné myší + + + Click left button and drag to select region; drag region edge to resize + Klepněte levým tlačítkem a táhněte pro výběr oblasti; táhněte za okraj oblasti pro změnu její velikosti + + + Multi Select + Vícenásobný výběr + + + Cmd-click left button and drag to select an additional region + Ctrl a klepněte levým tlačítkem a táhněte pro výběr další oblasti + + + Ctrl-click left button and drag to select an additional region + Ctrl a klepněte levým tlačítkem a táhněte pro výběr další oblasti + + + Fine Select + Citlivý výběr + + + Shift-click left button and drag to select without snapping to items or grid + Shift a klepněte levým tlačítkem a táhněte pro výběr bez přichytávání k položkám nebo mřížce + + + Edit Tool Mouse Actions + Činnosti nástroje úprav prováděné myší + + + Move + Posunout + + + Click left button on an item or selected region and drag to move + Klepněte levým tlačítkem na položku nebo vybranou oblast a táhněte pro její přesun + + + Draw Tool Mouse Actions + Činnosti nástroje kreslení prováděné myší + + + Click left button and drag to create new item + Klepněte levým tlačítkem a táhněte pro vytvoření nové položky + + + Erase Tool Mouse Actions + Činnosti nástroje vymazání prováděné myší + + + Click left button on an item to remove it from the layer + Klepněte levým tlačítkem na položku pro její odstranění z vrstvy + + + Measure Tool Mouse Actions + Činnosti nástroje měření prováděné myší + + + Measure Area + Oblast měření + + + Click left button and drag to measure a rectangular area + Klepněte levým tlačítkem a táhněte pro změření obdélníkové oblasti + + + Measure Item + Položka měření + + + Click left button and drag to measure extents of an item or shape + Klepněte levým tlačítkem a táhněte pro změření rozsahu položky nebo tvaru + + + 1. %2 + 1. %2 + + + %1. %2 + %1: %2 + + + Multiplex all of the above + Vícenásobně vše z výše + + + Playback speed: %1% (%2x slower) + Rychlost přehrávání: %1% (%2x pomalejši) + + + Playback speed: %1% (%2x faster) + Rychlost přehrávání: %1% (%2x rychlejší) + + + Problems loading plugins + Potíže při nahrávání přídavných modulů + + + <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 + <b>Vytvoření vrstvy se nezdařilo</b><p>Nepodařilo se vytvořit odvozenou vrstvu.<p>Proměna vrstvy "%1" se nezdařila:<p>%2 + + + <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. + <b>Vytvoření vrstvy se nezdařilo</b><p>Nepodařilo se vytvořit odvozenou vrstvu.<p>Proměna vrstvy "%1" se nezdařila.<p>Nejsou dostupné žádné informace o chybě. + + + <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> + <h3>Je dostupná novější verze</h3><p>Používáte verzi %1 programu Sonic Visualiser, ale nyní je dostupná verze %2.</p><p>Podívejte se, prosím, na stránky <a href="http://sonicvisualiser.org/">projektu Sonic Visualiser</a>, abyste získal více informací.</p> + + + Export SVG File... + Vyvést do souboru SVG... + + + Export a single pane to a scalable SVG image file + Vyvést jednu tabulku do škálovatelného obrázkového souboru SVG + + + Subdivide Selected Instants... + Rozdělit vybrané okamžiky na menší části... + + + Add new instants at regular intervals between the selected instants + Přidat nové okamžiky v pravidelných odstupech mezi vybranými okamžiky + + + Winnow Selected Instants... + Protřídit vybrané okamžiky... + + + Remove subdivisions, leaving only every Nth instant + Odstranit rozdělení na menší části, ponechaje jen každý n-tý okamžik + + + Export the whole pane + Vyvést celou tabulku + + + Export the visible area only + Vyvést pouze viditelnou oblast + + + Which region of the current pane do you want to export as a scalable SVG image? + Kterou oblast nynější tabulky chcete vyvést jako škálovatelný obrázek SVG? + + + Failed to save SVG file + Soubor SVG se nepodařilo uložit + + + Failed to save SVG file %1 + Nepodařilo se uložit soubor SVG %1 + + + Subdivide instants + Rozdělit okamžiky na menší části + + + Number of subdivisions: + Počet rozdělení na menší části: + + + Winnow instants + Protřídit body + + + Remove all instants apart from multiples of: + Odstranit všechny okamžiky kromě násobků: + + + <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment:<p>%1 + <b>Spočítání zarovnání se nezdařilo</b><p>Nepodařilo se spočítat zarovnání zvuku<p>%1 + + + Adjust the master playback level and pan + Přizpůsobit hlavní úroveň přehrávání a vyvážení + + + With Qt v%1 &copy; The Qt Company + Qt verze %1 &copy; společnost Qt + + + <br>With Rubber Band Library v%1 &copy; Particular Programs Ltd + <br>Knihovna Rubber Band verze %1 &copy; Particular Programs Ltd + + + <br>With Rubber Band Library &copy; Particular Programs Ltd + <br>Knihovna Rubber Band &copy; Particular Programs Ltd + + + <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam and QMUL + <br>Podpora pro přídavné moduly Vamp (API verze %1, host SDK verze %2) &copy; Chris Cannam and QMUL + + + <br>With Dataquay Qt/RDF library &copy; Particular Programs Ltd + <br>Knihovna Dataquay Qt/RDF &copy; Particular Programs Ltd + + + <br>With Cap'n Proto serialisation &copy; Sandstorm Development Group + <br>Vydávání na pokračování Cap'n Proto &copy; Vývojová skupina Sandstorm + + + What's &New? + Co je &nového? + + + Show changes in this release of %1 + Ukázat změny v tomto vydání %1 + + + Failed to query transform attributes + Nepodařilo se zeptat se na vlastnosti proměn + + + <b>Failed to query transform attributes</b><p>Plugin or server error: %1</p> + <b>Nepodařilo se zeptat se na vlastnosti proměn</b><p>Chyba přídavného modulu nebo serveru: %1</p> + + + Transform failed + Proměna selhala + + + <b>Failed to run transform</b><p>Plugin or server error: %1</p> + <b>Nepodařilo se spustit proměnu</b><p>Chyba přídavného modulu nebo serveru: %1</p> + + + What's New + Co je nového + + + <h3>What's New in %1</h3> + <h3>Co je nového v %1</h3> + + + <b>Note:</b> A newer version of Sonic Visualiser is available.<br>(Version %1 is available; you are using version %2) + <b>Poznámka:</b> Je dostupná novější verze programu Sonic Visualiser.<br>(je dostupná verze %1; používáte verzi %2) + + + %1 : %2 configuration, %3-bit build + %1 : %2 nastavení, %3-bitové sestavení + + + About %1 + O %1 + + + Multiplexed audio + Víceproudý zvuk + + + <br>With Piper Vamp protocol bridge &copy; QMUL + <br>Můstkový komunikační protokol Piper Vamp &copy; QMUL + + + Russian UI translation contributed by Alexandre Prokoudine. - Export Audio Data... - &Vyvést zvuková data... - - - Export Annotation La&yer... + Czech UI translation contributed by Pavel Fric. - Ctrl+Y + Shift+; - Browse Recorded Audio Folder + Ctrl+Shift+; - - Open the Recorded Audio folder in the system file browser - - - - Ctrl+Shift+Return - - - - Show &Unit Converter - - - - Open a window of pitch and timing conversion utilities - - - - Switch to Previous Layer - - - - { - - - - Make the previous layer in the pane current - - - - Switch to Next Layer - - - - } - - - - Make the next layer in the pane current - - - - Record - - - - Ctrl+Space - - - - Record a new audio file - - - - Navigate Tool Mouse Actions - Činnosti nástroje pro navádění prováděné myší - - - Click left button and drag to move around - Klepněte levým tlačítkem a táhněte pro přesouvání se - - - Zoom to Area - Přiblížit oblast - - - Shift-click left button and drag to zoom to a rectangular area - Shift-klepněte levým tlačítkem a táhněte pro přiblížení obdélníkové oblasti - - - Relocate - Přemístit - - - Double-Click Left - Dvakrát klepněte levým - - - Double-click left button to jump to clicked location - Dvakrát klepněte levým tlačítkem pro skok na klepnuté místo - - - Double-click left button on an item to edit it - Dvakrát klepněte levým tlačítkem na položce pro její upravení - - - Select Tool Mouse Actions - Činnosti nástroje výběru prováděné myší - - - Click left button and drag to select region; drag region edge to resize - Klepněte levým tlačítkem a táhněte pro výběr oblasti; táhněte za okraj oblasti pro změnu její velikosti - - - Multi Select - Vícenásobný výběr - - - Cmd-click left button and drag to select an additional region - Ctrl-klepněte levým tlačítkem a táhněte pro výběr další oblasti - - - Ctrl-click left button and drag to select an additional region - Ctrl-klepněte levým tlačítkem a táhněte pro výběr další oblasti - - - Fine Select - Citlivý výběr - - - Shift-click left button and drag to select without snapping to items or grid - Shift-klepněte levým tlačítkem a táhněte pro výběr bez zapadávání k položkám nebo mřížce - - - Edit Tool Mouse Actions - Činnosti nástroje úprav prováděné myší - - - Move - Posunout - - - Click left button on an item or selected region and drag to move - Klepněte levým tlačítkem na položku nebo vybranou oblast a táhněte pro její přesun - - - Draw Tool Mouse Actions - Činnosti nástroje kreslení prováděné myší - - - Click left button and drag to create new item - Klepněte levým tlačítkem a táhněte pro vytvoření nové položky - - - Erase Tool Mouse Actions - - - - Click left button on an item to remove it from the layer - - - - Measure Tool Mouse Actions - Činnosti nástroje měření prováděné myší - - - Measure Area - Oblast měření - - - Click left button and drag to measure a rectangular area - Klepněte levým tlačítkem a táhněte pro změření obdélníkové oblasti - - - Measure Item - Položka měření - - - Click left button and drag to measure extents of an item or shape - Klepněte levým tlačítkem a táhněte pro změření rozsahu položky nebo tvaru - - - 1. %2 - - - - %1. %2 - %1: %2 {1.?} - - - Multiplex all of the above - - - - Playback speed: %1% (%2x slower) - - - - Playback speed: %1% (%2x faster) - - - - Problems loading plugins - - - - <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 - - - - <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. - - - - <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> - <h3>Je dostupná novější verze</h3><p>Používáte verzi %1 programu Sonic Visualiser, ale nyní je dostupná verze %3.</p><p>Podívejte se, prosím, na stránky <a href="http://sonicvisualiser.org/">projektu Sonic Visualiser</a>, abyste získal více informací.</p> {3>?} {3>?} {1 ?} {2 ?} - MainWindowBase @@ -3834,7 +4119,7 @@ <b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> - <b>Žádný zvuk není dostupný</b><p> Zvukové zařízení se nepodařilo otevřít pro přehrávání.<p>Automatické určení zvukového zařízení se nezdařilo. Přehrávání zvuku během tohoto sezení nebude dostupné.</p> + <b>Žádný zvuk není dostupný</b><p> Zvukové zařízení se nepodařilo otevřít pro přehrávání.<p>Automatické určení zvukového zařízení se nezdařilo. Přehrávání zvuku během tohoto sezení nebude dostupné.</p> Add Point @@ -3964,10 +4249,83 @@ Import Recorded Audio + Zavést nahraný zvuk + + + Recording: %1 + Nahrává se: %1 + + + Not enough disc space + Nedostatek místa na disku + + + <b>Not enough disc space</b><p>There doesn't appear to be enough spare disc space to accommodate any necessary temporary files.</p><p>Please clear some space and try again.</p> + <b>Nedostatek místa na disku</b><p></p>Zdá se, že na disku není dostatek místa na to, aby pojalo všechny nezbytné dočasné soubory.<p> </p><p>Uvolněte, prosím, nějaké místo a zkuste to znovu.</p> + + + <b>No audio available</b><p>Could not open an audio device.</p> + <b>Není dostupný žádný zvuk</b><p>Nepodařilo se otevřít zvukové zařízení.</p> + + + <b>No audio available</b><p>Could not open audio device: %1</p> + <b>Není dostupný žádný zvuk</b><p>Nepodařilo se otevřít zvukové zařízení: %1</p> + + + <p>Automatic audio device detection failed. Audio playback and recording will not be available during this session.</p> + <p>Automatické zjištění zvukového zařízení selhalo. Přehrávání zvuku a nahrávání nebudou během tohoto sezení dostupné.</p> + + + <p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> + <p>Automatické zjištění zvukového zařízení selhalo. Přehrávání zvuku nebude během tohoto sezení dostupné.</p> + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1").</p> + <b>Není dostupný žádný zvuk</b><p>Nepodařilo se otevřít vámi upřednostňovaný ovladač zvuku ("%1").</p> + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1"): %2.</p> + <b>Není dostupný žádný zvuk</b><p>Nepodařilo se otevřít vámi upřednostňovaný ovladač zvuku ("%1"): %2.</p> + + + <p>Audio playback and recording will not be available during this session.</p> + <p>Přehrávání zvuku a nahrávání nebudou během tohoto sezení dostupné.</p> + + + <p>Audio playback will not be available during this session.</p> + <p>Přehrávání zvuku nebude během tohoto sezení dostupné.</p> + + + No record device available + Není dostupné žádné nahrávací zařízení + + + <b>No record device available</b><p>Failed to find or open an audio device for recording. Only playback will be available.</p> + <p>Není dostupné žádné nahrávací zařízení.</b><p>Nepodařilo se najít nebo otevřít zvukové zařízení pro nahrávání. Bude dostupné pouze přehrávání.</p> + + + Recording failed + Nahrávání selhalo + + + <b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p> + <b>Nahrávání selhalo</b><p>Nepodařilo se přepnout do nahrávacího režimu (nějaké potíže uvnitř?)</p> + + + Not enough memory - Recording: %1 + <b>Not enough memory</b><p>There doesn't appear to be enough memory to accommodate any necessary temporary data.</p> + + + + Incomplete session loaded + + + + Some of the audio content referred to by the original session file could not be loaded. +If you save this session, it will be saved without any reference to that audio, and information may be lost. @@ -4068,15 +4426,27 @@ NetworkPermissionTester Welcome to Sonic Visualiser - - - - <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary, University of London, Sonic Visualiser is provided free as open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like to make networking connections and open a network port.</p><p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control, where configured; and</li><li> Tell you when updates are available.</li></ul><p>No personal information will be sent, no tracking is carried out, and all requests happen in the background without interrupting your work.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful. But if you do not wish to do so, please un-check the box below.<br></p> - + Vítejte v Sonic Visualiseru Allow this - + Povolit + + + <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary University of London, Sonic Visualiser is open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like permission to use the network.</p> + <h2>Vítejte v Sonic Visualiseru!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser je program na zobrazování a zkoumání zvukových dat pro semantický rozbor hudby a psaní poznámek.</p><p>Vyvíjen ve Středisku pro digitální hudbu (Centre for Digital Music) na londýnské univerzitě královny Marie (Queen Mary University of London), Sonic Visualiser je program s otevřeným zdrojovým kódem pod veřejnou obecnou licencí GNU (GNU General Public License).</p><p><hr></p><p><b>Předtím než budeme pokračovat...</b></p><p>Sonic Visualiser chce požádat o svolení k používání sítě.</p> + + + <p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control; and</li><li> Tell you when updates are available.</li></ul> + <p>Účelem je:</p><ul><li> Najít informace o dostupných a nainstalovaných přídavných modulech;</li><li> Podpořit používání Open Sound Control; a</li><li> Říct vám, když jsou dostupné aktualizace.</li></ul> + + + <p>This is to:</p><ul><li> Find information about available and installed plugins; and</li><li> Tell you when updates are available.</li></ul> + <p>Účelem je:</p><ul><li> Najít informace o dostupných a nainstalovaných přídavných modulech;</li><li> Říct vám, když jsou dostupné aktualizace.</li></ul> + + + <p><b>No personal information will be sent, no tracking is carried out, and no individual information will be shared with anyone else.</b> We will however make aggregate counts of distinct requests for usage reporting.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful to you and supports the public funding of this work. But if you do not wish to allow it, please un-check the box below.<br></p> + <p><b>Nebudou odesílány žádné osobní informace, neprovádí se žádné sledování, a žádné údaje o jednotlivci nebudou s nikým dalším sdíleny.</b> Nicméně budeme dělat úhrnné součty odlišných požadavků pro zpravodajství o užití.</p><p>Doporučujeme, abyste toto povolil, protože to pro vás dělá Sonic Visualiser užitečnějším a podporuje veřejné financování této práce. Pokud si to však nepřejete, zrušte, prosím, zaškrtnutí okénka níže.<br></p> @@ -4256,7 +4626,7 @@ Overview Click and drag to navigate; double-click to jump - Klepněte a táhněte pro navádění; dvakrát klepněte pro skok + Klepněte a táhněte pro navedení; dvakrát klepněte pro skok Overview @@ -4355,7 +4725,7 @@ Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate - Klepněte a táhněte pro výběr rozsahu; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navedení Reset horizontal and vertical zoom levels to their defaults @@ -4411,7 +4781,7 @@ Click and drag to select a range; middle-click and drag to navigate - Klepněte a táhněte pro výběr rozsahu; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; klepněte prostředním tlačítkem a táhněte pro navedení Scroll up or down in the vertical axis @@ -4423,7 +4793,7 @@ Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate - Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul zapadávání k položkám; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul přichytávání k položkám; klepněte prostředním tlačítkem a táhněte pro navedení Alt+Wheel @@ -4435,7 +4805,7 @@ Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate - Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul zapadávání k položkám; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul přichytávání k položkám; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navedení Click and drag to adjust the visible range of the vertical scale @@ -4443,7 +4813,7 @@ Click and drag to navigate - Klepněte a táhněte pro navádění + Klepněte a táhněte pro navedení Shift+Wheel @@ -4479,7 +4849,7 @@ Navigate - Navádět + Navedení Ctrl+Left @@ -4515,7 +4885,7 @@ Click middle button and drag to navigate with any tool - Klepněte prostředním tlačítkem a táhněte pro vedení s jakýmkoli nástrojem + Klepněte prostředním tlačítkem a táhněte pro navedení s jakýmkoli nástrojem Double-Click Left @@ -4527,7 +4897,7 @@ Shift-click left button and drag to select without snapping to items or grid - Shift-klepněte levým tlačítkem a táhněte pro výběr bez zapadávání k položkám nebo mřížce + Shift a klepněte levým tlačítkem a táhněte pro výběr bez přichytávání k položkám nebo mřížce Relocate @@ -4539,7 +4909,7 @@ Navigate Tool Mouse Actions - Činnosti nástroje pro navádění prováděné myší + Činnosti nástroje pro navedení prováděné myší Reference @@ -4615,11 +4985,11 @@ Click and drag to select a range; hold Shift to avoid snapping to items; hold Cmd for multi-select; middle-click and drag to navigate - Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul zapadávání k položkám; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; držte klávesu Shift, abyste se vyhnul přichytávání k položkám; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navedení Click and drag to select a range; hold Cmd for multi-select; middle-click and drag to navigate - Klepněte a táhněte pro výběr rozsahu; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navádění + Klepněte a táhněte pro výběr rozsahu; držte klávesu Ctrl pro provedení vícenásobného výběru; klepněte prostředním tlačítkem a táhněte pro navedení @@ -4650,7 +5020,7 @@ Change Playback Sample - + Změnit vzorek přehrávání @@ -4771,6 +5141,125 @@ + PluginPathConfigurator + + Move the selected location later in the list + + + + Move the selected location earlier in the list + + + + Add a new location to the list + + + + Remove the selected location from the list + + + + Reset to Default + + + + Reset the list for this plugin type to its default + + + + Review plugins... + + + + Plugin locations for plugin type: + + + + Vamp + + + + LADSPA + + + + DSSI + + + + Vamp (32-bit) + + + + LADSPA (32-bit) + + + + DSSI (32-bit) + + + + (Variable is currently unset) + + + + (Current value begins: "%1 ...") + + + + (Currently set to: "%1") + + + + Allow the %1 environment variable to take priority over this +%2 + + + + Choose directory to add + + + + + PluginReviewDialog + + Plugins Loaded + + + + Type + Typ + + + Library + + + + Identifier + + + + Found in + + + + Name + Název + + + Vamp + + + + DSSI + + + + LADSPA + + + + Preferences Hann @@ -4942,39 +5431,43 @@ Normalise audio signal when reading from audio file - + Normalizovat zvukový signál při čtení ze zvukového souboru Single fixed sample rate to resample all files to - + Jeden pevný vzorkovací kmitočet pro převzorkování všech souborů Time display precision - + Přesnost zobrazení času Use hours:minutes:seconds format - + Použít formát hodiny:minuty:sekundy Label middle C as - + Opatřit štítkem jednočárkované C (C1, C') C0 - middle of octave scale - + C0 - střed rozsahu oktávy C3 - common MIDI sequencer convention - + C3 - obecná zvyklost pro sekvencer MIDI C4 - ASA American standard - + C4 - americký standard ASA C5 - used in Cakewalk and others - + C5 - používáno v programu Cakewalk a dalších + + + Load mp3 files in gapless mode + Nahrát soubory MP v bezmezerovém režimu @@ -5019,7 +5512,7 @@ Default session template for audio files: - Výchozí předloha sezení pro zvukové soubory: + Výchozí předloha sezení pro zvukové soubory: Anal&ysis @@ -5047,7 +5540,7 @@ &General - &Obecné + &Obecné Playback audio device: @@ -5079,22 +5572,74 @@ Allow network usage - + Povolit používání sítě Draw layers at Retina resolution: - + Kreslit vrstvy v rozlišení Retina: Default spectrogram colour: - + Výchozí barva spektrogramu: Default melodic spectrogram colour: - + Výchozí barva melodického spektrogramu: Default colour 3D plot colour: + Výchozí barva barevného trojrozměrného nákresu: + + + Green + Zelená + + + (auto) + (auto) + + + Overview waveform colour: + Barva tvaru vlny přehledu: + + + Run Vamp plugins in separate process: + Spustit přídavné moduly Vamp v samostatném procesu: + + + Default session template when loading audio files: + Výchozí předloha sezení při nahrávání zvukových souborů: + + + (Use "%1" in the File menu to add to these.) + Použít "%1" v nabídce Soubor pro přidání k těmto.) + + + Export Session as Template... + Vyvést sezení jako předlohu... + + + Audio service: + Zvuková služba: + + + Audio playback device: + Zařízení pro přehrávání zvuku: + + + Audio record device: + Zařízení pro nahrávání zvuku: + + + A&udio I/O + Vstup/Výstup &zvuku + + + &Other + &Jiné + + + &Plugins @@ -5109,11 +5654,11 @@ PropertyBox dB - dB + dB Play - Přehrát + Přehrát Show @@ -5137,11 +5682,11 @@ Playback Pan / Balance - Vyvážení přehrávání/rovnováha + Vyvážení přehrávání/rovnováha Prefer black background for this colour - Upřednostňovat černé pozadí pro tuto barvu + Upřednostňovat černé pozadí pro tuto barvu Toggle Visibility of %1 @@ -5153,23 +5698,35 @@ Add New Colour... - Přidat novou barvu... + Přidat novou barvu... Name New Colour - Pojmenovat novou barvu + Pojmenovat novou barvu Enter a name for the new colour: - Zadejte název pro novou barvu: + Zadejte název pro novou barvu: Playback Gain - Zesílení přehrávání + Zesílení přehrávání Set playback clip: - + Nastavit záběr přehrávání: + + + Click to toggle playback + Klepnout pro přepnutí přehrávání + + + Adjust playback level and pan of %1 + Přizpůsobit úroveň přehrávání a vyvážení %1 + + + Change sound used for playback (currently "%1") + Změnit zvuk používaný pro přehrávání (nyní "%1") @@ -5280,24 +5837,91 @@ QObject - <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> - - - - - Failed to load library - - - - Failed to query plugins from library after loading - - - - Unknown failure - - - - Success: internal error? + External plugin host executable does not appear to be installed + Zdá se, že není nainstalován spustitelný soubor pro vnějšího hostitele přídavného modulu + + + Could not start external plugin host + Nepodařilo se spustit vnějšího hostitele přídavného modulu + + + External plugin host exited unexpectedly while listing plugins + Vnější hostitel přídavného modulu byl během vypisování přídavných modulů neočekávaně ukončen + + + External plugin host invocation failed: %1 + Nepodařilo se vyvolat vnějšího hostitele přídavného modulu: %1 + + + <b>Did not scan for plugins</b><p>Apparently no scan for plugins was attempted (internal error?)</p> + <b>Neprohledáno na přídavné moduly</b><p>Podle všeho nedošlo k žádnému pokusu o prohledání na přídavné moduly (vnitřní chyba?)</p> + + + <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> + <b>Nepodařilo se nahrát přídavné moduly</b><p>Nepodařilo se nahrát jednu nebo více knihoven s přídavnými moduly:</p> + + + <p>These plugins may be incompatible with the system, and will be ignored during this run of %1.</p> + <p>Tyto přídavné moduly se nemusí slučovat se systémem, a budou během tohoto spuštění %1 přehlíženy.</p> + + + <unknown> + <neznámý> + + + Green + Zelená + + + White on Black + Bílá na černé + + + Black on White + Černá na bílé + + + Cherry + Třešňová barva + + + Wasp + Vosa + + + Ice + Led + + + Sunset + Západ slunce + + + Fruit Salad + Ovocný salát + + + Banded + Pruhovaný + + + Highlight + Zvýraznění + + + Printer + Tiskárna + + + High Gain + Zesílení výšek + + + <b>Failed to scan for plugins</b><p>Failed to scan for plugins at startup. Possibly the plugin checker program was not correctly installed alongside %1?</p> + <b>Nepodařilo se prohledat na přídavné moduly</b><p>Při spuštění se nepodařilo provést vyhledání přídavných modulů. Je možné, že kontrolor přídavných modulů nebyl zároveň s %1 správně nainstalován?</p> + + + Exporting audio data... @@ -5305,7 +5929,7 @@ QuickTimeFileReader Decoding %1... - Dekóduje se %1... + Dekóduje se %1... @@ -5341,7 +5965,7 @@ ReadOnlyWaveFileModel Wave File - Soubor Wave + Soubor Wave @@ -5479,7 +6103,7 @@ Frame - Rámeček + Snímek Label @@ -5790,7 +6414,7 @@ -Inf - -Inf + -Inf 25 % @@ -5984,7 +6608,7 @@ Smoothing - Vyhlazování + Vyhlazování dB: %1 @@ -6072,7 +6696,19 @@ Normalization - + Normalizace + + + Col + Barva + + + View + Pohled + + + Hybrid + Smíšený @@ -6083,7 +6719,7 @@ -Inf - -Inf + -Inf 25 % @@ -6173,6 +6809,10 @@ %1 - %2 Hz + + Hz + + SubdividingMenu @@ -6185,11 +6825,11 @@ Surveyer No, thanks - Ne, děkuji + Ne, děkuji Yes! Take me to the survey - Ano! Vezmi mě do průzkumu + Ano! Vezmi mě do průzkumu @@ -6592,39 +7232,35 @@ Discrete Curves - + Samostatné křivky %1 Hz (%2, %3) - %1 Hz (%2, %3) + %1 Hz (%2, %3) %1 %2 - %1 %2 + %1 %2 %1 - %1 + %1 Time: %1 Value: %2 No label - Čas: %1 -Hodnota: %2%3 -Žádný štítek {1 -?} {2 -?} + Čas: %1 +Hodnota: %2 +Žádný štítek Time: %1 Value: %2 Label: %4 - Čas: %1 -Hodnota: %2%3 -Štítek: %4 {1 -?} {2 -?} + Čas: %1 +Hodnota: %2 +Štítek: %4 @@ -6748,6 +7384,10 @@ Effects Data Efektová data + + Failed to list Vamp plugins: %1 + Nepodařilo se vypsat přídavné moduly Vamp: %1 + TransformFinder @@ -6856,56 +7496,57 @@ UnitConverter Pitch - Výška tónu + Výška tónu cents - + centů In 12-tone Equal Temperament: - + V 12-tónovém rovnoměrně temperovaném ladění: = - + = + - + + Piano note - + Nota klavíru in octave - + v oktávě MIDI pitch - + Výška tónu MIDI Note that only pitches in the range 0 to 127 are valid in the MIDI protocol. - + Mějte na paměti, že v protokolu MIDI jsou platnými pouze výšky tónů v rozsahu 0 až 127. Tempo - + Tempo Beat period - + Perioda (doba) rytmu at - + na With concert-A tuning frequency at %1 Hz, and middle C residing in octave %2. (These can be changed in the application preferences.) - + S kmitočtem koncertního ladění A na %1 Hz a jednočárkovaným C spočívajícím v oktávě %2. +(To vše lze změnit v nastavení programu.) @@ -6958,6 +7599,10 @@ Alignment Zarovnání + + Exported image from %1 + Vyvedený obrázek z %1 + ViewManager @@ -6971,7 +7616,7 @@ Enter Navigate mode - Vstoupit do režimu navádění + Vstoupit do režimu navedení Change overlay level @@ -7047,7 +7692,7 @@ Enter NoteEdit mode - + Vstoupit do režimu úprav not @@ -7069,7 +7714,7 @@ -Inf - -Inf + -Inf Gain diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_en_GB.qm Binary file i18n/sonic-visualiser_en_GB.qm has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_en_GB.ts --- a/i18n/sonic-visualiser_en_GB.ts Mon Sep 17 13:53:25 2018 +0100 +++ b/i18n/sonic-visualiser_en_GB.ts Mon Sep 17 14:05:41 2018 +0100 @@ -4,17 +4,17 @@ ActivityLog - + Activity Log - + <p>Activity Log lists your interactions and other events within %1.</p> - + %1: %2 @@ -22,7 +22,7 @@ AddLayerCommand - + Add %1 Layer @@ -44,59 +44,85 @@ + AlignmentView + + + AlignmentView + + + + AudioCallbackPlaySource - + Play from %1 - + Stop at %1 - + Change time-stretch factor to %1 + AudioCallbackRecordTarget + + + recorded-%1.wav + + + + + Recorded %1 + + + + AudioDial - + + %1: %2 + + + + %1: %2%3 - + %2%3 - + New value for %1, from %2 to %3 %4: - + New value for %1, from %2 to %3: - + Enter a new value from %1 to %2 %3: - - + + Enter a new value from %1 to %2: - - + + Enter new value @@ -104,72 +130,82 @@ BZipFileDevice - + File is already open - + Append mode not supported - + File access mode not specified - + Read and write modes both specified - + Failed to open file for writing - + + Failed to open file handle for writing + + + + Failed to open bzip2 stream for writing - + Failed to open file for reading - + + Failed to open file handle for reading + + + + Failed to open bzip2 stream for reading - + Internal error (open for neither read nor write) - + File not open - + bzip2 stream write close error - + bzip2 stream read close error - + Internal error (close for neither read nor write) - + bzip2 stream read error @@ -188,8 +224,7 @@ CSVFileWriter - - + Failed to open file %1 for writing @@ -296,91 +331,114 @@ Colour3DPlotLayer - - + + Colour - - + + Scale - Normalize Columns - Normalise Columns - - - + Normalise Columns + + Normalize Visible Area - Normalise Visible Area - - - + Normalise Visible Area + + + + Normalization + + + + Invert Vertical Scale - + Gain - + Always Opaque - + Smooth - + Bin Scale - + Bins - - + + Linear - - + + Log - + +/-1 - + Absolute - + + None + + + + + Col + + + + + View + + + + + Hybrid + + + + <unknown> - + dB - + Time: %1 - %2 Bin: %3 Value: %4 @@ -388,71 +446,25 @@ - ColourMapper - - - - <unknown> - - - - - White on Black - - - - - Black on White - - - - - Green - - - - - Cherry - - - - - Wasp - - - - - Ice - - - - - Sunset - - - - - Fruit Salad - - - - - Banded - - - - - Highlight - - - - - Printer - - - - - High Gain + ColourComboBox + + + Name New Colour + + + + + Enter a name for the new colour: + + + + + Prefer black background for this colour + + + + + Add New Colour... @@ -535,7 +547,7 @@ DecodingWavFileReader - + Decoding %1... @@ -543,7 +555,7 @@ Dense3DModelPeakCache - + Dense 3-D Peak Cache @@ -551,17 +563,17 @@ DenseThreeDimensionalModel - + Dense 3-D - + Time - + Frame @@ -569,7 +581,7 @@ DenseTimeValueModel - + Dense Time-Value @@ -577,12 +589,12 @@ Document - + Set main model to %1 - + Clear main model @@ -590,7 +602,7 @@ EditableDenseThreeDimensionalModel - + Editable Dense 3-D @@ -598,12 +610,12 @@ FFTModel - + FFT - + %1 Hz @@ -634,53 +646,53 @@ FeatureExtractionModelTransformer - + Transforms supplied to a single FeatureExtractionModelTransformer instance must be similar in every respect except plugin output - + No factory available for feature extraction plugin id "%1" (unknown plugin type, or internal error?) - + Input model for feature extraction plugin "%1" is of wrong type (internal error?) - + Failed to instantiate plugin "%1" - + Cannot provide enough channels to feature extraction plugin "%1" (plugin min is %2, max %3; input model has %4) - - + + Failed to initialise feature extraction plugin "%1" - + Feature extraction plugin "%1" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead - + Transform was configured for version %1 of plugin "%2", but the plugin being used is version %3 - + Plugin "%1" has no outputs - + Plugin "%1" has no output named "%2" @@ -688,29 +700,29 @@ FileSource - - - + + + Unsupported scheme in URL - + Downloading %1... - + Download cancelled - + Failed to create local file %1 - + File contains no data! @@ -718,75 +730,75 @@ FlexiNoteLayer - - - + + + New Point - + Vertical Scale - + Scale Units - + Scale - + Auto-Align - + Linear - + Log - + MIDI Notes - + In progress - - + + No local points - + %1 (%2, %3 Hz) - + %1 Hz (%2, %3) - + %1 %2 - + Time: %1 Pitch: %2 Duration: %3 @@ -794,7 +806,7 @@ - + Time: %1 Pitch: %2 Duration: %3 @@ -802,85 +814,85 @@ - + Draw Point - + Erase Point - + Drag Point - - - + + + Edit Point - + Relocate Point - + Change Point Value - + Add Point - + Snap Notes - + Merge Notes - + Drag Selection - + Resize Selection - - + + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + Record FlexiNote @@ -1096,19 +1108,19 @@ InteractiveFileFinder - + Select file - + All files (*.*) - + Select a session file @@ -1148,54 +1160,54 @@ - + File does not exist - + <b>File not found</b><p>File "%1" does not exist - + File is not readable - + <b>File is not readable</b><p>File "%1" can not be read - - + + Directory selected - - + + <b>Directory selected</b><p>File "%1" is a directory - + Non-file selected - + <b>Not a file</b><p>Path "%1" is not a file - + File is empty - + <b>File is empty</b><p>File "%1" is empty @@ -1240,6 +1252,13 @@ + + Scalable Vector Graphics files (*.svg) +All files (*.*) + + + + Comma-separated data files (*.csv) Space-separated .lab files (*.lab) Text files (*.txt) @@ -1247,7 +1266,7 @@ - + All supported files (*.sv %1 %2 %3) %4 session files (*.%5) Audio files (%1) @@ -1257,30 +1276,31 @@ - + %1 session files (*.%2) All files (*.*) - - - - - - - + + + + + + + + Select a file to export to - + WAV audio files (*.wav) All files (*.*) - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1290,7 +1310,7 @@ - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1299,7 +1319,7 @@ - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1309,7 +1329,7 @@ - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1318,78 +1338,78 @@ - + Portable Network Graphics files (*.png) All files (*.*) - + Comma-separated data files (*.csv) Text files (*.txt) All files (*.*) - + File exists - + <b>File exists</b><p>The file "%1" already exists. Do you want to overwrite it? - + <b>File not found</b><p>Audio file "%1" could not be opened. Do you want to locate it? - + <b>File not found</b><p>File "%1" could not be opened. Do you want to locate it? - + Failed to open file - + Locate file... - + Use URL... - + Cancel - + Use URL - + Please enter the URL to use for this file: - + Failed to open location - + <b>Failed to open location</b><p>URL "%1" could not be opened @@ -1566,6 +1586,7 @@ + %1.%2 @@ -1575,10 +1596,20 @@ - + Label Points + + + Subdivide Points + + + + + Winnow Points + + Layer @@ -1707,6 +1738,22 @@ + LevelPanToolButton + + + Click to adjust level and pan + + + + + LevelPanWidget + + + Drag vertically to adjust level, horizontally to adjust pan + + + + MIDIFileImportDialog @@ -1827,7 +1874,7 @@ MIDIInput - + Input @@ -1835,7 +1882,7 @@ MP3FileReader - + Decoding %1... @@ -1843,2636 +1890,2787 @@ MainWindow - + Black - + Red - + Blue - - - + + Green - + Purple - + Orange - + White - + Bright Red - + Bright Blue - - - + + Bright Green - + Bright Purple - + Bright Orange - + + + + &Layer + + + + + + &Transform + + + + + &File + + + + + File Toolbar + + + + + File and Session Management + + + + + &New Session + + + + + Ctrl+N + + + + + Ctrl+O + + + + + &Open... + + + + + Open a session file, audio file, or layer + + + + + &Save Session + + + + + Ctrl+S + + + + + Save Session &As... + + + + + Ctrl+Shift+S + + + + + Ctrl+I + + + + + &Export Audio File... + + + + + Export selection as an audio file + + + + + Import Annotation &Layer... + + + + + Ctrl+L + + + + + Import layer data from an existing file + + + + + Export layer data to a file + + + + + Export Image File... + + + + + Export a single pane to an image file + + + + + Open Lo&cation... + + + + + Playback Speed + + + + + Ctrl+Shift+O + + + + + Open or import a file from a remote URL + + + + + Export Audio Data... + + + + + &Preferences... + + + + + Adjust the application preferences + + + + + &Quit + + + + + Ctrl+Q + + + + + &Edit + + + + + Editing + + + + + Cu&t + + + + + Ctrl+X + + + + + Cut the selection from the current layer to the clipboard + + + + + &Copy + + + + + Ctrl+C + + + + + Copy the selection from the current layer to the clipboard + + + + + &Paste + + + + + Ctrl+V + + + + + Paste from the clipboard to the current layer + + + + + Paste at Playback Position + + + + + Ctrl+Shift+V + + + + + Paste from the clipboard to the current layer, placing the first item at the playback position + + + + + + &Delete Selected Items + + + + + Del + + + + + + Delete items in current selection from the current layer + + + + + Selection + + + + + Select &All + + + + + Ctrl+A + + + + + Select the whole duration of the current session + + + + + Select &Visible Range + + + + + Ctrl+Shift+A + + + + + Select the time range corresponding to the current window width + + + + + Select to &Start + + + + + + + + Shift+Left + + + + + Select from the start of the session to the current playback position + + + + + Select to &End + + + + + Shift+Right + + + + + Select from the current playback position to the end of the session + + + + + C&lear Selection + + + + + Esc + + + + + Clear the selection + + + + + Tapping Time Instants + + + + + &Insert Instant at Playback Position + + + + + Enter + + + + + Insert a new time instant at the current playback position, in a new layer if necessary + + + + + ; + + + + + Insert Instants at Selection &Boundaries + + + + + Shift+Enter + + + + + Insert new time instants at the start and end of the current selected regions, in a new layer if necessary + + + + + Insert Item at Selection + + + + + Insert a new note or region item corresponding to the current selection + + + + + Number New Instants with + + + + + Cycle size + + + + + Reset Numbering Counters + + + + + Reset to 1 all the counters used for counter-based labelling + + + + + Set Numbering Counters... + + + + + Set the counters used for counter-based labelling + + + + + Renumber Selected Instants + + + + + Renumber the selected instants using the current labelling scheme + + + + + Panning and Navigation + + + + + &View + + + + + Scroll &Left + + + + + + + + + + + Left + + + + + Scroll the current pane to the left + + + + + Scroll &Right + + + + + Right + + + + + Scroll the current pane to the right + + + + + &Jump Left + + + + + + + Ctrl+Left + + + + + Scroll the current pane a big step to the left + + + + + J&ump Right + + + + + Ctrl+Right + + + + + Scroll the current pane a big step to the right + + + + + Peek Left + + + + + Alt+Left + + + + + Scroll the current pane to the left without moving the playback cursor or other panes + + + + + Peek Right + + + + + Alt+Right + + + + + Scroll the current pane to the right without moving the playback cursor or other panes + + + + + Zoom + + + + + Zoom &In + + + + + Up + + + + + Increase the zoom level + + + + + Zoom &Out + + + + + Down + + + + + Decrease the zoom level + + + + + Restore &Default Zoom + + + + + Restore the zoom level to the default + + + + + Zoom to &Fit + + + + + F + + + + + Zoom to show the whole file + + + + + Display Features + + + + + Show &Centre Line + + + + + ' + + + + + Show or hide the centre line + + + + + Toggle All Time Rulers + + + + + Show &No Overlays + + + + + 0 + + + + + Show &Minimal Overlays + + + + + 9 + + + + + 8 + + + + + Show &All Overlays + + + + + Export audio from selection into a data file + + + + + Export Annotation La&yer... + + + + + Ctrl+Y + + + + + Export SVG File... + + + + + Export a single pane to a scalable SVG image file + + + + + Browse Recorded Audio Folder + + + + + Open the Recorded Audio folder in the system file browser + + + + + Shift+; + + + + + Ctrl+Shift+; + + + + + Ctrl+Shift+Enter + + + + + Ctrl+Shift+Return + + + + + Subdivide Selected Instants... + + + + + Add new instants at regular intervals between the selected instants + + + + + Winnow Selected Instants... + + + + + Remove subdivisions, leaving only every Nth instant + + + + + # + + + + + Show or hide all time rulers + + + + + Hide times, layer names, and scale + + + + + Show times and basic scale + + + + + Show times, layer names, and scale + + + + + Show &Zoom Wheels + + + - - &Layer - - - - - - &Transform - - - - - &File - - - - - File Toolbar - - - - - File and Session Management - - - - - &New Session - - - - - Ctrl+N - - - - - Ctrl+O - - - - - &Open... - - - - - Open a session file, audio file, or layer - - - - - &Save Session - - - - - Ctrl+S - - - - - Save Session &As... - - - - - Ctrl+Shift+S - - - - - Ctrl+I - - - - - &Export Audio File... - - - - - Export selection as an audio file - - - - - Import Annotation &Layer... - - - - - Ctrl+L - - - - - Import layer data from an existing file - - - - - Export layer data to a file - - - - - Export Image File... - - - - - Export a single pane to an image file - - - - - Open Lo&cation... - - - - - Playback Speed - - - - - Ctrl+Shift+O - - - - - Open or import a file from a remote URL - - - - - Export Audio Data... - - - - - &Preferences... - - - - - Adjust the application preferences - - - - - &Quit - - - - - Ctrl+Q - - - - - &Edit - - - - - Editing - - - - - Cu&t - - - - - Ctrl+X - - - - - Cut the selection from the current layer to the clipboard - - - - - &Copy - - - - - Ctrl+C - - - - - Copy the selection from the current layer to the clipboard - - - - - &Paste - - - - - Ctrl+V - - - - - Paste from the clipboard to the current layer - - - - - Paste at Playback Position - - - - - Ctrl+Shift+V - - - - - Paste from the clipboard to the current layer, placing the first item at the playback position - - - - + Z + + + + + Show thumbwheels for zooming horizontally and vertically + + + + + Show Property Bo&xes + + + + + X + + + + + Show the layer property boxes at the side of the main window + + + + + Show Status &Bar + + + + + Show context help information in the status bar at the bottom of the window + + + + + Show La&yer Summary + + + + + Y + + + + + Open a window displaying the hierarchy of panes and layers in this session + + + + + Show Acti&vity Log + + + + + Open a window listing interactions and other events + + + + + Show &Unit Converter + + + + + Open a window of pitch and timing conversion utilities + + + + + Go Full-Screen + + + + + F11 + + + + + Expand the pane area to the whole screen + + + + + &Pane + + + + + Managing Panes and Layers + + + + + Add &New Pane + + + + + N + + + + + Add a new pane containing only a time ruler + + + + + Add New %1 Layer + + + + + Add a new empty layer of type %1 + + + + + T + + + + + Add &Waveform + + + + + W + + + + + Add a new pane showing a waveform view + + + + + Shift+W + + + + + Add a new layer showing a waveform view + + + + + Add Spectro&gram + + + + + G + + + + + Add a new pane showing a spectrogram + + + + + Shift+G + + + + + Add a new layer showing a spectrogram + + + + + Add &Melodic Range Spectrogram + + + + + M + + + + + Add a new pane showing a spectrogram set up for an overview of note pitches + + + + + Shift+M + + + + + Add a new layer showing a spectrogram set up for an overview of note pitches + + + + + Add Pea&k Frequency Spectrogram + + + + + K + + + + + Add a new pane showing a spectrogram set up for tracking frequencies + + + + + Shift+K + + + + + Add a new layer showing a spectrogram set up for tracking frequencies + + + + + Add Spectr&um + + + + + U + + + + + Add a new pane showing a frequency spectrum + + + + + Shift+U + + + + + Add a new layer showing a frequency spectrum + + + + + &All Channels Mixed + + + + + &All Channels + + + + + Channel &%1 + + + + + + %1: %2 + + + + + Switch to Previous Pane + + + + + [ + + + + + Make the next pane up in the pane stack current + + + + + Switch to Next Pane + + + + + ] + + + + + Make the next pane down in the pane stack current + + + + + &Delete Pane + + + + + Ctrl+Shift+D + + + + + Delete the currently active pane + + + + + Add &Time Ruler + + + + + Add a new layer showing a time ruler + + + + + Add &Existing Layer + + + + + Add S&lice of Layer + + + + + Switch to Previous Layer + + + + + { + + + + + Make the previous layer in the pane current + + + + + Switch to Next Layer + + + + + } + + + + + Make the next layer in the pane current + + + + + &Rename Layer... + + + + + R + + + + + Rename the currently active layer + + + + + Edit Layer Data + + + + + E + + + + + Edit the currently active layer as a data grid + + + + + &Delete Layer + + + + + Ctrl+D + + + + + Delete the currently active layer + + + + + &Recent Transforms + + + + + %1 by Category + + + + + + Unclassified + + + + + %1 by Plugin Name + + + + + %1 by Maker + + + + + + Unknown + + + + + + [\(<].*$ + + + + + + %1... + + + + + Find a Transform... + + + + + Search for a transform from the installed plugins, by name or description + + + + + Ctrl+M + + + + + &Help + + + + + Help + + + + + &Help Reference + + + + + F1 + + + + + &Key and Mouse Reference + + + + + F2 + + + + + What's &New? + + + + + Show changes in this release of %1 + + + + + Ctrl+R + + + + + Re-open + + + + + Re-open the current or most recently opened file + + + + + Standard Waveform + + + + + Choose Default Template... + + + + + Ctrl+T + + + + + Repeat Transform + + + + + Re-select the most recently run transform + + + + + Playback and Transport Controls + + + + + Play&back + + + + + Playback + + + + + Playback Toolbar + + + + + Rewind to Start + + + + + Home + + + + + Rewind to the start + + + + + + + Rewind + + + + + PgUp + + + + + Rewind to the previous time instant or time ruler notch + + + + + Rewind to Similar Point + + + + + Shift+PgUp + + + + + Rewind to the previous similarly valued time instant + + + + + Play / Pause + + + + + Space + This text is a shortcut label referring to the space-bar on the keyboard. It probably should not be translated, and certainly should not be translated as if referring to an empty void or to the extra-terrestrial universe. + + + + + Start or stop playback from the current position + + + + + + Fast Forward + + + + + PgDown + + + + + Fast-forward to the next time instant or time ruler notch + + + + + Fast Forward to Similar Point + + + + + Shift+PgDown + + + + + Fast-forward to the next similarly valued time instant + + + + + Fast Forward to End + + + + + End + + + + + Fast-forward to the end + + + + + Record + + + + + Ctrl+Space + + + + + Record a new audio file + + + + + Play Mode Toolbar + + + + + Constrain Playback to Selection + + + + + s + + + + + Constrain playback to the selected regions + + + + + Loop Playback + + + + + l + + + + + Loop playback + + + + + Solo Current Pane + + + + + o + + + + + Solo the current pane during playback + + + + + Align File Timelines + + + + + Treat multiple audio files as versions of the same work, and align their timelines + + + + + Speed Up + + + + + Ctrl+PgUp + + + + + Time-stretch playback to speed it up without changing pitch + + + + + Slow Down + + + + + Ctrl+PgDown + + + + + Time-stretch playback to slow it down without changing pitch + + + + + Restore Normal Speed + + + + + Ctrl+Home + + + + + Restore non-time-stretched playback + + + + + Edit Toolbar + + + + + + + + + + Tool Selection + + + + + Export the whole pane + + + + + Export the visible area only + + + + + Which region of the current pane do you want to export as a scalable SVG image? + + + + + Failed to save SVG file + + + + + Failed to save SVG file %1 + + + + + Failed to query transform attributes + + + + + <b>Failed to query transform attributes</b><p>Plugin or server error: %1</p> + + + + + Multiplexed audio + + + + + Transform failed + + + + + <b>Failed to run transform</b><p>Plugin or server error: %1</p> + + + + + Playback speed: %1% (%2x slower) + + + + + Playback speed: %1% (%2x faster) + + + + + Subdivide instants + + + + + Number of subdivisions: + + + + + Winnow instants + + + + + Remove all instants apart from multiples of: + + + + + <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 + + + + + <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. + + + + + <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment:<p>%1 + + + + + Adjust the master playback level and pan + + + + + With Qt v%1 &copy; The Qt Company + + + + + <br>With Rubber Band Library v%1 &copy; Particular Programs Ltd + + + + + <br>With Rubber Band Library &copy; Particular Programs Ltd + + + + + <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam and QMUL + + + + + <br>With Piper Vamp protocol bridge &copy; QMUL + + + + + <br>With Dataquay Qt/RDF library &copy; Particular Programs Ltd + + + + + <br>With Cap'n Proto serialisation &copy; Sandstorm Development Group + + + + + Russian UI translation contributed by Alexandre Prokoudine. + + + + + Czech UI translation contributed by Pavel Fric. + + + + + <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> + + + + + Tools Toolbar + + + + + + + Navigate + + + + + 1 + + + + + + Select + + + + + 2 + + + + + Select ranges + + + + + + + Edit + + + + + Navigate Tool Mouse Actions + + + + + Click left button and drag to move around + + + + + + Zoom to Area + + + + + + Shift-click left button and drag to zoom to a rectangular area + + + + + Relocate + + + + + + + + Double-Click Left + + + - &Delete Selected Items - - - - - Del - - - - - - Delete items in current selection from the current layer - - - - - Selection - - - - - Select &All - - - - - Ctrl+A - - - - - Select the whole duration of the current session - - - - - Select &Visible Range - - - - - Ctrl+Shift+A - - - - - Select the time range corresponding to the current window width - - - - - Select to &Start - - - - - - - - Shift+Left - - - - - Select from the start of the session to the current playback position - - - - - Select to &End - - - - - Shift+Right - - - - - Select from the current playback position to the end of the session - - - - - C&lear Selection - - - - - Esc - - - - - Clear the selection - - - - - Tapping Time Instants - - - - - &Insert Instant at Playback Position - - - - - Enter - - - - - Insert a new time instant at the current playback position, in a new layer if necessary - - - - - ; - - - - - Insert Instants at Selection &Boundaries - - - - - Shift+Enter - - - - - Insert new time instants at the start and end of the current selected regions, in a new layer if necessary - - - - - Insert Item at Selection - - - - - Insert a new note or region item corresponding to the current selection - - - - - Number New Instants with - - - - - Cycle size - - - - - Reset Numbering Counters - - - - - Reset to 1 all the counters used for counter-based labelling - - - - - Set Numbering Counters... - - - - - Set the counters used for counter-based labelling - - - - - Renumber Selected Instants - - - - - Renumber the selected instants using the current labelling scheme - - - - - Panning and Navigation - - - - - &View - - - - - Scroll &Left - - - - - - - - - - - Left - - - - - Scroll the current pane to the left - - - - - Scroll &Right - - - - - Right - - - - - Scroll the current pane to the right - - - - - &Jump Left - - - - - - - Ctrl+Left - - - - - Scroll the current pane a big step to the left - - - - - J&ump Right - - - - - Ctrl+Right - - - - - Scroll the current pane a big step to the right - - - - - Peek Left - - - - - Alt+Left - - - - - Scroll the current pane to the left without moving the playback cursor or other panes - - - - - Peek Right - - - - - Alt+Right - - - - - Scroll the current pane to the right without moving the playback cursor or other panes - - - - - Zoom - - - - - Zoom &In - - - - - Up - - - - - Increase the zoom level - - - - - Zoom &Out - - - - - Down - - - - - Decrease the zoom level - - - - - Restore &Default Zoom - - - - - Restore the zoom level to the default - - - - - Zoom to &Fit - - - - - F - - - - - Zoom to show the whole file - - - - - Display Features - - - - - Show &Centre Line - - - - - ' - - - - - Show or hide the centre line - - - - - Toggle All Time Rulers - - - - - Show &No Overlays - - - - - 0 - - - - - Show &Minimal Overlays - - - - - 9 - - - - - 8 - - - - - Show &All Overlays - - - - - Export audio from selection into a data file - - - - - Export Annotation La&yer... - - - - - Ctrl+Y - - - - - Browse Recorded Audio Folder - - - - - Open the Recorded Audio folder in the system file browser - - - - - Ctrl+Shift+Return - - - - - # - - - - - Show or hide all time rulers - - - - - Hide times, layer names, and scale - - - - - Show times and basic scale - - - - - Show times, layer names, and scale - - - - - Show &Zoom Wheels - - - - - Z - - - - - Show thumbwheels for zooming horizontally and vertically - - - - - Show Property Bo&xes - - - - - X - - - - - Show the layer property boxes at the side of the main window - - - - - Show Status &Bar - - - - - Show context help information in the status bar at the bottom of the window - - - - - Show La&yer Summary - - - - - Y - - - - - Open a window displaying the hierarchy of panes and layers in this session - - - - - Show Acti&vity Log - - - - - Open a window listing interactions and other events - - - - - Show &Unit Converter - - - - - Open a window of pitch and timing conversion utilities - - - - - Go Full-Screen - - - - - F11 - - - - - Expand the pane area to the whole screen - - - - - &Pane - - - - - Managing Panes and Layers - - - - - Add &New Pane - - - - - N - - - - - Add a new pane containing only a time ruler - - - - - Add New %1 Layer - - - - - Add a new empty layer of type %1 - - - - - T - - - - - Add &Waveform - - - - - W - - - - - Add a new pane showing a waveform view - - - - - Shift+W - - - - - Add a new layer showing a waveform view - - - - - Add Spectro&gram - - - - - G - - - - - Add a new pane showing a spectrogram - - - - - Shift+G - - - - - Add a new layer showing a spectrogram - - - - - Add &Melodic Range Spectrogram - - - - - M - - - - - Add a new pane showing a spectrogram set up for an overview of note pitches - - - - - Shift+M - - - - - Add a new layer showing a spectrogram set up for an overview of note pitches - - - - - Add Pea&k Frequency Spectrogram - - - - - K - - - - - Add a new pane showing a spectrogram set up for tracking frequencies - - - - - Shift+K - - - - - Add a new layer showing a spectrogram set up for tracking frequencies - - - - - Add Spectr&um - - - - - U - - - - - Add a new pane showing a frequency spectrum - - - - - Shift+U - - - - - Add a new layer showing a frequency spectrum - - - - - &All Channels Mixed - - - - - &All Channels - - - - - Channel &%1 - - - - - - %1: %2 - - - - - Switch to Previous Pane - - - - - [ - - - - - Make the next pane up in the pane stack current - - - - - Switch to Next Pane - - - - - ] - - - - - Make the next pane down in the pane stack current - - - - - &Delete Pane - - - - - Ctrl+Shift+D - - - - - Delete the currently active pane - - - - - Add &Time Ruler - - - - - Add a new layer showing a time ruler - - - - - Add &Existing Layer - - - - - Add S&lice of Layer - - - - - Switch to Previous Layer - - - - - { - - - - - Make the previous layer in the pane current - - - - - Switch to Next Layer - - - - - } - - - - - Make the next layer in the pane current - - - - - &Rename Layer... - - - - - R - - - - - Rename the currently active layer - - - - - Edit Layer Data - - - - - E - - - - - Edit the currently active layer as a data grid - - - - - &Delete Layer - - - - - Ctrl+D - - - - - Delete the currently active layer - - - - - &Recent Transforms - - - - - %1 by Category - - - - - - Unclassified - - - - - %1 by Plugin Name - - - - - %1 by Maker - - - - - - Unknown - - - - - - [\(<].*$ - - - - - - %1... - - - - - Find a Transform... - - - - - Search for a transform from the installed plugins, by name or description - - - - - Ctrl+M - - - - - &Help - - - - - Help - - - - - &Help Reference - - - - - F1 - - - - - &Key and Mouse Reference - - - - - F2 - - - - - Ctrl+R - - - - - Re-open - - - - - Re-open the current or most recently opened file - - - - - Standard Waveform - - - - - Choose Default Template... - - - - - Ctrl+T - - - - - Repeat Transform - - - - - Re-select the most recently run transform - - - - - Playback and Transport Controls - - - - - Play&back - - - - - Playback - - - - - Playback Toolbar - - - - - Rewind to Start - - - - - Home - - - - - Rewind to the start - - - - - - - Rewind - - - - - PgUp - - - - - Rewind to the previous time instant or time ruler notch - - - - - Rewind to Similar Point - - - - - Shift+PgUp - - - - - Rewind to the previous similarly valued time instant - - - - - Play / Pause - - - - - Space - - - - - Start or stop playback from the current position - - - - - - Fast Forward - - - - - PgDown - - - - - Fast-forward to the next time instant or time ruler notch - - - - - Fast Forward to Similar Point - - - - - Shift+PgDown - - - - - Fast-forward to the next similarly valued time instant - - - - - Fast Forward to End - - - - - End - - - - - Fast-forward to the end - - - - - Record - - - - - Ctrl+Space - - - - - Record a new audio file - - - - - Play Mode Toolbar - - - - - Constrain Playback to Selection - - - - - s - - - - - Constrain playback to the selected regions - - - - - Loop Playback - - - - - l - - - - - Loop playback - - - - - Solo Current Pane - - - - - o - - - - - Solo the current pane during playback - - - - - Align File Timelines - - - - - Treat multiple audio files as versions of the same work, and align their timelines - - - - - Speed Up - - - - - Ctrl+PgUp - - - - - Time-stretch playback to speed it up without changing pitch - - - - - Slow Down - - - - - Ctrl+PgDown - - - - - Time-stretch playback to slow it down without changing pitch - - - - - Restore Normal Speed - - - - - Ctrl+Home - - - - - Restore non-time-stretched playback - - - - - Edit Toolbar - - - - - - - - - - Tool Selection - - - - - Playback speed: %1% (%2x slower) - - - - - Playback speed: %1% (%2x faster) - - - - - <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 - - - - - <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. - - - - - <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> - - - - - Tools Toolbar - - - - - - - Navigate - - - - - 1 - - - - - - Select - - - - - 2 - - - - - Select ranges - - - - - - - Edit - - - - - Navigate Tool Mouse Actions - - - - - Click left button and drag to move around - - - - - - Zoom to Area - - - - - - Shift-click left button and drag to zoom to a rectangular area - - - - - Relocate - - - - - - - - Double-Click Left - - - - Double-click left button to jump to clicked location - - + + Double-click left button on an item to edit it - + Select Tool Mouse Actions - + Click left button and drag to select region; drag region edge to resize - - + + Multi Select - + Cmd-click left button and drag to select an additional region - + Ctrl-click left button and drag to select an additional region - + Fine Select - + Shift-click left button and drag to select without snapping to items or grid - + 3 - + Edit items in layer - + Edit Tool Mouse Actions - + Move - + Click left button on an item or selected region and drag to move - - + + Draw - + 4 - + Draw new items in layer - + Draw Tool Mouse Actions - + Click left button and drag to create new item - - + + Erase - + 5 - + Erase items from layer - + Erase Tool Mouse Actions - + Click left button on an item to remove it from the layer - + Measure - + 6 - + Make measurements in layer - + Measure Tool Mouse Actions - + Measure Area - + Click left button and drag to measure a rectangular area - + Measure Item - + Click left button and drag to measure extents of an item or shape - + &Delete Current Measurement - + Delete the measurement currently under the mouse pointer - + Fast Forward to Next Instant - + Fast forward to the next time instant in the current layer - + Rewind to Previous Instant - + Rewind to the previous time instant in the current layer - + Fast Forward to Next Point - + Fast forward to the next point in the current layer - + Rewind to Previous Point - + Rewind to the previous point in the current layer - + Fast forward - + No audio file loaded. - + %1Hz (resampling to %2Hz) - - - - - - - + + + + + + + Failed to open file - - - + + + <b>File open failed</b><p>Audio file "%1" could not be opened - + 1. %2 - + %1. %2 - + Select audio file to export - + Which audio file do you want to export from? - + Export the selected region only - + Export the whole audio file - - - + + + + Select region to export - + Which region from the original audio file do you want to export? - + Export the selected regions into separate files - + Multiple regions of the original audio file are selected. What do you want to export? - + Fragment file %1 already exists, aborting - + Export multiple audio files - + Export audio to "%1" - - + + Failed to write file - + <b>File open failed</b><p>Layer file %1 could not be opened. - - - - - + + + + + <b>Audio required</b><p>Unable to load layer data from "%1" without an audio file.<br>Please load at least one audio file before importing annotations. - + Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values) - + Enter template name - + Please enter a name for the saved template: - + Set as default template for future audio files - + Template file exists - + <b>Template file exists</b><p>The template "%1" already exists.<br>Overwrite it? - + http://www.sonicvisualiser.org/doc/reference/%1/en/ - + + What's New + + + + + <h3>What's New in %1</h3> + + + + + <b>Note:</b> A newer version of Sonic Visualiser is available.<br>(Version %1 is available; you are using version %2) + + + + + %1 : %2 configuration, %3-bit build + + + + <br>With Serd and Sord RDF parser and store &copy; David Robillard - - <br>With Dataquay Qt/RDF library &copy; Chris Cannam - - - - + + About %1 + + + + Newer version available - + Failed to open file %1 for writing - + Abandon the current %1 session and start a new one - + &Import More Audio... - + Import an extra audio file into a new pane - + Replace &Main Audio... - + Replace the main audio file of the session with a different file - + Open &Recent - + Save the current session into a %1 session file - + Save the current session into a new %1 session file - + Apply Session Template - + Export Session as Template... - + Manage Exported Templates - + Exit %1 - + Open the %1 reference manual - + Open a window showing the keystrokes you can use in %1 - + %1 on the &Web - + Open the %1 website - + &About %1 - + Show information about %1 - + Export the selected regions into a single file - + Export the whole file - + Can't export non-note layers to MIDI - + Export layer to "%1" - + Export the whole pane (%1x%2 pixels) - + Export the visible area only (%1x%2 pixels) - + Export the selection extent (%1x%2 pixels) - + + Export the selection extent - + Which region of the current pane do you want to export as an image? - + Note: the whole pane is too wide to be exported as a single image. - + Failed to save image file - + Failed to save image file %1 - + <b>File open failed</b><p>File "%1" could not be opened - + Open Location - + Please enter the URL of the location to open: - - - - + + + + Failed to open location - + <b>Open failed</b><p>URL "%1" could not be opened - + <b>Open failed</b><p>File or URL "%1" could not be opened - - + + Failed to open dropped URL - + <b>Open failed</b><p>Dropped URL "%1" could not be opened - + Export image to "%1" - + Session modified - + <b>Session modified</b><p>The current session has been modified.<br>Do you want to save it? - + Close the current session and create a new one - + Add this data to the current session - + Select target for import - + <b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data? - - + + Failed to save file - - + + <b>Save failed</b><p>Session file "%1" could not be saved. - + Save session as "%1" - + Multiplex all of the above - + Rename Layer - + New name for this layer: - + Playback speed: Normal - + Selection: %1 to %2 (duration %3) - + Visible: %1 to %2 (duration %3) - + Sample rate mismatch - + <b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match the current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour. - - + + Audio processing overload - + <b>Overloaded</b><p>Audio effects plugin auditioning has been disabled due to a processing overload. - + <b>Overloaded</b><p>Audio playback speed processing has been reduced to a single channel, due to a processing overload. - + Problems loading plugins - + Add Point - + Reset Counters - - + + Failed to generate layer - - + + Warning - - + + Failed to regenerate layer - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed:<p>%3 - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed.<p>No error information is available. - + <b>Warning when regenerating layer</b><p>When regenerating the derived layer "%1" using new data model as input:<p>%2 - + Failed to calculate alignment - - <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment using transform "%1":<p>%2 - - - - - Adjust the master playback level - - - - + Adjust the master playback speed - + http://www.sonicvisualiser.org/ - + Release %1 : Revision %2 - + Release %1 - + Unreleased : Revision %1 - + <h3>About Sonic Visualiser</h3> - + <p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.<br><a href="http://www.sonicvisualiser.org/">http://www.sonicvisualiser.org/</a></p> - - <p><small>%1 : %2 configuration</small></p> - - - - + Debug - + Release - - With Qt v%1 &copy; Nokia Corporation - - - - + <br>With JACK audio output library v%1 &copy; Paul Davis and Jack O'Quin - + <br>With JACK audio output library &copy; Paul Davis and Jack O'Quin - + <br>With PortAudio audio output library &copy; Ross Bencina and Phil Burk - + <br>With PulseAudio audio output library v%1 &copy; Lennart Poettering and Pierre Ossman - + <br>With PulseAudio audio output library &copy; Lennart Poettering and Pierre Ossman - + <br>With Ogg file decoder (oggz v%1, fishsound v%2) &copy; CSIRO Australia - + <br>With Ogg file decoder &copy; CSIRO Australia - + <br>With MAD mp3 decoder v%1 &copy; Underbit Technologies Inc - + <br>With MAD mp3 decoder &copy; Underbit Technologies Inc - + <br>With libsamplerate v%1 &copy; Erik de Castro Lopo - + <br>With libsamplerate &copy; Erik de Castro Lopo - + <br>With libsndfile v%1 &copy; Erik de Castro Lopo - + <br>With libsndfile &copy; Erik de Castro Lopo - + <br>With FFTW3 v%1 &copy; Matteo Frigo and MIT - + <br>With FFTW3 &copy; Matteo Frigo and MIT - - <br>With Rubber Band v%1 &copy; Chris Cannam - - - - - <br>With Rubber Band &copy; Chris Cannam - - - - - <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam - - - - + <br>With LADSPA plugin support (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld - + <br>With DSSI plugin support (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton - + <br>With Redland RDF datastore v%1 &copy; Dave Beckett and the University of Bristol - + <br>With Redland RDF datastore &copy; Dave Beckett and the University of Bristol - + <br>With RtMidi &copy; Gary P. Scavone - + <br>With liblo Lite OSC library v%1 &copy; Steve Harris - + <br>With liblo Lite OSC library &copy; Steve Harris - + </small><p><small>The OSC URL for this instance is: "%1" - - With - - - - - Using - - - - - About Sonic Visualiser - - - - + Add %1 Pane @@ -4480,215 +4678,301 @@ MainWindowBase - + %1 (modified) - + (modified) - + Cut - + Paste - - - - - + + + + + Add Point - + Add Point at %1 s - + Add Item at %1 s - + Opening file or URL... - + Select target for import - - - - + + + + %1: %2 - - + + %1: %2 [%3] - - + + Import "%1" - + Opening playlist... - - + + Importing from RDF... - + Opening session... - + + Not enough disc space + + + + + <b>Not enough disc space</b><p>There doesn't appear to be enough spare disc space to accommodate any necessary temporary files.</p><p>Please clear some space and try again.</p> + + + + + Not enough memory + + + + + <b>Not enough memory</b><p>There doesn't appear to be enough memory to accommodate any necessary temporary data.</p> + + + + Close the current session and start a new one - + Replace the main audio file in this session - + Add the audio file to this session - + <b>Select a target for import</b><p>You already have an audio file loaded.<br>What would you like to do with the new audio file? - + Import audio file "%1" - + Import layer XML file "%1" - + Import MIDI file "%1" - - + + SV XML file read error: %1 - + Import session file "%1" - + + Incomplete session loaded + + + + + Some of the audio content referred to by the original session file could not be loaded. +If you save this session, it will be saved without any reference to that audio, and information may be lost. + + + + Open session template "%1" - - + + Failed to import RDF - + <b>Failed to import RDF</b><p>Importing data from RDF document at "%1" failed: %2</p> - + <b>Failed to import RDF</b><p>No suitable data models found for import from RDF document at "%1"</p> - + Import RDF document "%1" - + + <b>No audio available</b><p>Could not open an audio device.</p> + + + + + <b>No audio available</b><p>Could not open audio device: %1</p> + + + + + <p>Automatic audio device detection failed. Audio playback and recording will not be available during this session.</p> + + + + + <p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1").</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1"): %2.</p> + + + + + <p>Audio playback and recording will not be available during this session.</p> + + + + + <p>Audio playback will not be available during this session.</p> + + + + Couldn't open audio device - - <b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> - - - - + Recording: %1 - - - + + + Failed to write file - - - + + + <b>Save failed</b><p>Failed to write to file "%1": %2 - + + No record device available + + + + + <b>No record device available</b><p>Failed to find or open an audio device for recording. Only playback will be available.</p> + + + + + Recording failed + + + + + <b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p> + + + + Import Recorded Audio - + Add Pane - + Remove Pane - - + + Delete Pane - + Playing: %1 of %2 (%3 remaining) @@ -4802,7 +5086,7 @@ - + %1: %2 @@ -4810,17 +5094,32 @@ NetworkPermissionTester - + Welcome to Sonic Visualiser - - <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary, University of London, Sonic Visualiser is provided free as open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like to make networking connections and open a network port.</p><p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control, where configured; and</li><li> Tell you when updates are available.</li></ul><p>No personal information will be sent, no tracking is carried out, and all requests happen in the background without interrupting your work.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful. But if you do not wish to do so, please un-check the box below.<br></p> - - - - + + <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary University of London, Sonic Visualiser is open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like permission to use the network.</p> + + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control; and</li><li> Tell you when updates are available.</li></ul> + + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins; and</li><li> Tell you when updates are available.</li></ul> + + + + + <p><b>No personal information will be sent, no tracking is carried out, and no individual information will be shared with anyone else.</b> We will however make aggregate counts of distinct requests for usage reporting.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful to you and supports the public funding of this work. But if you do not wish to allow it, please un-check the box below.<br></p> + + + + Allow this @@ -4828,75 +5127,75 @@ NoteLayer - - + + New Point - + Vertical Scale - + Scale Units - + Scale - + Auto-Align - + Linear - + Log - + MIDI Notes - + In progress - - + + No local points - + %1 (%2, %3 Hz) - + %1 Hz (%2, %3) - + %1 %2 - + Time: %1 Pitch: %2 Duration: %3 @@ -4904,7 +5203,7 @@ - + Time: %1 Pitch: %2 Duration: %3 @@ -4912,68 +5211,68 @@ - + Draw Point - + Erase Point - + Drag Point - - + + Edit Point - + Relocate Point - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + Record Note @@ -5029,7 +5328,7 @@ OggVorbisFileReader - + Decoding %1... @@ -5042,7 +5341,7 @@ - + Click and drag to navigate; double-click to jump @@ -5050,300 +5349,300 @@ Pane - + Horizontal Zoom - + Vertical Zoom - + Reset zoom to default - + Some lengthy prefix: - + Reference - - + + Unaligned - + Aligning: %1% - + Aligned - + %1 - %2 - - + + +%1 - + (R) - + (X) - + %1 / %2Hz%3 - - + + Zoom - + Zoom In - + Wheel Up - + Zoom Out - + Wheel Down - + General Pane Mouse Actions - + Wheel - + Zoom in or out in time axis - + Scroll - + Ctrl+Wheel - + Scroll rapidly left or right in time axis - + Zoom Vertically - + Shift+Wheel - + Zoom in or out in the vertical axis - + Scroll Vertically - + Alt+Wheel - + Scroll up or down in the vertical axis - + Navigate - + Middle - + Click middle button and drag to navigate with any tool - + Relocate - + Double-Click Middle - + Double-click middle button to relocate with any tool - + Menu - + Right - + Show pane context menu - + Enter new range - + New vertical display range, from %1 to %2 %4: - + Drag Selection - + Resize Selection - + Click and drag to navigate - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Cmd for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Cmd for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate - + Click and drag to move the selection boundary - + Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate - + Click and drag to select a range; middle-click and drag to navigate - + Click to add a new item in the active layer - + Click to erase an item from the active layer - + Click and drag an item in the active layer to move it; hold Shift to override initial resistance - + Click and drag to move all items in the selected range - + Click and drag to adjust the visible range of the vertical scale - + Click and drag to adjust the vertical zoom level - + Click and drag to adjust the horizontal zoom level - + Reset horizontal and vertical zoom levels to their defaults @@ -5392,382 +5691,534 @@ PluginParameterDialog - - + + Plugin Parameters - + Name: - + Version: - + Maker: + + Copyright: + + + - Copyright: - - - - Output: - + Input Material - + Restrict to selection extents - + Channels - + Processing - - + + Advanced >> - + Channel mismatch - + This plugin requires at least %1 input channels, but only %2 %3 available. The plugin probably will not work correctly. - + are - + is - + This plugin accepts no more than %1 input channels, but %2 are available. Only the first %3 will be used. - + This plugin only has a single channel input, but the source has %1 channels. - + Use mean of source channels - + Use channel %1 only - + Window size: - + Audio frames per block: - + Window increment: - + Window shape: - + Advanced << + PluginPathConfigurator + + + Move the selected location later in the list + + + + + Move the selected location earlier in the list + + + + + Add a new location to the list + + + + + Remove the selected location from the list + + + + + Reset to Default + + + + + Reset the list for this plugin type to its default + + + + + Review plugins... + + + + + Plugin locations for plugin type: + + + + + Vamp + + + + + LADSPA + + + + + DSSI + + + + + Vamp (32-bit) + + + + + LADSPA (32-bit) + + + + + DSSI (32-bit) + + + + + (Variable is currently unset) + + + + + (Current value begins: "%1 ...") + + + + + (Currently set to: "%1") + + + + + Allow the %1 environment variable to take priority over this +%2 + + + + + Choose directory to add + + + + + PluginReviewDialog + + + Plugins Loaded + + + + + Type + + + + + Library + + + + + Identifier + + + + + Found in + + + + + Name + + + + + Vamp + + + + + DSSI + + + + + LADSPA + + + + Preferences - + Spectrogram y-axis interpolation: - + Spectrogram x-axis interpolation: - + Frequency of concert A - + Property box layout - + Spectral analysis window shape - + Playback resampler type - + Normalise audio signal when reading from audio file - + Omit temporaries from Recent Files menu - + Resample mismatching files on import - + + Load mp3 files in gapless mode + + + + Single fixed sample rate to resample all files to - + Location for cache file directory - + Background colour preference - + Time display precision - + Use hours:minutes:seconds format - + Label middle C as - + Font size for text overlays - + Show splash screen on startup - + Show boxes for all panes - + Show box for current pane only - + Rectangular - + Triangular - + Hamming - + Hann - + Blackman - + Gaussian - + Parzen - + Nuttall - + Blackman-Harris - + Fastest - + Standard - + Highest quality - + + + None + + + + + + Linear interpolation + + + - None - - - - + 4 x Oversampling + + + - Linear interpolation - - - - - 4 x Oversampling - - - - 4 x Oversampling with interpolation - + Follow desktop theme - + Dark background - + Light background - + Standard (to millisecond) - + High resolution (to microsecond) - + 24 FPS - + 25 FPS - + 30 FPS - + 50 FPS - + 60 FPS - + C0 - middle of octave scale - + C3 - common MIDI sequencer convention - + C4 - ASA American standard - + C5 - used in Cakewalk and others - + Preferences @@ -5775,155 +6226,212 @@ PreferencesDialog - + Sonic Visualiser: Application Preferences - + Apply - + + Green + + + + + + + (auto) + + + + <home directory> - + Follow system locale - + Russian - + British English - + American English - + Czech - - - - - - - - + + + + + + + + + + + + + + + %1: + + + - - - - - - %1: - - - - + Overview waveform colour: + + + + + Run Vamp plugins in separate process: + + + + + Default session template when loading audio files: + + + + + (Use "%1" in the File menu to add to these.) + + + + + Export Session as Template... + + + + + Audio service: + + + + + Audio playback device: + + + + + Audio record device: + + + + + A&udio I/O + + + + + &Plugins + + + + User interface language - + Allow network usage - - &General - - - - + Draw layers at Retina resolution: - + Default spectrogram colour: - + Default melodic spectrogram colour: - + Default colour 3D plot colour: - + &Appearance - + Anal&ysis - - Default session template for audio files: - - - - + Standard Waveform - + Session &Template - + + &Other + + + + OK - + Cancel - + Select a directory to create cache subdirectory in - + Preferences - + <b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p> - + Preferences Changed - + Some preferences have been changed but not applied. Apply them before closing? @@ -5932,7 +6440,7 @@ ProgressDialog - + Cancel @@ -5940,83 +6448,57 @@ PropertyBox - + Show - - Play - - - - - Playback Gain - - - - - dB - - - - - - Playback Pan / Balance - - - - - Add New Colour... - - - - - Name New Colour - - - - - Enter a name for the new colour: - - - - - Prefer black background for this colour - - - - + + Click to toggle playback + + + + Set playback clip: - + + Adjust playback level and pan of %1 + + + + + Change sound used for playback (currently "%1") + + + + (current value: %1%2) - + (current value: %1) - + Toggle Visibility of %1 - + Toggle Playback of %1 - + Toggle %1 property of %2 - + Adjust %1 property of %2%3 @@ -6054,7 +6536,7 @@ - + Set %1 Property @@ -6075,7 +6557,7 @@ QApplication - + Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation. @@ -6091,7 +6573,7 @@ - + Sonic Visualiser @@ -6126,13 +6608,13 @@ QFile - + File "%1" does not exist - + Failed to open file "%1" @@ -6147,18 +6629,18 @@ QMessageBox - - + + Failed to open file - + File or URL "%1" could not be opened - + <b>Audio required</b><p>Please load at least one audio file before importing annotation data @@ -6166,37 +6648,114 @@ QObject - - <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> - - - - - - Failed to load library - - - - - Failed to query plugins from library after loading - - - - - Unknown failure - - - - - Success: internal error? - - - - - QuickTimeFileReader - - - Decoding %1... + + External plugin host executable does not appear to be installed + + + + + Could not start external plugin host + + + + + External plugin host exited unexpectedly while listing plugins + + + + + External plugin host invocation failed: %1 + + + + + <b>Failed to scan for plugins</b><p>Failed to scan for plugins at startup. Possibly the plugin checker program was not correctly installed alongside %1?</p> + + + + + <b>Did not scan for plugins</b><p>Apparently no scan for plugins was attempted (internal error?)</p> + + + + + <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> + + + + + <p>These plugins may be incompatible with the system, and will be ignored during this run of %1.</p> + + + + + + <unknown> + + + + + Green + + + + + White on Black + + + + + Black on White + + + + + Cherry + + + + + Wasp + + + + + Ice + + + + + Sunset + + + + + Fruit Salad + + + + + Banded + + + + + Highlight + + + + + Printer + + + + + High Gain + + + + + Exporting audio data... @@ -6245,79 +6804,79 @@ RegionLayer - + New Region - + Vertical Scale - + Scale Units - + Plot Type - + Scale - + Bars - + Segmentation - + Auto-Align - + Equal Spaced - + Linear - + Log - + In progress - - + + No local points - + %1 %2 - + Time: %1 Value: %2 Duration: %3 @@ -6325,7 +6884,7 @@ - + Time: %1 Value: %2 Duration: %3 @@ -6333,63 +6892,63 @@ - + Draw Region - + Erase Region - + Drag Region - - + + Edit Region - + Relocate Region - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste @@ -6440,7 +6999,7 @@ RemoveLayerCommand - + Delete %1 Layer @@ -6454,7 +7013,7 @@ - + Opening file or URL... @@ -6475,13 +7034,13 @@ SliceLayer - - + + %1 - %2 - + Time: %1 - %2 Range: %3 samples (%4) Bin: %5 @@ -6489,139 +7048,139 @@ - + First - - + + Mean - - + + Peak - + Time: %1 - %2 Range: %3 samples (%4) - + 0dB - + -Inf - + x10 - + Plot Type - - + + Scale - + Normalize Normalise - + Threshold - + Gain - + Sampling Mode - - + + Linear - + Meter - + Rev Log - - + + dB - + Any - + Bin Scale - + Bins - - + + Log - + Absolute - + Lines - + Steps - + Blocks - + Colours @@ -6629,22 +7188,22 @@ SparseModel - + Sparse - + Edit Data - + Insert Data Point - + Delete Data Point @@ -6652,7 +7211,7 @@ SparseModel::AddPointCommand - + Add Point @@ -6660,7 +7219,7 @@ SparseModel::DeletePointCommand - + Delete Point @@ -6668,7 +7227,7 @@ SparseModel::RelabelCommand - + Re-Label Point @@ -6755,23 +7314,23 @@ SpectrogramLayer - - + + Colour - + Colour Scale - + Window Size - + Window Overlap @@ -6784,337 +7343,341 @@ Normalise Visible Area - + Normalization - + Bin Display - + Threshold - + Gain - + Colour Rotation - + Min Frequency - + Max Frequency - + Frequency Scale - - Smoothing - - - - + Bins - + Window - + Scale - - + + Linear - + Meter - + dBV^2 - + dBV - + Phase - - + + None - + + Col + + + + + View + + + + + Hybrid + + + + 25 % - + 50 % - + 75 % - + 87.5 % - + 93.75 % - + No min - + 10 Hz - + 20 Hz - + 40 Hz - + 100 Hz - + 250 Hz - - + + 500 Hz - - + + 1 KHz - - + + 4 KHz - + 10 KHz - + 1.5 KHz - + 2 KHz - + 6 KHz - + 8 KHz - + 12 KHz - + 16 KHz - + No max - + Log - + All Bins - + Peak Bins - + Frequencies - + <unknown> - - + + dB - + FFT cache failed - + Failed to create the FFT model for this spectrogram. There may be insufficient memory or disc space to continue. - + Peak Frequency: %1 - %2 Hz - + Peak Frequency: %1 Hz - + Peak Pitch: %3 - %4 - + Peak Pitch: %2 - + Time: %1 - %2 - + Time: %1 - + %1Bin Frequency: %2 - %3 Hz %4Bin Pitch: %5 - %6 - + %1Bin Frequency: %2 Hz %3Bin Pitch: %4 - - - -Inf - - - - + dB: %1 - %2 - + dB: %1 - + Phase: %1 - %2 - + Phase: %1 - + 43Hz - + %1Hz @@ -7122,90 +7685,84 @@ SpectrumLayer - + Window Size - + Window Overlap - + Show Peak Frequencies - + Window - + Bins - + None - + 25 % - + 50 % - + 75 % - + 87.5 % - + 93.75 % - - - + + + %1 - %2 - + %1 - %2 Hz - + %1 Hz - - - -Inf - - - - + %1 - + %1 Bin: %2 (%3) %4 value: %5 @@ -7213,28 +7770,33 @@ - + First - + Mean - + Peak - + %1 Bin: %2 (%3) Value: %4 dB: %5 + + + Hz + + SubdividingMenu @@ -7437,105 +7999,105 @@ TimeInstantLayer - - + + New Point - + Plot Type - + Instants - + Segmentation - + In progress - + No local points - + Time: %1 No label - + Time: %1 Label: %2 - + Draw Point - + Add Point at %1 s - + Erase Point - + Drag Point - + Move Point to %1 s - + Edit Point - + Drag Selection - + Resize Selection - + Delete Selection - + Re-align pasted instants? - + The instants you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste @@ -7543,227 +8105,227 @@ TimeValueLayer - - + + New Point - - + + Plot Type - + Vertical Scale - + Scale Units - + Draw Segment Division Lines - + Show Derivative - + Scale - + Points - + Stems - + Connected Points - + Lines - + Curve - + Segmentation - + Discrete Curves - + Auto-Align - + Linear - + Log - + +/-1 - + In progress - + No local points - + %1 Hz (%2, %3) - + %1 %2 - + %1 - + Time: %1 Value: %2 No label - + Time: %1 Value: %2 Label: %4 - + Draw Point - + Erase Point - + Drag Point - - + + Edit Point - + Relocate Point - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + The items you are pasting do not have values. What values do you want to use for these items? - + Some of the items you are pasting do not have values. What values do you want to use for these items? - + Zero for all items - + Choose value calculation - + Select cycle size - + Cycle size: @@ -7799,136 +8361,141 @@ TransformFactory - + [\(<].*$ - - + + <unknown maker> - - + + Extract features using "%1" plugin (from %2) - - + + Extract features using "%1" output of "%2" plugin (from %3) - - + + %1 using "%2" plugin (from %3) - - + + %1 using "%2" output of "%3" plugin (from %4) - + Analysis + + Generator + + + + + + Other + + + + + + %1: %2 + + + + + %1: Output %2 + + + + + Extract "%1" data output from "%2" effect plugin (from %3) + + + + + Extract data output %1 from "%2" effect plugin (from %3) + + + - Generator - - - - - - Other - - - - - - %1: %2 - - - - - %1: Output %2 - - - - - Extract "%1" data output from "%2" effect plugin (from %3) - - - - - Extract data output %1 from "%2" effect plugin (from %3) + Effects Data - Effects Data - - - - Effects - + + Failed to list Vamp plugins: %1 + + + + Transform audio signal with "%1" effect plugin (from %2) - + Generate audio signal using "%1" plugin (from %2) + + + Plugin type + + + + + + Category + + + + + + System Identifier + + + - Plugin type + Name + + + + + + Description - Category + Maker - System Identifier - - - - - - Name - - - - - - Description - - - - - - Maker - - - - - Units @@ -8134,166 +8701,171 @@ View - + Global Scroll - + Global Zoom - + Follow Playback - + Scroll - + Page - + Off - + <unknown> - + Layer rendering error - + Alignment - + Waiting for layers to be ready... - - + + Cancel - + Rendering image... + + + Exported image from %1 + + ViewManager - + Clear Selection - + Select Multiple Regions - + Select Region - + Enter Navigate mode - + Enter Select mode - + Enter Edit mode - + Enter Draw mode - + Enter Erase mode - + Enter Measure mode - + Enter NoteEdit mode - + Switch on Loop mode - + Switch off Loop mode - + Switch on Play Selection mode - + Switch off Play Selection mode - + Switch on Play Solo mode - + Switch off Play Solo mode - + Switch on Alignment mode - + Switch off Alignment mode - + Scroll to %1 - + Zoom to %n sample(s) per pixel @@ -8301,7 +8873,7 @@ - + Change overlay level @@ -8309,118 +8881,111 @@ WaveformLayer - - + + Scale - + Gain - + Normalize Visible Area Normalise Visible Area - + Channels - + Linear - + Meter - - + + dB - + Separate - + Mean - + Butterfly - + Time: %1 - %2 - + Time: %1 - + Level: - + Left: - + Right: - + Channel %1 - + %1 %2 - %3 (%4 dB peak) - + %1 %2 (%3 dB peak) - - - + + + 0dB - - - - - -Inf - - WindowShapePreview - + V / time @@ -8433,7 +8998,7 @@ WritableWaveFileModel - + Writable Wave File diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_en_US.qm Binary file i18n/sonic-visualiser_en_US.qm has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_en_US.ts --- a/i18n/sonic-visualiser_en_US.ts Mon Sep 17 13:53:25 2018 +0100 +++ b/i18n/sonic-visualiser_en_US.ts Mon Sep 17 14:05:41 2018 +0100 @@ -4,17 +4,17 @@ ActivityLog - + Activity Log - + <p>Activity Log lists your interactions and other events within %1.</p> - + %1: %2 @@ -22,7 +22,7 @@ AddLayerCommand - + Add %1 Layer @@ -44,59 +44,85 @@ + AlignmentView + + + AlignmentView + + + + AudioCallbackPlaySource - + Play from %1 - + Stop at %1 - + Change time-stretch factor to %1 + AudioCallbackRecordTarget + + + recorded-%1.wav + + + + + Recorded %1 + + + + AudioDial - + + %1: %2 + + + + %1: %2%3 - + %2%3 - + New value for %1, from %2 to %3 %4: - + New value for %1, from %2 to %3: - + Enter a new value from %1 to %2 %3: - - + + Enter a new value from %1 to %2: - - + + Enter new value @@ -104,72 +130,82 @@ BZipFileDevice - + File is already open - + Append mode not supported - + File access mode not specified - + Read and write modes both specified - + Failed to open file for writing - + + Failed to open file handle for writing + + + + Failed to open bzip2 stream for writing - + Failed to open file for reading - + + Failed to open file handle for reading + + + + Failed to open bzip2 stream for reading - + Internal error (open for neither read nor write) - + File not open - + bzip2 stream write close error - + bzip2 stream read close error - + Internal error (close for neither read nor write) - + bzip2 stream read error @@ -188,8 +224,7 @@ CSVFileWriter - - + Failed to open file %1 for writing @@ -296,91 +331,106 @@ Colour3DPlotLayer - - + + Colour Color - - + + Scale - - Normalize Columns - - - - - Normalize Visible Area - - - - + + Normalization + + + + Invert Vertical Scale - + Gain - + Always Opaque - + Smooth - + Bin Scale - + Bins - - + + Linear - - + + Log - + +/-1 - + Absolute - + + None + + + + + Col + + + + + View + + + + + Hybrid + + + + <unknown> - + dB - + Time: %1 - %2 Bin: %3 Value: %4 @@ -388,72 +438,26 @@ - ColourMapper - - - - <unknown> - - - - - White on Black - - - - - Black on White - - - - - Green - - - - - Cherry - - - - - Wasp - - - - - Ice - - - - - Sunset - - - - - Fruit Salad - - - - - Banded - - - - - Highlight - - - - - Printer - - - - - High Gain - + ColourComboBox + + + Name New Colour + Name New Color + + + + Enter a name for the new colour: + Enter a name for the new color: + + + + Prefer black background for this colour + Prefer black background for this color + + + + Add New Colour... + Add New Color... @@ -535,7 +539,7 @@ DecodingWavFileReader - + Decoding %1... @@ -543,7 +547,7 @@ Dense3DModelPeakCache - + Dense 3-D Peak Cache @@ -551,17 +555,17 @@ DenseThreeDimensionalModel - + Dense 3-D - + Time - + Frame @@ -569,7 +573,7 @@ DenseTimeValueModel - + Dense Time-Value @@ -577,12 +581,12 @@ Document - + Set main model to %1 - + Clear main model @@ -590,7 +594,7 @@ EditableDenseThreeDimensionalModel - + Editable Dense 3-D @@ -598,12 +602,12 @@ FFTModel - + FFT - + %1 Hz @@ -634,53 +638,53 @@ FeatureExtractionModelTransformer - + Transforms supplied to a single FeatureExtractionModelTransformer instance must be similar in every respect except plugin output - + No factory available for feature extraction plugin id "%1" (unknown plugin type, or internal error?) - + Input model for feature extraction plugin "%1" is of wrong type (internal error?) - + Failed to instantiate plugin "%1" - + Cannot provide enough channels to feature extraction plugin "%1" (plugin min is %2, max %3; input model has %4) - - + + Failed to initialise feature extraction plugin "%1" Failed to initialize feature extraction plugin "%1" - + Feature extraction plugin "%1" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead - + Transform was configured for version %1 of plugin "%2", but the plugin being used is version %3 - + Plugin "%1" has no outputs - + Plugin "%1" has no output named "%2" @@ -688,29 +692,29 @@ FileSource - - - + + + Unsupported scheme in URL - + Downloading %1... - + Download cancelled - + Failed to create local file %1 - + File contains no data! @@ -718,75 +722,75 @@ FlexiNoteLayer - - - + + + New Point - + Vertical Scale - + Scale Units - + Scale - + Auto-Align - + Linear - + Log - + MIDI Notes - + In progress - - + + No local points - + %1 (%2, %3 Hz) - + %1 Hz (%2, %3) - + %1 %2 - + Time: %1 Pitch: %2 Duration: %3 @@ -794,7 +798,7 @@ - + Time: %1 Pitch: %2 Duration: %3 @@ -802,85 +806,85 @@ - + Draw Point - + Erase Point - + Drag Point - - - + + + Edit Point - + Relocate Point - + Change Point Value - + Add Point - + Snap Notes - + Merge Notes - + Drag Selection - + Resize Selection - - + + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + Record FlexiNote @@ -1096,19 +1100,19 @@ InteractiveFileFinder - + Select file - + All files (*.*) - + Select a session file @@ -1148,54 +1152,54 @@ - + File does not exist - + <b>File not found</b><p>File "%1" does not exist - + File is not readable - + <b>File is not readable</b><p>File "%1" can not be read - - + + Directory selected - - + + <b>Directory selected</b><p>File "%1" is a directory - + Non-file selected - + <b>Not a file</b><p>Path "%1" is not a file - + File is empty - + <b>File is empty</b><p>File "%1" is empty @@ -1240,6 +1244,13 @@ + + Scalable Vector Graphics files (*.svg) +All files (*.*) + + + + Comma-separated data files (*.csv) Space-separated .lab files (*.lab) Text files (*.txt) @@ -1247,7 +1258,7 @@ - + All supported files (*.sv %1 %2 %3) %4 session files (*.%5) Audio files (%1) @@ -1257,30 +1268,31 @@ - + %1 session files (*.%2) All files (*.*) - - - - - - - + + + + + + + + Select a file to export to - + WAV audio files (*.wav) All files (*.*) - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1290,7 +1302,7 @@ - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1299,7 +1311,7 @@ - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1309,7 +1321,7 @@ - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1318,78 +1330,78 @@ - + Portable Network Graphics files (*.png) All files (*.*) - + Comma-separated data files (*.csv) Text files (*.txt) All files (*.*) - + File exists - + <b>File exists</b><p>The file "%1" already exists. Do you want to overwrite it? - + <b>File not found</b><p>Audio file "%1" could not be opened. Do you want to locate it? - + <b>File not found</b><p>File "%1" could not be opened. Do you want to locate it? - + Failed to open file - + Locate file... - + Use URL... - + Cancel - + Use URL - + Please enter the URL to use for this file: - + Failed to open location - + <b>Failed to open location</b><p>URL "%1" could not be opened @@ -1566,6 +1578,7 @@ + %1.%2 @@ -1575,10 +1588,20 @@ - + Label Points + + + Subdivide Points + + + + + Winnow Points + + Layer @@ -1707,6 +1730,22 @@ + LevelPanToolButton + + + Click to adjust level and pan + + + + + LevelPanWidget + + + Drag vertically to adjust level, horizontally to adjust pan + + + + MIDIFileImportDialog @@ -1827,7 +1866,7 @@ MIDIInput - + Input @@ -1835,7 +1874,7 @@ MP3FileReader - + Decoding %1... @@ -1843,692 +1882,690 @@ MainWindow - + Black - + Red - + Blue - - - + + Green - + Purple - + Orange - + White - + Bright Red - + Bright Blue - - - + + Bright Green - + Bright Purple - + Bright Orange - - - + + + &Layer - - + + &Transform - + &File - + File Toolbar - + File and Session Management - + &New Session - + Ctrl+N - + Ctrl+O - + &Open... - + Open a session file, audio file, or layer - + &Save Session + + Ctrl+S + + + + + Save Session &As... + + + + + Ctrl+Shift+S + + + - Ctrl+S - - - - - Save Session &As... - - - - - Ctrl+Shift+S - - - - Ctrl+I - + &Export Audio File... - + Export selection as an audio file - + Import Annotation &Layer... - + Ctrl+L - + Import layer data from an existing file - + Export layer data to a file - + Export Image File... - + Export a single pane to an image file - + Open Lo&cation... - + Playback Speed - + Ctrl+Shift+O - + Open or import a file from a remote URL - + Export Audio Data... - + &Preferences... - + Adjust the application preferences - + &Quit - + Ctrl+Q - + &Edit - + Editing - + Cu&t - + Ctrl+X - + Cut the selection from the current layer to the clipboard - + &Copy - + Ctrl+C - + Copy the selection from the current layer to the clipboard - + &Paste - + Ctrl+V - + Paste from the clipboard to the current layer - + Paste at Playback Position - + Ctrl+Shift+V - + Paste from the clipboard to the current layer, placing the first item at the playback position - - + + &Delete Selected Items - + Del - - + + Delete items in current selection from the current layer - + Selection - + Select &All - + Ctrl+A - + Select the whole duration of the current session - + Select &Visible Range - + Ctrl+Shift+A - + Select the time range corresponding to the current window width - + Select to &Start - - - - + + + + Shift+Left - + Select from the start of the session to the current playback position - + Select to &End - + Shift+Right - + Select from the current playback position to the end of the session - + C&lear Selection - + Esc - + Clear the selection - + Tapping Time Instants - + &Insert Instant at Playback Position - + Enter - + Insert a new time instant at the current playback position, in a new layer if necessary - + ; - + Insert Instants at Selection &Boundaries - + Shift+Enter - + Insert new time instants at the start and end of the current selected regions, in a new layer if necessary - + Insert Item at Selection - + Insert a new note or region item corresponding to the current selection - + Number New Instants with - + Cycle size - + Reset Numbering Counters - + Reset to 1 all the counters used for counter-based labelling - + Set Numbering Counters... - + Set the counters used for counter-based labelling - + Renumber Selected Instants - + Renumber the selected instants using the current labelling scheme - + Panning and Navigation - + &View - + Scroll &Left - - - - - - - + + + + + + + Left - + Scroll the current pane to the left - + Scroll &Right - + Right - + Scroll the current pane to the right - + &Jump Left - - - + + + Ctrl+Left - + Scroll the current pane a big step to the left - + J&ump Right - + Ctrl+Right - + Scroll the current pane a big step to the right - + Peek Left - + Alt+Left - + Scroll the current pane to the left without moving the playback cursor or other panes - + Peek Right - + Alt+Right - + Scroll the current pane to the right without moving the playback cursor or other panes - + Zoom - + Zoom &In - + Up - + Increase the zoom level - + Zoom &Out - + Down - + Decrease the zoom level - + Restore &Default Zoom - + Restore the zoom level to the default - + Zoom to &Fit - + F - + Zoom to show the whole file - + Display Features - + Show &Centre Line - + ' - + Show or hide the centre line - + Toggle All Time Rulers - + Show &No Overlays - + 0 @@ -2537,12 +2574,12 @@ Hide center indicator, frame times, layer names and scale - + Show &Minimal Overlays - + 9 @@ -2551,7 +2588,7 @@ Show center indicator only - + 8 @@ -2560,1931 +2597,2084 @@ Show center indicator, frame times and scale - + Show &All Overlays - + # - + Export audio from selection into a data file - + Export Annotation La&yer... - + Ctrl+Y - + + Export SVG File... + + + + + Export a single pane to a scalable SVG image file + + + + Browse Recorded Audio Folder - + Open the Recorded Audio folder in the system file browser - + + Shift+; + + + + + Ctrl+Shift+; + + + + + Ctrl+Shift+Enter + + + + Ctrl+Shift+Return - + + Subdivide Selected Instants... + + + + + Add new instants at regular intervals between the selected instants + + + + + Winnow Selected Instants... + + + + + Remove subdivisions, leaving only every Nth instant + + + + Show or hide all time rulers - + Hide times, layer names, and scale - + Show times and basic scale - + Show times, layer names, and scale - + Show &Zoom Wheels - + Z - + Show thumbwheels for zooming horizontally and vertically - + Show Property Bo&xes - + X - + Show the layer property boxes at the side of the main window - + Show Status &Bar - + Show context help information in the status bar at the bottom of the window - + Show La&yer Summary - + Y - + Open a window displaying the hierarchy of panes and layers in this session - + Show Acti&vity Log - + Open a window listing interactions and other events - + Show &Unit Converter - + Open a window of pitch and timing conversion utilities - + Go Full-Screen - + F11 - + Expand the pane area to the whole screen - + &Pane - + Managing Panes and Layers - + Add &New Pane - + N - + Add a new pane containing only a time ruler - + Add New %1 Layer - + Add a new empty layer of type %1 - + T - + Add &Waveform + + W + + + + + Add a new pane showing a waveform view + + + + + Shift+W + + + + + Add a new layer showing a waveform view + + + + + Add Spectro&gram + + + + + G + + + + + Add a new pane showing a spectrogram + + + + + Shift+G + + + + + Add a new layer showing a spectrogram + + + + + Add &Melodic Range Spectrogram + + + + + M + + + + + Add a new pane showing a spectrogram set up for an overview of note pitches + + + + + Shift+M + + + + + Add a new layer showing a spectrogram set up for an overview of note pitches + + + + + Add Pea&k Frequency Spectrogram + + + + + K + + + + + Add a new pane showing a spectrogram set up for tracking frequencies + + + + + Shift+K + + + + + Add a new layer showing a spectrogram set up for tracking frequencies + + + + + Add Spectr&um + + + - W - - - - - Add a new pane showing a waveform view - - - - - Shift+W - - - - - Add a new layer showing a waveform view - - - - - Add Spectro&gram - - - - - G - - - - - Add a new pane showing a spectrogram - - - - - Shift+G - - - - - Add a new layer showing a spectrogram - - - - - Add &Melodic Range Spectrogram - - - - - M - - - - - Add a new pane showing a spectrogram set up for an overview of note pitches - - - - - Shift+M - - - - - Add a new layer showing a spectrogram set up for an overview of note pitches - - - - - Add Pea&k Frequency Spectrogram - - - - - K - - - - - Add a new pane showing a spectrogram set up for tracking frequencies - - - - - Shift+K - - - - - Add a new layer showing a spectrogram set up for tracking frequencies - - - - - Add Spectr&um - - - - U - + Add a new pane showing a frequency spectrum - + Shift+U - + Add a new layer showing a frequency spectrum - + &All Channels Mixed - + &All Channels - + Channel &%1 - - + + %1: %2 - + Switch to Previous Pane - + [ - + Make the next pane up in the pane stack current - + Switch to Next Pane - + ] - + Make the next pane down in the pane stack current - + &Delete Pane - + Ctrl+Shift+D - + Delete the currently active pane - + Add &Time Ruler - + Add a new layer showing a time ruler - + Add &Existing Layer - + Add S&lice of Layer - + Switch to Previous Layer - + { - + Make the previous layer in the pane current - + Switch to Next Layer - + } - + Make the next layer in the pane current - + &Rename Layer... - + R - + Rename the currently active layer - + Edit Layer Data - + E - + Edit the currently active layer as a data grid - + &Delete Layer - + Ctrl+D - + Delete the currently active layer - + &Recent Transforms - + %1 by Category - - + + Unclassified - + %1 by Plugin Name - + %1 by Maker - - + + Unknown - - + + [\(<].*$ - - + + %1... - + Find a Transform... - + Search for a transform from the installed plugins, by name or description - + Ctrl+M - + &Help - + Help - + &Help Reference - + F1 - + &Key and Mouse Reference - + F2 - + + What's &New? + + + + + Show changes in this release of %1 + + + + Ctrl+R - + Re-open - + Re-open the current or most recently opened file - + Standard Waveform - + Choose Default Template... - + Ctrl+T - + Repeat Transform - + Re-select the most recently run transform - + Playback and Transport Controls - + Play&back - + Playback - + Playback Toolbar - + Rewind to Start - + Home - + Rewind to the start - - + + + + Rewind + + + + + PgUp + + + + + Rewind to the previous time instant or time ruler notch + + + + + Rewind to Similar Point + + + + + Shift+PgUp + + + + + Rewind to the previous similarly valued time instant + + + + + Play / Pause + + + + + Space + This text is a shortcut label referring to the space-bar on the keyboard. It probably should not be translated, and certainly should not be translated as if referring to an empty void or to the extra-terrestrial universe. + + + + + Start or stop playback from the current position + + + + + + Fast Forward + + + + + PgDown + + + + + Fast-forward to the next time instant or time ruler notch + + + + + Fast Forward to Similar Point + + + + + Shift+PgDown + + + + + Fast-forward to the next similarly valued time instant + + + + + Fast Forward to End + + + + + End + + + + + Fast-forward to the end + + + + + Record + + + + + Ctrl+Space + + + + + Record a new audio file + + + + + Play Mode Toolbar + + + + + Constrain Playback to Selection + + + + + s + + + + + Constrain playback to the selected regions + + + + + Loop Playback + + + + + l + + + + + Loop playback + + + + + Solo Current Pane + + + + + o + + + + + Solo the current pane during playback + + + + + Align File Timelines + + + + + Treat multiple audio files as versions of the same work, and align their timelines + + + + + Speed Up + + + + + Ctrl+PgUp + + + + + Time-stretch playback to speed it up without changing pitch + + + + + Slow Down + + + + + Ctrl+PgDown + + + + + Time-stretch playback to slow it down without changing pitch + + + + + Restore Normal Speed + + + + + Ctrl+Home + + + + + Restore non-time-stretched playback + + + + + Edit Toolbar + + + + + + + + + + Tool Selection + + + + + Export the whole pane + + + + + Export the visible area only + + + + + Which region of the current pane do you want to export as a scalable SVG image? + + + + + Failed to save SVG file + + + + + Failed to save SVG file %1 + + + + + Failed to query transform attributes + + + + + <b>Failed to query transform attributes</b><p>Plugin or server error: %1</p> + + + + + Multiplexed audio + + + + + Transform failed + + + + + <b>Failed to run transform</b><p>Plugin or server error: %1</p> + + + + + Playback speed: %1% (%2x slower) + + + + + Playback speed: %1% (%2x faster) + + + + + Subdivide instants + + + + + Number of subdivisions: + + + + + Winnow instants + + + + + Remove all instants apart from multiples of: + + + + + <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 + + + + + <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. + + + + + <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment:<p>%1 + + + + + Adjust the master playback level and pan + + + + + With Qt v%1 &copy; The Qt Company + + + + + <br>With Rubber Band Library v%1 &copy; Particular Programs Ltd + + + + + <br>With Rubber Band Library &copy; Particular Programs Ltd + + + + + <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam and QMUL + + + + + <br>With Piper Vamp protocol bridge &copy; QMUL + + + + + <br>With Dataquay Qt/RDF library &copy; Particular Programs Ltd + + + + + <br>With Cap'n Proto serialisation &copy; Sandstorm Development Group + + + + + Russian UI translation contributed by Alexandre Prokoudine. + + + + + Czech UI translation contributed by Pavel Fric. + + + + + <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> + + + + + Tools Toolbar + + + + + + + Navigate + + + + + 1 + + + + - Rewind - - - - - PgUp - - - - - Rewind to the previous time instant or time ruler notch - - - - - Rewind to Similar Point - - - - - Shift+PgUp - - - - - Rewind to the previous similarly valued time instant - - - - - Play / Pause - - - - - Space - - - - - Start or stop playback from the current position - - - - - - Fast Forward - - - - - PgDown - - - - - Fast-forward to the next time instant or time ruler notch - - - - - Fast Forward to Similar Point - - - - - Shift+PgDown - - - - - Fast-forward to the next similarly valued time instant - - - - - Fast Forward to End - - - - - End - - - - - Fast-forward to the end - - - - - Record - - - - - Ctrl+Space - - - - - Record a new audio file - - - - - Play Mode Toolbar - - - - - Constrain Playback to Selection - - - - - s - - - - - Constrain playback to the selected regions - - - - - Loop Playback - - - - - l - - - - - Loop playback - - - - - Solo Current Pane - - - - - o - - - - - Solo the current pane during playback - - - - - Align File Timelines - - - - - Treat multiple audio files as versions of the same work, and align their timelines - - - - - Speed Up - - - - - Ctrl+PgUp - - - - - Time-stretch playback to speed it up without changing pitch - - - - - Slow Down - - - - - Ctrl+PgDown - - - - - Time-stretch playback to slow it down without changing pitch - - - - - Restore Normal Speed - - - - - Ctrl+Home - - - - - Restore non-time-stretched playback - - - - - Edit Toolbar - - - - - - - - - - Tool Selection - - - - - Playback speed: %1% (%2x slower) - - - - - Playback speed: %1% (%2x faster) - - - - - <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 - - - - - <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. - - - - - <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> - - - - - Tools Toolbar - - - - - - - Navigate - - - - - 1 - - - - - Select - + 2 - + Select ranges - - - + + + Edit - + Navigate Tool Mouse Actions - + Click left button and drag to move around - - + + Zoom to Area - - + + Shift-click left button and drag to zoom to a rectangular area - + Relocate - - - - + + + + Double-Click Left - + Double-click left button to jump to clicked location - - + + Double-click left button on an item to edit it - + Select Tool Mouse Actions - + Click left button and drag to select region; drag region edge to resize - - + + Multi Select - + Cmd-click left button and drag to select an additional region - + Ctrl-click left button and drag to select an additional region - + Fine Select - + Shift-click left button and drag to select without snapping to items or grid - + 3 - + Edit items in layer - + Edit Tool Mouse Actions - + Move - + Click left button on an item or selected region and drag to move - - + + Draw - + 4 - + Draw new items in layer - + Draw Tool Mouse Actions - + Click left button and drag to create new item - - + + Erase - + 5 - + Erase items from layer - + Erase Tool Mouse Actions - + Click left button on an item to remove it from the layer - + Measure - + 6 - + Make measurements in layer - + Measure Tool Mouse Actions - + Measure Area - + Click left button and drag to measure a rectangular area - + Measure Item - + Click left button and drag to measure extents of an item or shape - + &Delete Current Measurement - + Delete the measurement currently under the mouse pointer - + Fast Forward to Next Instant - + Fast forward to the next time instant in the current layer - + Rewind to Previous Instant - + Rewind to the previous time instant in the current layer - + Fast Forward to Next Point - + Fast forward to the next point in the current layer - + Rewind to Previous Point - + Rewind to the previous point in the current layer - + Fast forward - + No audio file loaded. - + %1Hz (resampling to %2Hz) - - - - - - - + + + + + + + Failed to open file - - - + + + <b>File open failed</b><p>Audio file "%1" could not be opened - + 1. %2 - + %1. %2 - + Select audio file to export - + Which audio file do you want to export from? - + Export the selected region only - + Export the whole audio file - - - + + + + Select region to export - + Which region from the original audio file do you want to export? - + Export the selected regions into separate files - + Multiple regions of the original audio file are selected. What do you want to export? - + Fragment file %1 already exists, aborting - + Export multiple audio files - + Export audio to "%1" - - + + Failed to write file - + <b>File open failed</b><p>Layer file %1 could not be opened. - - - - - + + + + + <b>Audio required</b><p>Unable to load layer data from "%1" without an audio file.<br>Please load at least one audio file before importing annotations. - + Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values) - + Enter template name - + Please enter a name for the saved template: - + Set as default template for future audio files - + Template file exists - + <b>Template file exists</b><p>The template "%1" already exists.<br>Overwrite it? - + http://www.sonicvisualiser.org/doc/reference/%1/en/ - + + What's New + + + + + <h3>What's New in %1</h3> + + + + + <b>Note:</b> A newer version of Sonic Visualiser is available.<br>(Version %1 is available; you are using version %2) + + + + + %1 : %2 configuration, %3-bit build + + + + <br>With Serd and Sord RDF parser and store &copy; David Robillard - - <br>With Dataquay Qt/RDF library &copy; Chris Cannam - - - - + + About %1 + + + + Newer version available - + Failed to open file %1 for writing - + Abandon the current %1 session and start a new one - + &Import More Audio... - + Import an extra audio file into a new pane - + Replace &Main Audio... - + Replace the main audio file of the session with a different file - + Open &Recent - + Save the current session into a %1 session file - + Save the current session into a new %1 session file - + Apply Session Template - + Export Session as Template... - + Manage Exported Templates - + Exit %1 - + Open the %1 reference manual - + Open a window showing the keystrokes you can use in %1 - + %1 on the &Web - + Open the %1 website - + &About %1 - + Show information about %1 - + Export the selected regions into a single file - + Export the whole file - + Can't export non-note layers to MIDI - + Export layer to "%1" - + Export the whole pane (%1x%2 pixels) - + Export the visible area only (%1x%2 pixels) - + Export the selection extent (%1x%2 pixels) - + + Export the selection extent - + Which region of the current pane do you want to export as an image? - + Note: the whole pane is too wide to be exported as a single image. - + Failed to save image file - + Failed to save image file %1 - + <b>File open failed</b><p>File "%1" could not be opened - + Open Location - + Please enter the URL of the location to open: - - - - + + + + Failed to open location - + <b>Open failed</b><p>URL "%1" could not be opened - + <b>Open failed</b><p>File or URL "%1" could not be opened - - + + Failed to open dropped URL - + <b>Open failed</b><p>Dropped URL "%1" could not be opened - + Export image to "%1" - + Session modified - + <b>Session modified</b><p>The current session has been modified.<br>Do you want to save it? - + Close the current session and create a new one - + Add this data to the current session - + Select target for import - + <b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data? - - + + Failed to save file - - + + <b>Save failed</b><p>Session file "%1" could not be saved. - + Save session as "%1" - + Multiplex all of the above - + Rename Layer - + New name for this layer: - + Playback speed: Normal - + Selection: %1 to %2 (duration %3) - + Visible: %1 to %2 (duration %3) - + Sample rate mismatch - + <b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match the current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour. - - + + Audio processing overload - + <b>Overloaded</b><p>Audio effects plugin auditioning has been disabled due to a processing overload. - + <b>Overloaded</b><p>Audio playback speed processing has been reduced to a single channel, due to a processing overload. - + Problems loading plugins - + Add Point - + Reset Counters - - + + Failed to generate layer - - + + Warning - - + + Failed to regenerate layer - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed:<p>%3 - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed.<p>No error information is available. - + <b>Warning when regenerating layer</b><p>When regenerating the derived layer "%1" using new data model as input:<p>%2 - + Failed to calculate alignment - - <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment using transform "%1":<p>%2 - - - - - Adjust the master playback level - - - - + Adjust the master playback speed - + http://www.sonicvisualiser.org/ - + Release %1 : Revision %2 - + Release %1 - + Unreleased : Revision %1 - + <h3>About Sonic Visualiser</h3> - + <p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.<br><a href="http://www.sonicvisualiser.org/">http://www.sonicvisualiser.org/</a></p> - - <p><small>%1 : %2 configuration</small></p> - - - - + Debug - + Release - - With Qt v%1 &copy; Nokia Corporation - - - - + <br>With JACK audio output library v%1 &copy; Paul Davis and Jack O'Quin - + <br>With JACK audio output library &copy; Paul Davis and Jack O'Quin - + <br>With PortAudio audio output library &copy; Ross Bencina and Phil Burk - + <br>With PulseAudio audio output library v%1 &copy; Lennart Poettering and Pierre Ossman - + <br>With PulseAudio audio output library &copy; Lennart Poettering and Pierre Ossman - + <br>With Ogg file decoder (oggz v%1, fishsound v%2) &copy; CSIRO Australia - + <br>With Ogg file decoder &copy; CSIRO Australia - + <br>With MAD mp3 decoder v%1 &copy; Underbit Technologies Inc - + <br>With MAD mp3 decoder &copy; Underbit Technologies Inc - + <br>With libsamplerate v%1 &copy; Erik de Castro Lopo - + <br>With libsamplerate &copy; Erik de Castro Lopo - + <br>With libsndfile v%1 &copy; Erik de Castro Lopo - + <br>With libsndfile &copy; Erik de Castro Lopo - + <br>With FFTW3 v%1 &copy; Matteo Frigo and MIT - + <br>With FFTW3 &copy; Matteo Frigo and MIT - - <br>With Rubber Band v%1 &copy; Chris Cannam - - - - - <br>With Rubber Band &copy; Chris Cannam - - - - - <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam - - - - + <br>With LADSPA plugin support (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld - + <br>With DSSI plugin support (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton - + <br>With Redland RDF datastore v%1 &copy; Dave Beckett and the University of Bristol - + <br>With Redland RDF datastore &copy; Dave Beckett and the University of Bristol - + <br>With RtMidi &copy; Gary P. Scavone - + <br>With liblo Lite OSC library v%1 &copy; Steve Harris - + <br>With liblo Lite OSC library &copy; Steve Harris - + </small><p><small>The OSC URL for this instance is: "%1" - - With - - - - - Using - - - - - About Sonic Visualiser - - - - + Add %1 Pane @@ -4492,215 +4682,301 @@ MainWindowBase - + %1 (modified) - + (modified) - + Cut - + Paste - - - - - + + + + + Add Point - + Add Point at %1 s - + Add Item at %1 s - + Opening file or URL... - + Select target for import - - - - + + + + %1: %2 - - + + %1: %2 [%3] - - + + Import "%1" - + Opening playlist... - - + + Importing from RDF... - + Opening session... - + + Not enough disc space + + + + + <b>Not enough disc space</b><p>There doesn't appear to be enough spare disc space to accommodate any necessary temporary files.</p><p>Please clear some space and try again.</p> + + + + + Not enough memory + + + + + <b>Not enough memory</b><p>There doesn't appear to be enough memory to accommodate any necessary temporary data.</p> + + + + Close the current session and start a new one - + Replace the main audio file in this session - + Add the audio file to this session - + <b>Select a target for import</b><p>You already have an audio file loaded.<br>What would you like to do with the new audio file? - + Import audio file "%1" - + Import layer XML file "%1" - + Import MIDI file "%1" - - + + SV XML file read error: %1 - + Import session file "%1" - + + Incomplete session loaded + + + + + Some of the audio content referred to by the original session file could not be loaded. +If you save this session, it will be saved without any reference to that audio, and information may be lost. + + + + Open session template "%1" - - + + Failed to import RDF - + <b>Failed to import RDF</b><p>Importing data from RDF document at "%1" failed: %2</p> - + <b>Failed to import RDF</b><p>No suitable data models found for import from RDF document at "%1"</p> - + Import RDF document "%1" - + + <b>No audio available</b><p>Could not open an audio device.</p> + + + + + <b>No audio available</b><p>Could not open audio device: %1</p> + + + + + <p>Automatic audio device detection failed. Audio playback and recording will not be available during this session.</p> + + + + + <p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1").</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1"): %2.</p> + + + + + <p>Audio playback and recording will not be available during this session.</p> + + + + + <p>Audio playback will not be available during this session.</p> + + + + Couldn't open audio device - - <b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> - - - - + Recording: %1 - - - + + + Failed to write file - - - + + + <b>Save failed</b><p>Failed to write to file "%1": %2 - + + No record device available + + + + + <b>No record device available</b><p>Failed to find or open an audio device for recording. Only playback will be available.</p> + + + + + Recording failed + + + + + <b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p> + + + + Import Recorded Audio - + Add Pane - + Remove Pane - - + + Delete Pane - + Playing: %1 of %2 (%3 remaining) @@ -4814,7 +5090,7 @@ - + %1: %2 @@ -4822,17 +5098,32 @@ NetworkPermissionTester - + Welcome to Sonic Visualiser - - <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary, University of London, Sonic Visualiser is provided free as open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like to make networking connections and open a network port.</p><p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control, where configured; and</li><li> Tell you when updates are available.</li></ul><p>No personal information will be sent, no tracking is carried out, and all requests happen in the background without interrupting your work.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful. But if you do not wish to do so, please un-check the box below.<br></p> - - - - + + <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary University of London, Sonic Visualiser is open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like permission to use the network.</p> + + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control; and</li><li> Tell you when updates are available.</li></ul> + + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins; and</li><li> Tell you when updates are available.</li></ul> + + + + + <p><b>No personal information will be sent, no tracking is carried out, and no individual information will be shared with anyone else.</b> We will however make aggregate counts of distinct requests for usage reporting.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful to you and supports the public funding of this work. But if you do not wish to allow it, please un-check the box below.<br></p> + + + + Allow this @@ -4840,75 +5131,75 @@ NoteLayer - - + + New Point - + Vertical Scale - + Scale Units - + Scale - + Auto-Align - + Linear - + Log - + MIDI Notes - + In progress - - + + No local points - + %1 (%2, %3 Hz) - + %1 Hz (%2, %3) - + %1 %2 - + Time: %1 Pitch: %2 Duration: %3 @@ -4916,7 +5207,7 @@ - + Time: %1 Pitch: %2 Duration: %3 @@ -4924,68 +5215,68 @@ - + Draw Point - + Erase Point - + Drag Point - - + + Edit Point - + Relocate Point - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + Record Note @@ -5041,7 +5332,7 @@ OggVorbisFileReader - + Decoding %1... @@ -5054,7 +5345,7 @@ - + Click and drag to navigate; double-click to jump @@ -5062,300 +5353,300 @@ Pane - + Horizontal Zoom - + Vertical Zoom - + Reset zoom to default - + Some lengthy prefix: - + Reference - - + + Unaligned - + Aligning: %1% - + Aligned - + %1 - %2 - - + + +%1 - + (R) - + (X) - + %1 / %2Hz%3 - - + + Zoom - + Zoom In - + Wheel Up - + Zoom Out - + Wheel Down - + General Pane Mouse Actions - + Wheel - + Zoom in or out in time axis - + Scroll - + Ctrl+Wheel - + Scroll rapidly left or right in time axis - + Zoom Vertically - + Shift+Wheel - + Zoom in or out in the vertical axis - + Scroll Vertically - + Alt+Wheel - + Scroll up or down in the vertical axis - + Navigate - + Middle - + Click middle button and drag to navigate with any tool - + Relocate - + Double-Click Middle - + Double-click middle button to relocate with any tool - + Menu - + Right - + Show pane context menu - + Enter new range - + New vertical display range, from %1 to %2 %4: - + Drag Selection - + Resize Selection - + Click and drag to navigate - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Cmd for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Cmd for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate - + Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate - + Click and drag to move the selection boundary - + Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate - + Click and drag to select a range; middle-click and drag to navigate - + Click to add a new item in the active layer - + Click to erase an item from the active layer - + Click and drag an item in the active layer to move it; hold Shift to override initial resistance - + Click and drag to move all items in the selected range - + Click and drag to adjust the visible range of the vertical scale - + Click and drag to adjust the vertical zoom level - + Click and drag to adjust the horizontal zoom level - + Reset horizontal and vertical zoom levels to their defaults @@ -5404,382 +5695,534 @@ PluginParameterDialog - - + + Plugin Parameters - + Name: - + Version: - + Maker: + + Copyright: + + + - Copyright: - - - - Output: - + Input Material - + Restrict to selection extents - + Channels - + Processing - - + + Advanced >> - + Channel mismatch - + This plugin requires at least %1 input channels, but only %2 %3 available. The plugin probably will not work correctly. - + are - + is - + This plugin accepts no more than %1 input channels, but %2 are available. Only the first %3 will be used. - + This plugin only has a single channel input, but the source has %1 channels. - + Use mean of source channels - + Use channel %1 only - + Window size: - + Audio frames per block: - + Window increment: - + Window shape: - + Advanced << + PluginPathConfigurator + + + Move the selected location later in the list + + + + + Move the selected location earlier in the list + + + + + Add a new location to the list + + + + + Remove the selected location from the list + + + + + Reset to Default + + + + + Reset the list for this plugin type to its default + + + + + Review plugins... + + + + + Plugin locations for plugin type: + + + + + Vamp + + + + + LADSPA + + + + + DSSI + + + + + Vamp (32-bit) + + + + + LADSPA (32-bit) + + + + + DSSI (32-bit) + + + + + (Variable is currently unset) + + + + + (Current value begins: "%1 ...") + + + + + (Currently set to: "%1") + + + + + Allow the %1 environment variable to take priority over this +%2 + + + + + Choose directory to add + + + + + PluginReviewDialog + + + Plugins Loaded + + + + + Type + + + + + Library + + + + + Identifier + + + + + Found in + + + + + Name + + + + + Vamp + + + + + DSSI + + + + + LADSPA + + + + Preferences - + Spectrogram y-axis interpolation: - + Spectrogram x-axis interpolation: - + Frequency of concert A - + Property box layout - + Spectral analysis window shape - + Playback resampler type - + Normalise audio signal when reading from audio file - + Omit temporaries from Recent Files menu - + Resample mismatching files on import - + + Load mp3 files in gapless mode + + + + Single fixed sample rate to resample all files to - + Location for cache file directory - + Background colour preference Background color preference - + Time display precision - + Use hours:minutes:seconds format - + Label middle C as - + Font size for text overlays - + Show splash screen on startup - + Show boxes for all panes - + Show box for current pane only - + Rectangular - + Triangular - + Hamming - + Hann - + Blackman - + Gaussian - + Parzen - + Nuttall - + Blackman-Harris - + Fastest - + Standard - + Highest quality - + + + None + + + + + + Linear interpolation + + + - None - - - - + 4 x Oversampling + + + - Linear interpolation - - - - - 4 x Oversampling - - - - 4 x Oversampling with interpolation - + Follow desktop theme - + Dark background - + Light background - + Standard (to millisecond) - + High resolution (to microsecond) - + 24 FPS - + 25 FPS - + 30 FPS - + 50 FPS - + 60 FPS - + C0 - middle of octave scale - + C3 - common MIDI sequencer convention - + C4 - ASA American standard - + C5 - used in Cakewalk and others - + Preferences @@ -5787,155 +6230,212 @@ PreferencesDialog - + Sonic Visualiser: Application Preferences - + Apply - + + Green + + + + + + + (auto) + + + + <home directory> - + Follow system locale - + Russian - + British English - + American English - + Czech - - - - - - - - + + + + + + + + + + + + + + + %1: + + + - - - - - - %1: - - - - + Overview waveform colour: + + + + + Run Vamp plugins in separate process: + + + + + Default session template when loading audio files: + + + + + (Use "%1" in the File menu to add to these.) + + + + + Export Session as Template... + + + + + Audio service: + + + + + Audio playback device: + + + + + Audio record device: + + + + + A&udio I/O + + + + + &Plugins + + + + User interface language - + Allow network usage - - &General - - - - + Draw layers at Retina resolution: - + Default spectrogram colour: Default spectrogram color: - + Default melodic spectrogram colour: Default melodic spectrogram color: - + Default colour 3D plot colour: Default color 3d plot color: - + &Appearance - + Anal&ysis - - Default session template for audio files: - - - - + Standard Waveform - + Session &Template - + + &Other + + + + OK - + Cancel - + Select a directory to create cache subdirectory in - + Preferences - + <b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p> - + Preferences Changed - + Some preferences have been changed but not applied. Apply them before closing? @@ -5944,7 +6444,7 @@ ProgressDialog - + Cancel @@ -5952,83 +6452,73 @@ PropertyBox - + Show - - Play - - - - - Playback Gain - - - - - dB - - - - - - Playback Pan / Balance - - - - Add New Colour... - Add New Color... - - - + Add New Color... + + Name New Colour - Name New Color - - - + Name New Color + + Enter a name for the new colour: - Enter a name for the new color: - - - + Enter a name for the new color: + + Prefer black background for this colour - Prefer black background for this color - - - + Prefer black background for this color + + + + Click to toggle playback + + + + Set playback clip: - + + Adjust playback level and pan of %1 + + + + + Change sound used for playback (currently "%1") + + + + (current value: %1%2) - + (current value: %1) - + Toggle Visibility of %1 - + Toggle Playback of %1 - + Toggle %1 property of %2 - + Adjust %1 property of %2%3 @@ -6066,7 +6556,7 @@ - + Set %1 Property @@ -6087,7 +6577,7 @@ QApplication - + Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation. @@ -6103,7 +6593,7 @@ - + Sonic Visualiser @@ -6111,13 +6601,13 @@ QFile - + File "%1" does not exist - + Failed to open file "%1" @@ -6132,18 +6622,18 @@ QMessageBox - - + + Failed to open file - + File or URL "%1" could not be opened - + <b>Audio required</b><p>Please load at least one audio file before importing annotation data @@ -6151,37 +6641,114 @@ QObject - - <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> - - - - - - Failed to load library - - - - - Failed to query plugins from library after loading - - - - - Unknown failure - - - - - Success: internal error? - - - - - QuickTimeFileReader - - - Decoding %1... + + External plugin host executable does not appear to be installed + + + + + Could not start external plugin host + + + + + External plugin host exited unexpectedly while listing plugins + + + + + External plugin host invocation failed: %1 + + + + + <b>Failed to scan for plugins</b><p>Failed to scan for plugins at startup. Possibly the plugin checker program was not correctly installed alongside %1?</p> + + + + + <b>Did not scan for plugins</b><p>Apparently no scan for plugins was attempted (internal error?)</p> + + + + + <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> + + + + + <p>These plugins may be incompatible with the system, and will be ignored during this run of %1.</p> + + + + + + <unknown> + + + + + Green + + + + + White on Black + + + + + Black on White + + + + + Cherry + + + + + Wasp + + + + + Ice + + + + + Sunset + + + + + Fruit Salad + + + + + Banded + + + + + Highlight + + + + + Printer + + + + + High Gain + + + + + Exporting audio data... @@ -6230,79 +6797,79 @@ RegionLayer - + New Region - + Vertical Scale - + Scale Units - + Plot Type - + Scale - + Bars - + Segmentation - + Auto-Align - + Equal Spaced - + Linear - + Log - + In progress - - + + No local points - + %1 %2 - + Time: %1 Value: %2 Duration: %3 @@ -6310,7 +6877,7 @@ - + Time: %1 Value: %2 Duration: %3 @@ -6318,63 +6885,63 @@ - + Draw Region - + Erase Region - + Drag Region - - + + Edit Region - + Relocate Region - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste @@ -6425,7 +6992,7 @@ RemoveLayerCommand - + Delete %1 Layer @@ -6439,7 +7006,7 @@ - + Opening file or URL... @@ -6460,13 +7027,13 @@ SliceLayer - - + + %1 - %2 - + Time: %1 - %2 Range: %3 samples (%4) Bin: %5 @@ -6474,139 +7041,139 @@ - + First - - + + Mean - - + + Peak - + Time: %1 - %2 Range: %3 samples (%4) - + 0dB - + -Inf - + x10 - + Plot Type - - + + Scale - + Normalize - + Threshold - + Gain - + Sampling Mode - - + + Linear - + Meter - + Rev Log - - + + dB - + Any - + Bin Scale - + Bins - - + + Log - + Absolute - + Lines - + Steps - + Blocks - + Colours Colors @@ -6614,22 +7181,22 @@ SparseModel - + Sparse - + Edit Data - + Insert Data Point - + Delete Data Point @@ -6637,7 +7204,7 @@ SparseModel::AddPointCommand - + Add Point @@ -6645,7 +7212,7 @@ SparseModel::DeletePointCommand - + Delete Point @@ -6653,7 +7220,7 @@ SparseModel::RelabelCommand - + Re-Label Point @@ -6740,358 +7307,362 @@ SpectrogramLayer - - + + Colour Color - + Colour Scale Color Scale - + Window Size - + Window Overlap - + Normalization - + Bin Display - + Threshold - + Gain - + Colour Rotation Color Rotation - + Min Frequency - + Max Frequency - + Frequency Scale - - Smoothing - - - - + Bins - + Window - + Scale - - + + Linear - + Meter - + dBV^2 - + dBV - + Phase - - + + None - + + Col + + + + + View + + + + + Hybrid + + + + 25 % - + 50 % - + 75 % - + 87.5 % - + 93.75 % - + No min - + 10 Hz - + 20 Hz - + 40 Hz - + 100 Hz - + 250 Hz - - + + 500 Hz - - + + 1 KHz - - + + 4 KHz - + 10 KHz - + 1.5 KHz - + 2 KHz - + 6 KHz - + 8 KHz - + 12 KHz - + 16 KHz - + No max - + Log - + All Bins - + Peak Bins - + Frequencies - + <unknown> - - + + dB - + FFT cache failed - + Failed to create the FFT model for this spectrogram. There may be insufficient memory or disc space to continue. - + Peak Frequency: %1 - %2 Hz - + Peak Frequency: %1 Hz - + Peak Pitch: %3 - %4 - + Peak Pitch: %2 - + Time: %1 - %2 - + Time: %1 - + %1Bin Frequency: %2 - %3 Hz %4Bin Pitch: %5 - %6 - + %1Bin Frequency: %2 Hz %3Bin Pitch: %4 - - - -Inf - - - - + dB: %1 - %2 - + dB: %1 - + Phase: %1 - %2 - + Phase: %1 - + 43Hz - + %1Hz @@ -7099,90 +7670,84 @@ SpectrumLayer - + Window Size - + Window Overlap - + Show Peak Frequencies - + Window - + Bins - + None - + 25 % - + 50 % - + 75 % - + 87.5 % - + 93.75 % - - - + + + %1 - %2 - + %1 - %2 Hz - + %1 Hz - - - -Inf - - - - + %1 - + %1 Bin: %2 (%3) %4 value: %5 @@ -7190,28 +7755,33 @@ - + First - + Mean - + Peak - + %1 Bin: %2 (%3) Value: %4 dB: %5 + + + Hz + + SubdividingMenu @@ -7414,105 +7984,105 @@ TimeInstantLayer - - + + New Point - + Plot Type - + Instants - + Segmentation - + In progress - + No local points - + Time: %1 No label - + Time: %1 Label: %2 - + Draw Point - + Add Point at %1 s - + Erase Point - + Drag Point - + Move Point to %1 s - + Edit Point - + Drag Selection - + Resize Selection - + Delete Selection - + Re-align pasted instants? - + The instants you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste @@ -7520,227 +8090,227 @@ TimeValueLayer - - + + New Point - - + + Plot Type - + Vertical Scale - + Scale Units - + Draw Segment Division Lines - + Show Derivative - + Scale - + Points - + Stems - + Connected Points - + Lines - + Curve - + Segmentation - + Discrete Curves - + Auto-Align - + Linear - + Log - + +/-1 - + In progress - + No local points - + %1 Hz (%2, %3) - + %1 %2 - + %1 - + Time: %1 Value: %2 No label - + Time: %1 Value: %2 Label: %4 - + Draw Point - + Erase Point - + Drag Point - - + + Edit Point - + Relocate Point - + Change Point Value - + Drag Selection - + Resize Selection - + Delete Selected Points - + Re-align pasted items? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste - + The items you are pasting do not have values. What values do you want to use for these items? - + Some of the items you are pasting do not have values. What values do you want to use for these items? - + Zero for all items - + Choose value calculation - + Select cycle size - + Cycle size: @@ -7776,136 +8346,141 @@ TransformFactory - + [\(<].*$ - - + + <unknown maker> - - + + Extract features using "%1" plugin (from %2) - - + + Extract features using "%1" output of "%2" plugin (from %3) - - + + %1 using "%2" plugin (from %3) - - + + %1 using "%2" output of "%3" plugin (from %4) - + Analysis + + Generator + + + + + + Other + + + + + + %1: %2 + + + + + %1: Output %2 + + + + + Extract "%1" data output from "%2" effect plugin (from %3) + + + + + Extract data output %1 from "%2" effect plugin (from %3) + + + - Generator - - - - - - Other - - - - - - %1: %2 - - - - - %1: Output %2 - - - - - Extract "%1" data output from "%2" effect plugin (from %3) - - - - - Extract data output %1 from "%2" effect plugin (from %3) + Effects Data - Effects Data - - - - Effects - + + Failed to list Vamp plugins: %1 + + + + Transform audio signal with "%1" effect plugin (from %2) - + Generate audio signal using "%1" plugin (from %2) + + + Plugin type + + + + + + Category + + + + + + System Identifier + + + - Plugin type + Name + + + + + + Description - Category + Maker - System Identifier - - - - - - Name - - - - - - Description - - - - - - Maker - - - - - Units @@ -8111,166 +8686,171 @@ View - + Global Scroll - + Global Zoom - + Follow Playback - + Scroll - + Page - + Off - + <unknown> - + Layer rendering error - + Alignment - + Waiting for layers to be ready... - - + + Cancel - + Rendering image... + + + Exported image from %1 + + ViewManager - + Clear Selection - + Select Multiple Regions - + Select Region - + Enter Navigate mode - + Enter Select mode - + Enter Edit mode - + Enter Draw mode - + Enter Erase mode - + Enter Measure mode - + Enter NoteEdit mode - + Switch on Loop mode - + Switch off Loop mode - + Switch on Play Selection mode - + Switch off Play Selection mode - + Switch on Play Solo mode - + Switch off Play Solo mode - + Switch on Alignment mode - + Switch off Alignment mode - + Scroll to %1 - + Zoom to %n sample(s) per pixel @@ -8278,7 +8858,7 @@ - + Change overlay level @@ -8286,118 +8866,111 @@ WaveformLayer - - + + Scale - + Gain - + Normalize Visible Area - + Channels - + Linear - + Meter - - + + dB - + Separate - + Mean - + Butterfly - + Time: %1 - %2 - + Time: %1 - + Level: - + Left: - + Right: - + Channel %1 - + %1 %2 - %3 (%4 dB peak) - + %1 %2 (%3 dB peak) - - - + + + 0dB - - - - - -Inf - - WindowShapePreview - + V / time @@ -8410,7 +8983,7 @@ WritableWaveFileModel - + Writable Wave File diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_ru.qm Binary file i18n/sonic-visualiser_ru.qm has changed diff -r 246bdf94ef7b -r 55d9bbf1fe45 i18n/sonic-visualiser_ru.ts --- a/i18n/sonic-visualiser_ru.ts Mon Sep 17 13:53:25 2018 +0100 +++ b/i18n/sonic-visualiser_ru.ts Mon Sep 17 14:05:41 2018 +0100 @@ -4,17 +4,17 @@ ActivityLog - + Activity Log Журнал изменений - + <p>Activity Log lists your interactions and other events within %1.</p> <p>Список всех предпринятых вами действий с %1.</p> - + %1: %2 %1: %2 @@ -22,7 +22,7 @@ AddLayerCommand - + Add %1 Layer Добавить слой %1 @@ -44,59 +44,85 @@ + AlignmentView + + + AlignmentView + + + + AudioCallbackPlaySource - + Play from %1 Воспроизведение от %1 - + Stop at %1 Остановка в позиции %1 - + Change time-stretch factor to %1 Смена коэффициента растяжения во времени на %1 + AudioCallbackRecordTarget + + + recorded-%1.wav + + + + + Recorded %1 + + + + AudioDial - - + + Enter new value Введите новое значение - + %1: %2%3 %1: %2%3 - + + %1: %2 + %1: %2 + + + %2%3 %2%3 - + New value for %1, from %2 to %3 %4: Новое значение для «%1», от %2 до %3 %4: - + New value for %1, from %2 to %3: Новое значение для «%1», от %2 до %3: - + Enter a new value from %1 to %2 %3: Введите новое значение от %1 до %2 %3: - - + + Enter a new value from %1 to %2: Введите новое значение от %1 до %2: @@ -127,72 +153,82 @@ BZipFileDevice - + File is already open Этот файл уже открыт - + Append mode not supported Режим добавления в конец не поддерживается - + File access mode not specified Способ доступа к файлам не указан - + Read and write modes both specified Режимы чтения и записи определены - + Failed to open file for writing Не удалось открыть файл для записи - + + Failed to open file handle for writing + + + + Failed to open bzip2 stream for writing Не удалось открыть поток bzip2 для записи - + Failed to open file for reading Не удалось открыть файл для чтения - + + Failed to open file handle for reading + + + + Failed to open bzip2 stream for reading Не удалось открыть поток bzip2 для чтения - + Internal error (open for neither read nor write) Внутренняя ошибка (не открывается ни на чтение, ни на запись) - + File not open Файл не открыт - + bzip2 stream write close error Ошибка закрытия записи в поток bzip2 - + bzip2 stream read close error Ошибка закрытия чтения потока bzip2 - + Internal error (close for neither read nor write) Внутренняя ошибка (не закрывается ни чтение, ни запись) - + bzip2 stream read error Ошибка чтения потока bzip2 @@ -212,8 +248,7 @@ CSVFileWriter - - + Failed to open file %1 for writing Не удалось открыть файл %1 для записи @@ -362,7 +397,7 @@ Colour3DPlotLayer - + Time: %1 - %2 Bin: %3 Value: %4 @@ -371,111 +406,153 @@ Значение: %4 - - + + Linear Линейный - + <unknown> <неизвестно> - - + + Colour Цвет - - + + Scale Масштаб - Normalize Columns - Нормализовать столбцы - - - + Нормализовать столбцы + + Normalize Visible Area - Нормализовать видимую область - - - - + Нормализовать видимую область + + + + Log Логарифмический - + +/-1 ±1 - + Invert Vertical Scale Инвертировать масштаб по вертикали - + Always Opaque Всегда непрозрачно - + Absolute Абсолютный - + Gain - Усиление - - - + Усиление + + + + Normalization + + + + Smooth - + Bin Scale - + Bins Бины - + + None + + + + + Col + + + + + View + + + + + Hybrid + + + + dB Дб + ColourComboBox + + + Name New Colour + Дайте цвету название + + + + Enter a name for the new colour: + Введите название нового цвета: + + + + Prefer black background for this colour + Предпочитать черный фон для этого цвета + + + + Add New Colour... + Добавить новый цвет... + + + ColourMapper - - <unknown> - <неизвестно> + <неизвестно> Default По умолчанию - White on Black - Белое на чёрном - - - + Белое на чёрном + + Black on White - Чёрное на белом + Чёрное на белом Red on Blue @@ -490,54 +567,28 @@ Синее на чёрном - Green - Зелёный - - - - Cherry - - - - - Wasp - - - - - Ice - - - - + Зелёный + + Sunset - Закат - - - + Закат + + Fruit Salad - Фруктовый салат - - - + Фруктовый салат + + Banded - В полоску - - - + В полоску + + Highlight - Подсветка - - - + Подсветка + + Printer - Принтер - - - - High Gain - + Принтер @@ -619,7 +670,7 @@ DecodingWavFileReader - + Decoding %1... Декодируется %1... @@ -627,7 +678,7 @@ Dense3DModelPeakCache - + Dense 3-D Peak Cache @@ -635,17 +686,17 @@ DenseThreeDimensionalModel - + Dense 3-D - + Time Время - + Frame Выборка @@ -653,7 +704,7 @@ DenseTimeValueModel - + Dense Time-Value @@ -661,12 +712,12 @@ Document - + Set main model to %1 Сделать %1 основной моделью - + Clear main model Очистить основную модель @@ -674,7 +725,7 @@ EditableDenseThreeDimensionalModel - + Editable Dense 3-D @@ -682,12 +733,12 @@ FFTModel - + %1 Hz %1 Гц - + FFT FFT @@ -718,68 +769,68 @@ FeatureExtractionModelTransformer - + Transforms supplied to a single FeatureExtractionModelTransformer instance must be similar in every respect except plugin output - + No factory available for feature extraction plugin id "%1" (unknown plugin type, or internal error?) - + Input model for feature extraction plugin "%1" is of wrong type (internal error?) - + Failed to instantiate plugin "%1" - + Cannot provide enough channels to feature extraction plugin "%1" (plugin min is %2, max %3; input model has %4) - - + + Failed to initialise feature extraction plugin "%1" - + Feature extraction plugin "%1" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead - + Transform was configured for version %1 of plugin "%2", but the plugin being used is version %3 - + Plugin "%1" has no outputs - У расширения "%1" нет выходов - - - + У плагина "%1" нет выходов + + + Plugin "%1" has no output named "%2" - У расширения "%1" нет выхода с названием "%2" + У плагина "%1" нет выхода с названием "%2" FileSource - - - + + + Unsupported scheme in URL Неподдерживаемая схема URL - + Downloading %1... Скачивается %1... @@ -800,17 +851,17 @@ Скачивание с FTP-сервера прервано - + Download cancelled Скачивание отменено - + Failed to create local file %1 Не удалось создать локальный файл %1 - + File contains no data! Файл не содержит данных! @@ -818,75 +869,75 @@ FlexiNoteLayer - - - + + + New Point Новая точка - + Vertical Scale Верт. масштаб - + Scale Units Единицы шкалы - + Scale - - - - + Масштаб + + + Auto-Align - Автовыравнивание - - - + Автовыравнивание + + + Linear - Линейный - - - + Линейный + + + Log - - - - + Логарифмический + + + MIDI Notes Ноты MIDI - + In progress В процессе - - + + No local points Нет локальных точек - + %1 (%2, %3 Hz) %1 (%2, %3 Гц) - + %1 Hz (%2, %3) %1Гц (%2, %3) - + %1 %2 %1 %2 - + Time: %1 Pitch: %2 Duration: %3 @@ -897,7 +948,7 @@ Без метки - + Time: %1 Pitch: %2 Duration: %3 @@ -908,85 +959,85 @@ Метка: %4 - + Draw Point Нарисовать точку - + Erase Point - + Drag Point Перетащить точку - - - + + + Edit Point Изменить точку - + Relocate Point Переместить точку - + Change Point Value Изменить значение точки - + Add Point Добавить точку - + Snap Notes - + Merge Notes - + Drag Selection - + Resize Selection - - + + Delete Selected Points Удалить выбранные точки - + Re-align pasted items? Заново выровнять вставленные объекты? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste Вставить - + Record FlexiNote @@ -1001,7 +1052,7 @@ Time - Время + Время @@ -1011,32 +1062,32 @@ Pitch - Высота тона + Высота тона Duration - Длительность + Длительность Level - Уровень + Уровень Label - Метка + Метка Unknown - + Неизвестно Edit Data - Изменить данные + Изменить данные @@ -1202,21 +1253,21 @@ InteractiveFileFinder - + Select file Выберите файл - + All files (*.*) Все файлы (*.*) - + Select a session file - Выберите файл сеанса + Выберите файл сессии Sonic Visualiser session files (*.sv) @@ -1303,54 +1354,54 @@ Все файлы (*.*) - + File does not exist Файл не существует - + <b>File not found</b><p>File "%1" does not exist <b>Файл не найден</b><p>Файл "%1" не существует - + File is not readable Файл нечитаем - + <b>File is not readable</b><p>File "%1" can not be read <b>Файл нечитаем</b><p>Файл "%1" не может быть прочитан - - + + Directory selected Выбран каталог - - + + <b>Directory selected</b><p>File "%1" is a directory <b>Выбран каталог</b><p>Файл "%1" является каталогом - + Non-file selected Выбран не файл - + <b>Not a file</b><p>Path "%1" is not a file <b>Это не файл</b><p>Путь "%1" не является файлом - + File is empty Файл пуст - + <b>File is empty</b><p>File "%1" is empty <b>Пустой файл</b><p>Файл "%1" пуст @@ -1397,10 +1448,22 @@ Audio files (%2) RDF files (%1) All files (*.*) - + Все поддерживаемые типы файлов (*.sv %1 %2) +Файлы сессий %3 (*.%4) +Звуковые файлы (%2) +Файлы RDF (%1) +Все файлы (*.*) + + Scalable Vector Graphics files (*.svg) +All files (*.*) + Файлы Scalable Vector Graphics (*.svg) +Все файлы (*.*) + + + Comma-separated data files (*.csv) Space-separated .lab files (*.lab) Text files (*.txt) @@ -1408,7 +1471,7 @@ - + All supported files (*.sv %1 %2 %3) %4 session files (*.%5) Audio files (%1) @@ -1418,31 +1481,32 @@ - + %1 session files (*.%2) All files (*.*) - - - - - - - + + + + + + + + Select a file to export to Выберите файл, в который экспортировать - + WAV audio files (*.wav) All files (*.*) Звуковые файлы WAV (*.wav) Все файлы (*.*) - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1457,7 +1521,7 @@ Все файлы (*.*) - + Sonic Visualiser Layer XML files (*.svl) Comma-separated data files (*.csv) RDF/Turtle files (%1) @@ -1470,7 +1534,7 @@ Все файлы (*.*) - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1480,7 +1544,7 @@ - + Comma-separated data files (*.csv) Sonic Visualiser Layer XML files (*.svl) RDF/Turtle files (%1) @@ -1489,82 +1553,82 @@ - + Portable Network Graphics files (*.png) All files (*.*) Файлы Portable Network Graphics (*.png) Все файлы (*.*) - + Comma-separated data files (*.csv) Text files (*.txt) All files (*.*) - + File exists Такой файл уже существует - + <b>File exists</b><p>The file "%1" already exists. Do you want to overwrite it? <b>Файл существует</b>Файл "%1" уже существует. Вы хотите перезаписать его? - + <b>File not found</b><p>Audio file "%1" could not be opened. Do you want to locate it? <b>Файл не найден</b><p>Не удалось открыть звуковой файл "%1". Вы хотите указать его программе? - + <b>File not found</b><p>File "%1" could not be opened. Do you want to locate it? <b>Файл не найден</b><p>Не удалось открыть файл "%1". Вы хотите указать его программе? - + Failed to open file Не удалось открыть файл - + Locate file... Указать файл... - + Use URL... Использовать URL... - + Cancel Отменить - + Use URL Использовать URL - + Please enter the URL to use for this file: Укажите URL, который будет использоваться для этого файла: - + Failed to open location Не удалось открыть местоположение - + <b>Failed to open location</b><p>URL "%1" could not be opened <b>Не удалось открыть местоположение</b><p>Не удалось открыть URL "%1". @@ -1752,6 +1816,7 @@ + %1.%2 %1.%2 @@ -1761,10 +1826,20 @@ %1 - + Label Points + + + Subdivide Points + + + + + Winnow Points + + Layer @@ -1911,6 +1986,22 @@ + LevelPanToolButton + + + Click to adjust level and pan + + + + + LevelPanWidget + + + Drag vertically to adjust level, horizontally to adjust pan + + + + MIDIFileImportDialog @@ -2031,7 +2122,7 @@ MIDIInput - + Input Вход @@ -2039,7 +2130,7 @@ MP3FileReader - + Decoding %1... Декодируется %1... @@ -2051,29 +2142,29 @@ Sonic Visualiser - - - + + + &Layer С&лой - + &File &Файл - + File Toolbar Панель файлов - + &New Session - &Создать сеанс - - - + &Создать сессию + + + Ctrl+N Ctrl+N @@ -2082,7 +2173,7 @@ &Открыть сеанс... - + Ctrl+O Ctrl+O @@ -2091,22 +2182,22 @@ Открыть файл сохранённого ранее сеанса Sonic Visualiser - + &Open... О&ткрыть... - + Open a session file, audio file, or layer - Открыть файл сеанса, звуковой файл или слой - - - + Открыть файл сессии, звуковой файл или слой + + + &Save Session - Сохр&анить сеанс - - - + Сохр&анить сессию + + + Ctrl+S Ctrl+S @@ -2115,7 +2206,7 @@ Сохранить в файл текущий сеанс Sonic Visualiser - + Save Session &As... Сохранить сеанс &как... @@ -2128,7 +2219,7 @@ &Импортировать звуковой файл... - + Ctrl+I Ctrl+I @@ -2149,27 +2240,27 @@ Импортировать ещё один звуковой файл в отдельный слой - + &Export Audio File... Э&кспортировать звуковой файл... - + Export selection as an audio file Экспортировать выделенное в звуковой файл - + Import Annotation &Layer... И&мпортировать слой аннотаций... - + Ctrl+L Ctrl+L - + Import layer data from an existing file Импортировать данные слоя из существующего файла @@ -2178,534 +2269,574 @@ Экспортировать слой аннотаций... - + Export layer data to a file Экспортировать данные слоя в файл - + &Quit В&ыход - + Ctrl+Q Ctrl+Q - + &Edit &Правка - + Cu&t &Вырезать - + Ctrl+X Ctrl+X - + &Copy С&копировать - + Ctrl+C Ctrl+C - + &Paste Вст&авить - + Ctrl+V Ctrl+V - - + + &Delete Selected Items &Удалить выбранное - + Del Del - + Select &All В&ыделить всё - + Ctrl+A Ctrl+A - + Select &Visible Range Вы&делить всё видимое - + Ctrl+Shift+A Ctrl+Shift+A - + Select to &Start Выделить до &начала - - - - + + + + Shift+Left Shift+Left - + Select to &End Выделить до &конца - + Shift+Right Shift+Right - + C&lear Selection Сн&ять выделение - + Esc Esc - + &Insert Instant at Playback Position Вставить &отметку в точку воспроизведения - + Enter Enter - + &View &Вид - + 0 0 - + 9 9 - + 8 8 - + Scroll &Left Прокрутить в&лево - + Playback Speed - - - - + Скорость воспроизведения + + + Abandon the current %1 session and start a new one - + Replace &Main Audio... - - - - + &Заменить основной аудиофайл… + + + Replace the main audio file of the session with a different file - + Save the current session into a %1 session file - + Save the current session into a new %1 session file - + Export Audio Data... - - - - + Экспортировать звуковые данные… + + + Export Annotation La&yer... - - - - + Экспортировать слой &аннотаций… + + + Ctrl+Y - - - - + Ctrl+Y + + + + Export SVG File... + Экспортировать файл SVG… + + + + Export a single pane to a scalable SVG image file + + + + Browse Recorded Audio Folder - - - - + Открыть папку с записанными аудиофайлами + + + Open the Recorded Audio folder in the system file browser - + Exit %1 - - - - + Завершить работу с %1 + + + + Shift+; + + + + + Ctrl+Shift+; + + + + Ctrl+Shift+Return - + Reset Numbering Counters - - - - + Сбросить счётчики нумерации + + + Reset to 1 all the counters used for counter-based labelling - - - - - - - + + Subdivide Selected Instants... + + + + + Add new instants at regular intervals between the selected instants + + + + + Winnow Selected Instants... + + + + + Remove subdivisions, leaving only every Nth instant + + + + + + + + + + Left Влево - + Scroll the current pane to the left Прокрутить активное окно влево - + Scroll &Right Прокрутить в&право - + Right Вправо - + Scroll the current pane to the right Прокрутить активное окно вправо - - - + + + Ctrl+Left Ctrl+Влево - + Scroll the current pane a big step to the left Сделать большой шаг прокрутки влево - + Ctrl+Right Ctrl+Вправо - + Scroll the current pane a big step to the right Сделать большой шаг прокрутки вправо - + Zoom &In При&близить - + Up Вверх - + Increase the zoom level Увеличить масштаб отображения - + Zoom &Out &Отдалить - + Down Вниз - + Decrease the zoom level Уменьшить масштаб отображения - + Restore &Default Zoom &Восстановить обычный масштаб - + Zoom to &Fit &Уместить в окне - + Zoom to show the whole file Увидеть весь файл - + Show &Centre Line - - - - + Показывать &центральную линию + + + ' - + Show or hide the centre line - + Toggle All Time Rulers - - - - + Переключить видимость всех линеек + + + Hide times, layer names, and scale - + Show times and basic scale - + Show times, layer names, and scale - + Show &Unit Converter - - - - + Показать конвертер &единиц + + + Open a window of pitch and timing conversion utilities - + Go Full-Screen - - - - + Полноэкранный режим + + + F11 - F11 - - - + F11 + + + Expand the pane area to the whole screen - + &Pane &Окно - + Add &New Pane Добавить &новое окно - + Add a new pane containing only a time ruler Добавить новое окно, содержащее только линейку времени - + Add New %1 Layer Добавить новый слой «%1» - + Add a new empty layer of type %1 Добавить новый пустой слой типа «%1» - + Add &Waveform Добавить &волновую форму - + Add a new pane showing a waveform view Добавить новое окно с видом волновой формы - + Add a new layer showing a waveform view Добавить новый слой с видом волновой формы - + Add &Melodic Range Spectrogram Добавить спектограмму &мелодического диапазона - + Add a new pane showing a spectrogram set up for tracking frequencies Добавить новое окно, отображающее спектрограмму для отслеживания частот - + Add a new layer showing a spectrogram set up for tracking frequencies Добавить новый слой, отображающий спектрограмму для отслеживания частот - + &All Channels Mixed Все &каналы сведены - + &All Channels &Все каналы - + Channel &%1 Канал &%1 - + &Delete Pane У&далить окно - + Add &Time Ruler Добавить линейку &времени - + Add a new layer showing a time ruler Добавить новый слой с линейкой - + Add &Existing Layer Добавить &существующий слой - + Switch to Previous Layer - - - - + Переключиться на предыдущий слой + + + { - - - - + { + + + Make the previous layer in the pane current - + Switch to Next Layer - - - - + Переключиться на следующий слой + + + } - - - - + } + + + Make the next layer in the pane current - + &Rename Layer... &Переименовать слой... - + Rename the currently active layer Переименовать активный слой - + &Delete Layer &Удалить слой - + Delete the currently active layer Удалить активный слой - + &Help &Справка - + &Help Reference &Руководство пользователя @@ -2730,224 +2861,226 @@ Показать информацию о Sonic Visualiser - + Rewind to Start Перемотать в начало - + Home Домой - + Rewind to the start Перемотать в начало - - - + + + Rewind Перемотать назад - + Rewind to the previous time instant in the current layer Перемотать до предыдущей отметки времени в текущем слое - + Play / Pause Воспроизвести / Приостановить - + Space - Пробел - - - + This text is a shortcut label referring to the space-bar on the keyboard. It probably should not be translated, and certainly should not be translated as if referring to an empty void or to the extra-terrestrial universe. + + + + Start or stop playback from the current position Запустить или остановить воспроизведение с текущей позиции - - + + Fast Forward Перемотать вперёд - + Fast forward to the next time instant in the current layer Перемотать до следующей отметки времени в текущем слое - + Fast Forward to End Перемотать до конца - + Open a window showing the keystrokes you can use in %1 - + %1 on the &Web - - - - + %1 в &Интернете + + + Open the %1 website - + &About %1 - - - - + &О %1 + + + Show information about %1 - - - - + Показать информацию о %1 + + + End Конец - + Fast-forward to the end Перемотать до конца - + Play Mode Toolbar Панель режима воспроизведения - + Constrain Playback to Selection Ограничить воспроизведение выделением - + s с - + Loop Playback Воспроизведение в цикле - + l l - + Loop playback Воспроизведение в цикле - + Edit Toolbar Панель правки - + Tools Toolbar Панель инструментов - - - + + + Navigate Перемещение - + 1 1 - - + + Select Выделение - + 2 2 - - - + + + Edit Правка - + 3 3 - - + + Draw Рисование - + 4 4 - + No audio file loaded. Ни один звуковой файл не загружен. - + %1Hz (resampling to %2Hz) %1 Гц (ресэмплирование до %2 Гц) - - - - - - - + + + + + + + Failed to open file Не удалось открыть файл - + Export the selected region only Экспортировать только выделенную область - + Export the whole audio file Экспортировать весь звуковой файл - - - + + + + Select region to export Выделите область для экспорта - + Which region from the original audio file do you want to export? Какую область исходного звукового файла вы хотите экспортировать? @@ -2956,30 +3089,30 @@ Экспортировать выделенные области в один звуковой файл - + Export the selected regions into separate files Экспортировать выделенные области в разные звуковые файлы - + Multiple regions of the original audio file are selected. What do you want to export? Выбрано несколько областей исходного звукового файла. Какую из них вы хотите экспортировать? - + Fragment file %1 already exists, aborting Файл фрагмента %1 уже существует, прерывание - - + + Failed to write file Не удалось записать файл - + Failed to open file %1 for writing Не удалось открыть файл %1 для записи @@ -2988,100 +3121,99 @@ Sonic Visualiser: %1 - + Session modified - Сеанс изменен - - - - + Сессия изменена + + + + Failed to save file Не удалось сохранить файл - + Rename Layer Переименовать слой - + New name for this layer: Новое имя этого слоя: - + Sample rate mismatch Несоответствие частоты дискретизации - - + + Failed to regenerate layer Не удалось повторно создать слой - + http://www.sonicvisualiser.org/ http://www.sonicvisualiser.org/ - + Release %1 : Revision %2 Версия %1 : Редакция %2 - + Release %1 Версия %1 - + Unreleased : Revision %1 Не выпущено : редакция %1 - + <h3>About Sonic Visualiser</h3> <h3>О программе Sonic Visualiser</h3> - + Debug Отладка - + Release Версия - + <br>With Ogg file decoder (oggz v%1, fishsound v%2) &copy; CSIRO Australia <br>С декодером Ogg (oggz v%1, fishsound v%2) &copy; CSIRO Australia - + <br>With LADSPA plugin support (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld - <br>С поддержкой расширений LADSPA (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld - - - + <br>С поддержкой плагинов LADSPA (API v%1) &copy; Richard Furse, Paul Davis, Stefan Westerfeld + + + <br>With DSSI plugin support (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton - <br>С поддержкой расширений DSSI (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton - - - + <br>С поддержкой плагинов DSSI (API v%1) &copy; Chris Cannam, Steve Harris, Sean Bolton + + About Sonic Visualiser - О программе Sonic Visualiser - - - - + О программе Sonic Visualiser + + + + Failed to generate layer Не удалось создать слой - + Adjust the application preferences Изменить параметры работы приложения @@ -3090,75 +3222,75 @@ Н&едавние файлы - + &Preferences... &Параметры... - + ; ; - + Show &Zoom Wheels Показывать &колёса масштабирования - + Z Z - + Show thumbwheels for zooming horizontally and vertically Показывать колёса для масштабирования по горизонтали и вертикали - + %1 by Category %1 по категории - - + + Unclassified Неклассифицированные - + %1 by Maker %1 по имени создателя - - + + Unknown Неизвестен - + %1 by Plugin Name - %1 по названию расширения - - - - + %1 по названию плагина + + + + %1... %1... - + Add Spectr&um Добавить &график спектральной функции - + Add a new pane showing a frequency spectrum Добавить новое окно с частотой спектра - + Add a new layer showing a frequency spectrum Добавить новый слой с частотой спектра @@ -3167,51 +3299,51 @@ Ускорение воспроизведения - - + + &Transform Пр&еобразования - - + + %1: %2 %1: %2 - + &Recent Transforms &Недавние преобразования - - + + [\(<].*$ [\(<].*$ - - + + Audio processing overload Перегрузка в обработке звука - + Show Property Bo&xes Показывать панели с&войств - + X X - + Show the layer property boxes at the side of the main window Показывать панели свойств слоёв сбоку от основного окна - + Add %1 Pane Добавить окно %1 @@ -3220,17 +3352,17 @@ Отказаться от текущего сеанса Sonic Visualiser и начать новый - + Open Lo&cation... Открыть &местоположение... - + Ctrl+Shift+O Ctrl+Shift+O - + Open or import a file from a remote URL Открыть или импортировать файл с удалённого узла @@ -3239,77 +3371,77 @@ Завершить работу с Sonic Visualiser - + Cut the selection from the current layer to the clipboard Вырезать выделение из активного слоя в буфер обмена - + Copy the selection from the current layer to the clipboard Скопировать выделение из активного слоя в буфер обмена - + Paste from the clipboard to the current layer Вставить содержимое буфера обмена в активный слой - + Select the whole duration of the current session Выбрать данные по всей длительности активнонр сеанса - + Select the time range corresponding to the current window width Сделать временной диапазон равным активной ширине окна - + Select from the start of the session to the current playback position - Выделить от начала сеанса до текущей точки воспроизведения - - - + Выделить от начала сессии до текущей точки воспроизведения + + + Select from the current playback position to the end of the session - Выделить от текущей точки воспроизведения до конца сеанса - - - + Выделить от текущей точки воспроизведения до конца сессии + + + Clear the selection Очистить выделение - + Insert a new time instant at the current playback position, in a new layer if necessary Вставить новую отметку времени в точку воспроизведения, при необходимости — в новый слой - + Insert Instants at Selection &Boundaries Вставить отметки времени по &краям выделения - + Shift+Enter Shift+Enter - + &Jump Left Перескочить в&лево - + J&ump Right П&ерескочить вправо - + Restore the zoom level to the default Восстановить обычный масштаб отображения - + Show &No Overlays Не по&казывать перекрытия совсем @@ -3318,7 +3450,7 @@ Спрятать индикацию центра, времён выделения, имена слоёв и масштаб - + Show &Minimal Overlays Показывать &минимум перекрытий @@ -3335,7 +3467,7 @@ Показывать индикатор центра, времена выделений, имена слоёв и масштаб - + Show &All Overlays Показывать в&се перекрытия @@ -3348,600 +3480,602 @@ Показывать весь текст и масштаб - + Show Status &Bar Показывать статусную &строку - + Show context help information in the status bar at the bottom of the window Показывать контекстную справку в статусной строке, находящейся внизу окна программы - + Add a new pane showing a spectrogram Добавить новое окно с отображением спектрограммы - + Add a new layer showing a spectrogram Добавить новый слой с отображением спектрограммы - + Add a new pane showing a spectrogram set up for an overview of note pitches Добавить новое окно, отображающее спектрограмму для обзора высоты тона нот - + Add a new layer showing a spectrogram set up for an overview of note pitches Добавить новый слой, отображающий спектрограмму для обзора высоты тона нот - + Delete the currently active pane Удалить активное окно - + Add S&lice of Layer Добавить &фрагмент слоя - + + What's &New? + &Что нового? + + + + Show changes in this release of %1 + Показать изменения в этой версии %1 + + + Select ranges Выбрать диапазон - + Edit items in layer Изменить объекты слоя - + Draw new items in layer Нарисовать новые объекты в слое - + Open Location Открыть местоположение - + Please enter the URL of the location to open: Введите URL открываемого местоположения: - - - - + + + + Failed to open location Не удалось открыть местоположение - + Multiplex all of the above - + Playback speed: %1% (%2x slower) - - - - + Скорость воспроизведения: %1% (в %2 раза медленнее) + + + Playback speed: %1% (%2x faster) - - - - + Скорость воспроизведения: %1% (в %2 раза быстрее) + + + Visible: %1 to %2 (duration %3) Видимая область: от %1 до %2 (длительность %3) - + Problems loading plugins - + <b>Layer generation failed</b><p>Failed to generate derived layer.<p>The layer transform %1failed:<p>%2 - + <b>Layer generation failed</b><p>Failed to generate a derived layer.<p>The layer transform %1failed.<p>No error information is available. - Adjust the master playback level - Изменить общую громкость воспроизведения - - - + Изменить общую громкость воспроизведения + + + Adjust the master playback speed Изменить общую скорость воспроизведения - + <br>With Ogg file decoder &copy; CSIRO Australia <br>С декодером Ogg &copy; CSIRO Australia - + <br>With MAD mp3 decoder &copy; Underbit Technologies Inc <br>С декодером MAD mp3 &copy; Underbit Technologies Inc - + <br>With libsamplerate &copy; Erik de Castro Lopo <br>С libsamplerate &copy; Erik de Castro Lopo - + <br>With libsndfile &copy; Erik de Castro Lopo <br>С libsndfile &copy; Erik de Castro Lopo - + <br>With FFTW3 &copy; Matteo Frigo and MIT <br>С FFTW3 &copy; Matteo Frigo и MIT - <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam - <br>С поддержкой расширений Vamp (API v%1, host SDK v%2) &copy; Chris Cannam - - - + <br>С поддержкой расширений Vamp (API v%1, host SDK v%2) &copy; Chris Cannam + + + <br>With Serd and Sord RDF parser and store &copy; David Robillard - - <br>With Dataquay Qt/RDF library &copy; Chris Cannam - - - - + <br>With liblo Lite OSC library &copy; Steve Harris <br>С liblo Lite OSC library &copy; Steve Harris - + Export Image File... Экспортировать в файл изображения... - + Export a single pane to an image file Экспортировать всё окно в файл изображения - + Export the whole pane (%1x%2 pixels) Экспортировать всё окно (%1x%2 пикселов) - + Export the visible area only (%1x%2 pixels) Экспортировать только видимую часть (%1x%2 пикселов) - + Export the selection extent (%1x%2 pixels) Экспортировать выделение (%1x%2 пикселов) - + + Export the selection extent Экспортировать выделение - + Which region of the current pane do you want to export as an image? Какую область текущего окна вы хотите экспортировать как изображение? - + Note: the whole pane is too wide to be exported as a single image. Примечание: всё окно слишком широко, чтобы сохранить его как изображение. - + Failed to save image file Не удалось сохранить файл изображения - + Failed to save image file %1 Не удалось сохранить файл изображения %1 - + Selection: %1 to %2 (duration %3) Выделение: %1 до %2 (длительность %3) - + Black Чёрный - + Red Красный - + Blue Синий - - - + + Green Зелёный - + Purple Пурпурный - + Orange Оранжевый - + White Белый - + Bright Red Ярко-красный - + Bright Blue Ярко-синий - - - + + Bright Green Ярко-зелёный - + Bright Purple Ярко-пурпурный - + Bright Orange Ярко-оранжевый - + File and Session Management - Файлы и управление сеансами - - - + Файлы и управление сессиями + + + &Import More Audio... - - - - + &Импортировать ещё аудиофайл… + + + Import an extra audio file into a new pane - - - - + Открыть дополнительный аудиофайл в новой панели + + + Open &Recent - - - - + Открыть &недавний + + + Export audio from selection into a data file - + Apply Session Template - - - - + Применить шаблон сессии + + + Export Session as Template... - - - - + Экспортировать сессию как шаблон… + + + Manage Exported Templates - - - - + Открыть папку с шаблонами + + + Editing Редактирование - + Paste at Playback Position - - - - + Вставить под курсор воспроизведения + + + Ctrl+Shift+V - - - - + Ctrl+Shift+V + + + Paste from the clipboard to the current layer, placing the first item at the playback position - - + + Delete items in current selection from the current layer Удалить объекты в активном выделении текущего слоя - + Selection Выделение - + Tapping Time Instants - + Insert new time instants at the start and end of the current selected regions, in a new layer if necessary - + Number New Instants with Способ нумерации новых отметок - + Cycle size Размер цикла - + Set Numbering Counters... Установить счетчики нумерации... - + Set the counters used for counter-based labelling Устанолвить счетчики для меток на основе подсчета - + Renumber Selected Instants Перенумеровать выбранные отметки - + Renumber the selected instants using the current labelling scheme - + Panning and Navigation Прокрутка и перемещение - + Zoom Масштаб просмотра - + F F - + Display Features Отображение элементов - + # - + Show or hide all time rulers - + Show La&yer Summary &Показать сводку по слою - + Y Y - + Open a window displaying the hierarchy of panes and layers in this session - Открыть окно, в котором отобразится иерархия окон и слоев активного сеанса - - - + Открыть окно, в котором отобразится иерархия окон и слоев активной сессии + + + Managing Panes and Layers Управление окнами и слоями - + N N - + T T - + W W - + Shift+W - + Add Spectro&gram Добавить &спектограмму - + G G - + Shift+G - + M M - + Shift+M - + Add Pea&k Frequency Spectrogram Добавить спектограмму &пиковой частоты - + K K - + Shift+K - + U U - + Shift+U - + Switch to Previous Pane Перейти к предыдущему окну - + [ [ - + Make the next pane up in the pane stack current - + Switch to Next Pane Перейти к следующему окну - + ] ] - + Make the next pane down in the pane stack current - + Ctrl+Shift+D Ctrl+Shift+D - + R R - + Edit Layer Data Изменить данные слоя - + E E - + Edit the currently active layer as a data grid Изменить активный слой как сетку данных - + Ctrl+D Ctrl+D - + Help Справка - + F1 F1 - + Open the %1 reference manual - + &Key and Mouse Reference &Использование клавиатуры и мыши - + F2 F2 @@ -3950,512 +4084,637 @@ Открыть окно, в котором перечисляются клавиатурные комбинации Sonic Visualiser - + Ctrl+R Ctrl+R - + Re-open Повторно открыть - + Re-open the current or most recently opened file Повторно открыть активный или недавно открывавшийся файл - + Standard Waveform - - - - + Обычная волновая форма сигнала + + + Choose Default Template... - - - - + Выбрать шаблон по умолчанию… + + + Ctrl+T Ctrl+T - + Repeat Transform Повторить преобразование - + Re-select the most recently run transform Повторно запустить самое последнее выполнявшееся преобразование - + Playback and Transport Controls Управление воспроизведением и перемоткой - + Play&back Воспро&изведение - + Playback Воспроизведение - + Playback Toolbar Панель воспроизведения - + PgUp PgUp - + Rewind to the previous time instant or time ruler notch - + PgDown PgDown - + Fast-forward to the next time instant or time ruler notch - + Record - - - - + Записать + + + Ctrl+Space - + Record a new audio file - + Constrain playback to the selected regions - + Solo Current Pane Соло активного окна - + o o - + Solo the current pane during playback При воспроизведении звучит лишь активное окно - + Align File Timelines Выровнять линейки времени - + Treat multiple audio files as versions of the same work, and align their timelines - + Speed Up Ускорить - + Ctrl+PgUp Ctrl+PgUp - + Time-stretch playback to speed it up without changing pitch Сжать время воспроизведения, не меняя высоту тона - + Slow Down Замедлить - + Ctrl+PgDown Ctrl+PgDown - + Time-stretch playback to slow it down without changing pitch Расширить время воспроизведения, не меняя высоту тона - + Restore Normal Speed Восстановить обычную скорость - + Ctrl+Home Ctrl+Home - + Restore non-time-stretched playback Восстановить естественную скорость воспроизведения - - - - - - + + + + + + Tool Selection Выбор инструмента - + Navigate Tool Mouse Actions Использование мыши с инструментом навигации - + Click left button and drag to move around - - + + Zoom to Area Масштабировать в выделение - - + + Shift-click left button and drag to zoom to a rectangular area - + Relocate - Перемещение скачком - - - - - - + Переместить + + + + + + Double-Click Left Двойной щелчок левой клавишей - + Double-click left button to jump to clicked location - - + + Double-click left button on an item to edit it - + Select Tool Mouse Actions Использование мыши с инструментом выделения - + Click left button and drag to select region; drag region edge to resize - - + + Multi Select Множественное выделение - + Cmd-click left button and drag to select an additional region - + Ctrl-click left button and drag to select an additional region - + Fine Select Выделить точно - + Shift-click left button and drag to select without snapping to items or grid - + Edit Tool Mouse Actions Использование мыши с инструментом редактирования - + Move Переместить - + Click left button on an item or selected region and drag to move - + Draw Tool Mouse Actions Использование мыши с инструментом рисования - + Click left button and drag to create new item Щелкните левой клавишей мыши и перетащите курсор для создания нового объекта - - + + Erase Стерка - + 5 5 - + Erase items from layer Стирать объекты слоя - + Erase Tool Mouse Actions - + Click left button on an item to remove it from the layer - + Measure Измеритель - + 6 6 - + Make measurements in layer Выполнять измерения в слое - + Measure Tool Mouse Actions Использование мыши с инструментом измерения - + Measure Area Измерить область - + Click left button and drag to measure a rectangular area - + Measure Item Измерить объект - + Click left button and drag to measure extents of an item or shape - + &Delete Current Measurement &Удалить активный замер - + Delete the measurement currently under the mouse pointer Удалить замер, находящийся под курсором мыши - + Fast Forward to Next Instant - + Rewind to Previous Instant - + Fast Forward to Next Point - + Fast forward to the next point in the current layer - + Rewind to Previous Point - + Rewind to the previous point in the current layer - + Fast forward Быстрый вперед - - - + + + <b>File open failed</b><p>Audio file "%1" could not be opened <b>Не удалось открыть файл</b><p>Не удалось открыть звуковой файл "%1" - + Export the selected regions into a single file - + Export the whole file - + <b>File open failed</b><p>Layer file %1 could not be opened. <b>Не удалось открыть файл</b><p>Не удалось открыть файл слоя "%1" - + Can't export non-note layers to MIDI Невозможно экспортировать ненотные слои в MIDI - + Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values) - + + Export the whole pane + + + + + Export the visible area only + + + + + Which region of the current pane do you want to export as a scalable SVG image? + + + + + Failed to save SVG file + + + + + Failed to save SVG file %1 + + + + + Failed to query transform attributes + + + + + <b>Failed to query transform attributes</b><p>Plugin or server error: %1</p> + + + + + Multiplexed audio + + + + + Transform failed + + + + + <b>Failed to run transform</b><p>Plugin or server error: %1</p> + + + + + Subdivide instants + + + + + Number of subdivisions: + + + + + Winnow instants + + + + + Remove all instants apart from multiples of: + + + + + <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment:<p>%1 + + + + + Adjust the master playback level and pan + + + + + With Qt v%1 &copy; The Qt Company + + + + + <br>With Rubber Band Library v%1 &copy; Particular Programs Ltd + + + + + <br>With Rubber Band Library &copy; Particular Programs Ltd + + + + + <br>With Vamp plugin support (API v%1, host SDK v%2) &copy; Chris Cannam and QMUL + <br>С поддержкой плагинов Vamp (API v%1, host SDK v%2) &copy; Chris Cannam и QMUL + + + + <br>With Piper Vamp protocol bridge &copy; QMUL + + + + + <br>With Dataquay Qt/RDF library &copy; Particular Programs Ltd + + + + + <br>With Cap'n Proto serialisation &copy; Sandstorm Development Group + + + + + Russian UI translation contributed by Alexandre Prokoudine. + + + + + Czech UI translation contributed by Pavel Fric. + + + + <h3>Newer version available</h3><p>You are using version %1 of Sonic Visualiser, but version %2 is now available.</p><p>Please see the <a href="http://sonicvisualiser.org/">Sonic Visualiser website</a> for more information.</p> - <h3>Доступна более новая версия</h3><p>Вы используетее Sonic Visualiser версии %1, но уже доступна версия %3.</p><p>Загляните на <a href="http://sonicvisualiser.org/">сайт Sonic Visualiser</a> за подробностями.</p> {3>?} {3>?} {1 ?} {2 ?} + <h3>Доступна новая версия программы</h3><p>Вы используетее Sonic Visualiser версии %1, но уже доступна версия %2.</p><p>Загляните на <a href="http://sonicvisualiser.org/">сайт Sonic Visualiser</a>, чтобы узнать подробности.</p> {3>?} {3>?} {1 ?} {2 ?} <b>File open failed</b><p>Session file "%1" could not be opened <b>Не удалось открыть файл</b><p>Не удалось открыть файл сеанса "%1" - + <b>File open failed</b><p>File "%1" could not be opened <b>Не удалось открыть файл</b><p>Не удалось открыть файл "%1" - + <b>Open failed</b><p>URL "%1" could not be opened <b>Не удалось открыть ссылку</b><p>Не удалось открыть URL "%1" - + <b>Open failed</b><p>File or URL "%1" could not be opened <b>Не удалось открыть ссылку</b><p>Не удалось открыть файл или URL "%1" - + Enter template name - - - - + Введите название шаблона + + + Please enter a name for the saved template: - + Set as default template for future audio files - + Template file exists - + <b>Template file exists</b><p>The template "%1" already exists.<br>Overwrite it? - - + + Failed to open dropped URL Не удалось открыть URL, перемещенный мышью в окно программы - + <b>Open failed</b><p>Dropped URL "%1" could not be opened <b>Не удалось открыть ссылку</b><p>Не удалось открыть файл URL "%1", перетащенный в окно программы мышью - + <b>Session modified</b><p>The current session has been modified.<br>Do you want to save it? <b>Сеанс изменился</b><p>Активный сеанс изменился<br>Вы хотите сохранить его? - - + + <b>Save failed</b><p>Session file "%1" could not be saved. - <b>Не удалось сохранить файл</b><p>Не удалось сохранить файл сеанса "%1" + <b>Не удалось сохранить файл</b><p>Не удалось сохранить файл сессии "%1" %1: %1 %1: %1 {1:?} - + Playback speed: Normal Скорость воспроизведения: обычная @@ -4464,141 +4723,132 @@ Скорость воспроизведения: %1%2% - + <b>Wrong sample rate</b><p>The sample rate of this audio file (%1 Hz) does not match the current playback rate (%2 Hz).<p>The file will play at the wrong speed and pitch.<p>Change the <i>Resample mismatching files on import</i> option under <i>File</i> -> <i>Preferences</i> if you want to alter this behaviour. - + <b>Overloaded</b><p>Audio effects plugin auditioning has been disabled due to a processing overload. - + Reset Counters Обнуление счетчиков - - + + Warning Предупреждение - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed:<p>%3 - + <b>Layer generation failed</b><p>Failed to regenerate derived layer "%1" using new data model as input.<p>The layer transform "%2" failed.<p>No error information is available. - + <b>Warning when regenerating layer</b><p>When regenerating the derived layer "%1" using new data model as input:<p>%2 - + Failed to calculate alignment Не удалось рассчитать выравнивание - - <b>Alignment calculation failed</b><p>Failed to calculate an audio alignment using transform "%1":<p>%2 - - - - + <br>With JACK audio output library &copy; Paul Davis and Jack O'Quin <br>С библиотекой JACK &copy; Paul Davis и Jack O'Quin - + <br>With PortAudio audio output library &copy; Ross Bencina and Phil Burk <br>С библиотекой PortAudio &copy; Ross Bencina и Phil Burk - + <br>With PulseAudio audio output library &copy; Lennart Poettering and Pierre Ossman <br>С библиотекой PulseAudio &copy; Lennart Poettering и Pierre Ossman - + <b>Overloaded</b><p>Audio playback speed processing has been reduced to a single channel, due to a processing overload. - <br>With Rubber Band &copy; Chris Cannam - <br>С Rubber Band &copy; Chris Cannam - - - + <br>С Rubber Band &copy; Chris Cannam + + + Find a Transform... Найти эффект трансформации... - + Search for a transform from the installed plugins, by name or description - Найти эффект трансформации среди установленных расширений по названию или описанию - - - + Найти эффект трансформации среди установленных плагинов по названию или описанию + + + Ctrl+M Ctrl+M - + <p>Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.<br><a href="http://www.sonicvisualiser.org/">http://www.sonicvisualiser.org/</a></p> <p>Sonic Visualiser — программа для просмотра и исследования звукозаписей с целью семантического анализа и аннотации музыки.<br><a href="http://www.sonicvisualiser.org/">http://www.sonicvisualiser.org/</a></p> - <p><small>%1 : %2 configuration</small></p> - <p><small>%1 : конфигурация %2</small></p> - - - + <p><small>%1 : конфигурация %2</small></p> + + With Qt v%1 &copy; Nokia Corporation - С использованием Qt v%1 &copy; Nokia Corporation - - - + С использованием Qt v%1 &copy; Nokia Corporation + + + <br>With JACK audio output library v%1 &copy; Paul Davis and Jack O'Quin <br>С библиотекой JACK v%1 &copy; Paul Davis и Jack O'Quin - + <br>With PulseAudio audio output library v%1 &copy; Lennart Poettering and Pierre Ossman <br>С библиотекой PulseAudio v%1 &copy; Lennart Poettering и Pierre Ossman - + <br>With MAD mp3 decoder v%1 &copy; Underbit Technologies Inc <br>С декодером mp3 MAD v%1 &copy; Underbit Technologies Inc - + <br>With libsamplerate v%1 &copy; Erik de Castro Lopo <br>С libsamplerate v%1 &copy; Erik de Castro Lopo - + <br>With libsndfile v%1 &copy; Erik de Castro Lopo <br>С libsndfile v%1 &copy; Erik de Castro Lopo - + <br>With FFTW3 v%1 &copy; Matteo Frigo and MIT <br>С FFTW3 v%1 &copy; Matteo Frigo и MIT - <br>With Rubber Band v%1 &copy; Chris Cannam - <br>С Rubber Band v%1 &copy; Chris Cannam + <br>С Rubber Band v%1 &copy; Chris Cannam <br>With Raptor RDF parser v%1 &copy; Dave Beckett and the University of Bristol @@ -4617,215 +4867,239 @@ <br>С движком запросов RDF Rasqal &copy; Dave Beckett и Бристольский университет - + <br>With Redland RDF datastore v%1 &copy; Dave Beckett and the University of Bristol <br>C хранилищем данных RDF Redland v%1 &copy; Dave Beckett и Бристольский университет - + <br>With Redland RDF datastore &copy; Dave Beckett and the University of Bristol <br>C хранилищем данных RDF Redland &copy; Dave Beckett и Бристольский университет - + <br>With liblo Lite OSC library v%1 &copy; Steve Harris <br>С библиотекой OSC liblo v%1 &copy; Steve Harris - + </small><p><small>The OSC URL for this instance is: "%1" - </small><p><small>Адрес OSC для этого сеанса: "%1" - - - + </small><p><small>Адрес OSC для этой сессии: "%1" + + With - С - - - + С + + Using - Используя - - - + Используя + + + Peek Left Глянуть влево - + Alt+Left Alt+влево - + Scroll the current pane to the left without moving the playback cursor or other panes - + Peek Right Глянуть вправо - + Alt+Right Alt+вправо - + Scroll the current pane to the right without moving the playback cursor or other panes - + Show Acti&vity Log Показать &журнал действий - + Open a window listing interactions and other events Открыть окно со списком всех действий в сеансе - + Export multiple audio files Экспортировать несколько звуковых файлов - + Export audio to "%1" Экспорт звука в "%1" - - - - - + + + + + <b>Audio required</b><p>Unable to load layer data from "%1" without an audio file.<br>Please load at least one audio file before importing annotations. - + Export layer to "%1" Экспорт слоя в "%1" - + Export image to "%1" Экспорт изображения в "%1" - + Close the current session and create a new one - + Add this data to the current session - Добавить эти данные в активный сеанс - - - + Добавить эти данные в активную сессию + + + Select target for import Выбрать цель для импорта - + <b>Select a target for import</b><p>This RDF document refers to one or more audio files.<br>You already have an audio waveform loaded.<br>What would you like to do with the new data? <b>Выберите цель импорта</b><p>Этот документ RDF ссылается на один или более звуковых файлов.<br>У вас уже есть один загруженный звуковой файл.<br>Что вы хотите сделать с новыми данными? - + Save session as "%1" - Сохранение сеанса как "%1" - - - + Сохранение сессию как "%1" + + + Add Point Добавить точку - + http://www.sonicvisualiser.org/doc/reference/%1/en/ http://www.sonicvisualiser.org/doc/reference/%1/en/ - + + What's New + Что нового в программе + + + + <h3>What's New in %1</h3> + <h3>Что нового в %1</h3> + + + + <b>Note:</b> A newer version of Sonic Visualiser is available.<br>(Version %1 is available; you are using version %2) + + + + + %1 : %2 configuration, %3-bit build + + + + <br>With RtMidi &copy; Gary P. Scavone <br>С RtMidi &copy; Gary P. Scavone - + Ctrl+Shift+S Ctrl+Shift+S - + Insert Item at Selection Вставить объект в выделение + Ctrl+Shift+Enter - Ctrl+Shift+Enter - - - + Ctrl+Shift+Enter + + + Insert a new note or region item corresponding to the current selection - + Rewind to Similar Point Назад к первой схожей точке - + Shift+PgUp Shift+PgUp - + Rewind to the previous similarly valued time instant - + Fast Forward to Similar Point Вперед к первой схожей точке - + Shift+PgDown Shift+PgDown - + Fast-forward to the next similarly valued time instant - + 1. %2 - 1. %2 - - - + 1. %2 + + + %1. %2 - %1. %2 - - - + %1. %2 + + + Select audio file to export Укажите экспортируемый звуковой файл - + Which audio file do you want to export from? Какой звуковой файл вы хотите экспортировать? - + + About %1 + + + + Newer version available Доступна более новая версия @@ -4837,41 +5111,41 @@ MainWindowBase - + %1 (modified) %1 (изменен) - + (modified) (изменен) - + Cut Вырезать - + Paste Вставить - - - - - + + + + + Add Point Добавить точку - + Add Point at %1 s Добавить точку по отметке %1 с - + Opening file or URL... Открывается файл или URL... @@ -4884,130 +5158,220 @@ Загрузить этот файл в новое окно волновой формы - + + Not enough disc space + Недостаточно дискового пространства + + + + <b>Not enough disc space</b><p>There doesn't appear to be enough spare disc space to accommodate any necessary temporary files.</p><p>Please clear some space and try again.</p> + + + + + Not enough memory + + + + + <b>Not enough memory</b><p>There doesn't appear to be enough memory to accommodate any necessary temporary data.</p> + + + + Select target for import Выбрать цель для импорта - + <b>Select a target for import</b><p>You already have an audio file loaded.<br>What would you like to do with the new audio file? - - - - + + + + %1: %2 %1: %2 - - + + %1: %2 [%3] %1: %2 [%3] - - + + Import "%1" Импортировать "%1" - + Opening playlist... Открывается список воспроизведения... - + Opening session... - Открывается сеанс... - - - - + Открывается сессия… + + + + SV XML file read error: %1 Ошибка чтения XML-файла SV: %1 - + + Incomplete session loaded + + + + + Some of the audio content referred to by the original session file could not be loaded. +If you save this session, it will be saved without any reference to that audio, and information may be lost. + + + + Open session template "%1" - - - - + Открыть шаблон сессии "%1" + + + <b>Failed to import RDF</b><p>No suitable data models found for import from RDF document at "%1"</p> - + + <b>No audio available</b><p>Could not open an audio device.</p> + + + + + <b>No audio available</b><p>Could not open audio device: %1</p> + + + + + <p>Automatic audio device detection failed. Audio playback and recording will not be available during this session.</p> + + + + + <p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1").</p> + + + + + <b>No audio available</b><p>Failed to open your preferred audio driver ("%1"): %2.</p> + + + + + <p>Audio playback and recording will not be available during this session.</p> + + + + + <p>Audio playback will not be available during this session.</p> + + + + Couldn't open audio device Не удалось открыть звуковое устройство - - - + + + Failed to write file Не удалось записать файл - - - + + + <b>Save failed</b><p>Failed to write to file "%1": %2 <b>Не удалось сохранить</b><p>Не удалось записать файл "%1": %2 - + + No record device available + Нет доступных устройств записи + + + + <b>No record device available</b><p>Failed to find or open an audio device for recording. Only playback will be available.</p> + + + + + Recording failed + Не удалось записать + + + + <b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p> + + + + Import Recorded Audio - + Add Pane Добавить окно - + Remove Pane Удалить окно - - + + Delete Pane Удалить окно - + Playing: %1 of %2 (%3 remaining) Воспроизводится: %1 из %2 (осталось %3) - + Recording: %1 - - - - + Запись: %1 + + <b>No audio available</b><p>Could not open an audio device for playback.<p>Automatic audio device detection failed. Audio playback will not be available during this session.</p> - <b>Беззвучный режим</b><p>Не удалось открыть звуковое устройство для воспроизведения.<p>Не удалось автоматически определить звуковое устройство. На этот раз придется обойтись без воспроизведения звука.</p> - - - + <b>Беззвучный режим</b><p>Не удалось открыть звуковое устройство для воспроизведения.<p>Не удалось автоматически определить звуковое устройство. На этот раз придется обойтись без воспроизведения звука.</p> + + + Close the current session and start a new one - + Replace the main audio file in this session - - - - + Заменить основной аудиофайл в этйо сессии + + + Add the audio file to this session @@ -5016,8 +5380,8 @@ <b>Беззвучный режим</b><p>Не удалось открыть предпочитаемое звуковое устройство («%1»).<p>На этот раз придется обойтись без воспроизведения звука.</p> - - + + Importing from RDF... Выполняется импорт из RDF... @@ -5026,43 +5390,43 @@ <b>Выберите цель импорта</b><p>У вас уже есть один загруженный звуковой файл.<br>Что вы хотите сделать с новыми звуковыми данными? - + Import audio file "%1" Импорт звукового файла "%1" - + Import layer XML file "%1" Импорт XML-файла слоя "%1" - + Import MIDI file "%1" Импорт файла MIDI "%1" - + Import session file "%1" - Импорт файла сеанса "%1" - - - - + Импорт файла сессии "%1" + + + + Failed to import RDF Не удалось импортировать RDF - + <b>Failed to import RDF</b><p>Importing data from RDF document at "%1" failed: %2</p> <b>Не удалось импортировать RDF</b><p>Не удалось импортировать данные из документа RDF "%1": %2</p> - + Import RDF document "%1" Импорт документа RDF "%1" - + Add Item at %1 s Добавить объект в позицию %1с @@ -5190,7 +5554,7 @@ %1 <%2> - + %1: %2 %1: %2 @@ -5198,53 +5562,68 @@ NetworkPermissionTester - + Welcome to Sonic Visualiser - - - - - <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary, University of London, Sonic Visualiser is provided free as open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like to make networking connections and open a network port.</p><p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control, where configured; and</li><li> Tell you when updates are available.</li></ul><p>No personal information will be sent, no tracking is carried out, and all requests happen in the background without interrupting your work.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful. But if you do not wish to do so, please un-check the box below.<br></p> - - - - + Приветствуем в Sonic Visualiser + + + + <h2>Welcome to Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.</p><p>Developed in the Centre for Digital Music at Queen Mary University of London, Sonic Visualiser is open source software under the GNU General Public License.</p><p><hr></p><p><b>Before we go on...</b></p><p>Sonic Visualiser would like permission to use the network.</p> + <h2>Приветствуем в Sonic Visualiser!</h2><p><img src=":icons/qm-logo-smaller.png" style="float:right">Это программа для просмотра и исследования звуковых данных с целью семантического анализа и аннотации музыки.</p><p>Программа разработана в Центре фировой музыки (Centre for Digital Music) университета Королевы Мэри (Queen Mary University) в Лондоне. Sonic Visualiser — приложение с открытым исходным кодом, которое распространяется на условиях GNU General Public License.</p><p><hr></p><p><b>Перед началом работы…</b></p><p>Sonic Visualiser необходимо получить ваше разрешение на доступ в Сеть.</p> + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins;</li><li> Support the use of Open Sound Control; and</li><li> Tell you when updates are available.</li></ul> + <p>Для чего это нужно:</p><ul><li> Находить информацию о доступных и установленных плагинах;</li><li> Использовать протокол Open Sound Control;</li><li> Сообщать вам о появлении новых версий программы.</li></ul> + + + + <p>This is to:</p><ul><li> Find information about available and installed plugins; and</li><li> Tell you when updates are available.</li></ul> + <p>Для чего это нужно:</p><ul><li> Находить информацию о доступных и установленных плагинах;</li><li> Сообщать вам о появлении новых версий программы.</li></ul> + + + + <p><b>No personal information will be sent, no tracking is carried out, and no individual information will be shared with anyone else.</b> We will however make aggregate counts of distinct requests for usage reporting.</p><p>We recommend that you allow this, because it makes Sonic Visualiser more useful to you and supports the public funding of this work. But if you do not wish to allow it, please un-check the box below.<br></p> + <p><b>Программа не будет передавать персональные данные, следить за вами или делиться с кем-то вашей личной информацией.</b> Однако Sonic Visualiser будет собирать базовую статистику о своем использовании.</p><p>Мы рекомендуем разрешить программе доступ в Сеть, поскольку это позволит нам сделать Sonic Visualiser лучше для вас, а кроме того, поможет с финансированием разработки. Если вы против, просто снимите флажок ниже.<br></p> + + + Allow this - + Разрешить доступ в Сеть NoteLayer - - + + New Point Новая точка - + Vertical Scale Верт. масштаб - + Auto-Align Автовыравнивание - + In progress В процессе - - + + No local points Нет локальных точек - + Time: %1 Pitch: %2 Duration: %3 @@ -5255,7 +5634,7 @@ Без метки - + Time: %1 Pitch: %2 Duration: %3 @@ -5266,108 +5645,108 @@ Метка: %4 - + Draw Point Нарисовать точку - + Drag Point Перетащить точку - - + + Edit Point Изменить точку - + Relocate Point Переместить точку - + Change Point Value Изменить значение точки - + Drag Selection Перетащить выделение - + Resize Selection Изменить размер выделения - + Delete Selected Points Удалить выбранные точки - + Paste Вставить - + Scale Units Единицы шкалы - + Scale Масштаб - + Linear Линейный - + Log Логарифмический - + MIDI Notes Ноты MIDI - + %1 %2 %1 %2 - + Erase Point Стереть точку - + Re-align pasted items? Заново выровнять вставленные объекты? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Record Note - + %1 (%2, %3 Hz) %1 (%2, %3 Гц) - + %1 Hz (%2, %3) %1Гц (%2, %3) @@ -5423,7 +5802,7 @@ OggVorbisFileReader - + Decoding %1... Декодируется %1... @@ -5436,7 +5815,7 @@ Обзор - + Click and drag to navigate; double-click to jump Щёлкните и потащите для перемещения по окну; щёлкните дважды для скачка @@ -5444,285 +5823,285 @@ Pane - + Some lengthy prefix: Некий длинный префикс: - + (R) (R) - + (X) (X) - + %1 / %2Hz%3 %1 / %2 Гц%3 - + Drag Selection Перетащить выделение - + Resize Selection Изменить выделение - + Horizontal Zoom Горизонтальное масштабирование - + Vertical Zoom Вертикальное масштабирование - + Enter new range Введите новый диапазон - + New vertical display range, from %1 to %2 %4: Новый диапазон отображения по вертикали, от %1 до %2 %4: - + Click and drag to navigate Щёлкните и потащите для перемещения по окну - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate Щёлкните и потащите для выделения области; + Shift — для отключения прилипания к объектам; + Ctrl — для выделения нескольких объектов, + средняя клавиша мыши — для перемещения по окну - + Click and drag to select a range; hold Shift to avoid snapping to items; hold Cmd for multi-select; middle-click and drag to navigate Щёлкните и потащите для выделения области; + Shift — для отключения прилипания к объектам; + Cmd — для выделения нескольких объектов, + средняя клавиша мыши — для перемещения по окну - + Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate Щёлкните и потащите для выделения диапазона; + Ctrl — для выделения нескольких объектов, + средняя клавиша мыши — для перемещения по окну - + Click and drag to select a range; hold Cmd for multi-select; middle-click and drag to navigate Щёлкните и потащите для выделения диапазона; + Cmd — для выделения нескольких объектов, + средняя клавиша мыши — для перемещения по окну - + Click and drag to move the selection boundary Щёлкните и потащите для перемещения границ выделения - + Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate Щёлкните и потащите для выделения области; + Shift — для отключения прилипания к объектам; + средняя клавиша мыши — для перемещения по окну - + Click and drag to select a range; middle-click and drag to navigate Щёлкните и потащите для выделения области; + средняя клавиша мыши — для перемещения по окну - + Click to add a new item in the active layer Щёлкните для добавления нового объекта на активный слой - + Click and drag to move all items in the selected range Щёлкните и потащите все объекты в выделенной области - + Click and drag to adjust the visible range of the vertical scale Щёлкните и потащите для смены видимого диапазона масштабирования по вертикали - + Click and drag to adjust the vertical zoom level Щёлкните и потащите для смены уровня масштабирования по вертикали - + Click and drag to adjust the horizontal zoom level Щёлкните и потащите для смены уровня масштабирования по горизонтали - + Reset horizontal and vertical zoom levels to their defaults Сбросить уровни масштабирования по горизонтали и вертикали до исходных значений - + Reference - - + + Unaligned - + Aligning: %1% - + Aligned - + %1 - %2 %1 - %2 - - + + +%1 - - + + Zoom Масштабирование отображения - + Zoom In Приблизить - + Wheel Up Колесом вверх - + Zoom Out Отдалить - + Wheel Down Колесом вниз - + General Pane Mouse Actions Использование мыши в окнах - + Wheel Колесо - + Zoom in or out in time axis Приближение и отдаление по временной шкале - + Ctrl+Wheel Ctrl+прокрутка - + Scroll - Прокручивать окно сеанса - - - + Прокручивать окно сессии + + + Scroll rapidly left or right in time axis Быстро перемещаться вправо и влево по временной шкале - + Zoom Vertically Вертикальный масштаб - + Shift+Wheel Shift+прокрутка - + Zoom in or out in the vertical axis Масштабировать отображение по вертикальной оси - + Scroll Vertically Прокрутка по вертикали - + Alt+Wheel Alt+Колесо - + Scroll up or down in the vertical axis Прокручивать отображение по вертикальной оси - + Navigate Перемещение - + Middle - + Click middle button and drag to navigate with any tool - + Relocate Перемещение скачком - + Double-Click Middle Двойной щелчок средней клавишей - + Double-click middle button to relocate with any tool Перескочить вправо или влево в зависимости от положения курсора - + Menu Меню - + Right Правая клавиша - + Show pane context menu Показать контекстное меню окна @@ -5803,17 +6182,17 @@ Измерить объект - + Click to erase an item from the active layer - + Reset zoom to default - + Click and drag an item in the active layer to move it; hold Shift to override initial resistance @@ -5886,7 +6265,7 @@ This plugin has no adjustable parameters. - У этого расширения нет изменяемых параметров. + У этого плагина нет изменяемых параметров. @@ -5897,350 +6276,502 @@ PluginParameterDialog - + Name: Название: - + Maker: Автор: - + Copyright: Авторские права: - + Version: Версия: - - + + Plugin Parameters - Параметры расширения - - - + Параметры плагина + + + Channel mismatch Несовпадение каналов - + This plugin requires at least %1 input channels, but only %2 %3 available. The plugin probably will not work correctly. - Этому расширению нужно хотя бы %1 вхдных каналовs, но лишь %2 %3 доступны. Вероятно, расширение не сработает как должно. - - - + Этому плагину нужно хотя бы %1 входных каналов, но лишь %2 %3 доступны. Вероятно, плагин не будет корректно работать. + + + are являются - + is является - + Channels Каналы - + This plugin accepts no more than %1 input channels, but %2 are available. Only the first %3 will be used. - Это расширение принимает не более %1 каналов на входе, -но доступно целых %2. Только первые %3 будут использованы. + Этот плагин принимает не более %1 каналов на входе, +но доступно %2. Только первые %3 будут использованы. - + This plugin only has a single channel input, but the source has %1 channels. - Это расширение может обрабатывать только один канал, + Этот плагин может обрабатывать только один канал, но у источника %1 каналов. - + Use mean of source channels Использовать среднее значение каналов источника - + Use channel %1 only Использовать только канал %1 - + Output: Выход: - + Processing Обработка - + Window size: Размер оконной функции: - + Audio frames per block: Выборок звука на блок: - + Window increment: Шаг: - + Window shape: Форма: - - + + Advanced >> Больше >> - + Advanced << Меньше << - + Input Material - + Restrict to selection extents Только выделение + PluginPathConfigurator + + + Move the selected location later in the list + + + + + Move the selected location earlier in the list + + + + + Add a new location to the list + + + + + Remove the selected location from the list + + + + + Reset to Default + + + + + Reset the list for this plugin type to its default + + + + + Review plugins... + + + + + Plugin locations for plugin type: + + + + + Vamp + + + + + LADSPA + + + + + DSSI + + + + + Vamp (32-bit) + + + + + LADSPA (32-bit) + + + + + DSSI (32-bit) + + + + + (Variable is currently unset) + + + + + (Current value begins: "%1 ...") + + + + + (Currently set to: "%1") + + + + + Allow the %1 environment variable to take priority over this +%2 + + + + + Choose directory to add + + + + + PluginReviewDialog + + + Plugins Loaded + + + + + Type + Тип + + + + Library + + + + + Identifier + + + + + Found in + + + + + Name + Название + + + + Vamp + + + + + DSSI + + + + + LADSPA + + + + Preferences - + Frequency of concert A Частота условной ноты Ля (A) - + Property box layout Внешний вид панели свойств - + Spectral analysis window shape Форма оконной функции при спектральном анализе - + Normalise audio signal when reading from audio file - - - - + Нормировать звуковой сигнал при чтении аудиофайлов + + + + Load mp3 files in gapless mode + Загружать файлы MP3 без интервалов + + + Single fixed sample rate to resample all files to - + Time display precision - - - - + Точность показываемого времени + + + Use hours:minutes:seconds format - - - - + Использовать формат часы:минуты:секунды + + + Label middle C as - + Show boxes for all panes Показывать панели для всех окон - + Show box for current pane only Показывать панель только для активного окна - + Rectangular Прямоугольная - + Triangular Треугольная - + Hamming Хамминга - + Blackman Блэкмена - + Gaussian Гауссова - + Parzen Парзена - + Nuttall Нутталла - + Blackman-Harris Блэкмена-Харриса - + C0 - middle of octave scale - + C3 - common MIDI sequencer convention - + C4 - ASA American standard - + C5 - used in Cakewalk and others - + Preferences Параметры - + Playback resampler type Тип ресэмплирования при воспроизведении - + Fastest Самый быстрый - + Standard Обычный - + Highest quality Наивысшего качества - + Spectrogram y-axis interpolation: Интерполяция оси Y спектрограммы: - + Omit temporaries from Recent Files menu Пропускать временные файлы в меню недавно открывавшихся - + Resample mismatching files on import Ресэмплировать файлы при импорте - + Location for cache file directory Расположение каталога с кэшем - + Background colour preference Предпочитаемый цвет фона - + Font size for text overlays Кегль шрифта для текстовых перекрытий - + Show splash screen on startup Показывать заставку при старте программы - + Hann Хэнна - + Follow desktop theme Использовать параметры окружения - + Dark background Темный фон - + Light background Светлый фон - + Spectrogram x-axis interpolation: Интерполяция спектрограммы по оси X: - - + + None Нет - - + + Linear interpolation Линейная интерполяция - + 4 x Oversampling 4 × пересэмплированная - + 4 x Oversampling with interpolation 4 × пересэмплированная с интерполяцией @@ -6249,37 +6780,37 @@ Формат отображения времени - + Standard (to millisecond) - Обычный (до мс) - - - + Обычная (до мс) + + + High resolution (to microsecond) Высокое разрешение (до мкс) - + 24 FPS 24 кадра/с - + 25 FPS 25 кадров/с - + 30 FPS 30 кадров/с - + 50 FPS 50 кадров/с - + 60 FPS 60 кадров/с @@ -6287,145 +6818,206 @@ PreferencesDialog - + Apply Применить - - - - - - - - - + - - - - + + + + + + + + + + + + %1: %1: - + Default spectrogram colour: - - - - + Цвет спектрограммы по умолчанию: + + + Default melodic spectrogram colour: - - - - + Цвет спектрограммы мелодического диапазона по умолчанию: + + + Default colour 3D plot colour: - - - - + Цвет трёхмерного графика по умолчанию: + + + + &Other + &Прочее + + + OK ОК - + Cancel Отменить - + Sonic Visualiser: Application Preferences - Параметры работы Sonic Visualiser - - - + Параметры Sonic Visualiser + + + + Green + Зелёный + + + + + + (auto) + (авто) + + + <home directory> <домашний каталог> - + Follow system locale - - - - + Использовать системные настройки + + + Russian - - - - + Русский + + + British English - - - - + Английский (Великобритания) + + + American English - - - - + Английский (США) + + + Czech - - - - + Чешский + + + + Overview waveform colour: + Цвет миниатюры волнового сигнала: + + + + Run Vamp plugins in separate process: + Запускать плагины VAMP отдельным процессом: + + + + Default session template when loading audio files: + Шаблон сессии по умолчанию при загрузке аудиофайлов: + + + + (Use "%1" in the File menu to add to these.) + Используйте команду «%1» в меню «Файл», чтобы создать новые шаблоны. + + + + Export Session as Template... + Экспортировать сессию как шаблон… + + + + Audio service: + Звуковой движок: + + + + Audio playback device: + Устройство воспроизведения: + + + + Audio record device: + Устройство записи: + + + + A&udio I/O + &Звуковой вход/выход + + + + &Plugins + + + + User interface language - - - - + Язык интерфейса + + + Allow network usage - - - - + Разрешить выход в Сеть + + &General - О&бщие - - - + О&бщие + + + Draw layers at Retina resolution: - - - - - Default session template for audio files: - - - - + Рисовать слои в разрешении Retina: + + + Standard Waveform - - - - + Обычная волновая форма сигнала + + + Session &Template - - - - + &Шаблон сессий + + + Select a directory to create cache subdirectory in Выберите каталог для хранения кэша - + Preferences Параметры - + <b>Restart required</b><p>One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.</p><p>Please exit and restart the application now if you want these changes to take effect immediately.</p> <b>Требуется перезапуск программы</b><p>Некоторые изменившиеся параметры не могут быть учтены без перезапуска Sonic Visualiser.</p><p>Завершите работу с программой и повторно запустите ее, чтобы внесенные изменения возымели эффект.</p> - + Preferences Changed Параметры изменены - + Some preferences have been changed but not applied. Apply them before closing? Некоторые параметры работы программы @@ -6437,12 +7029,12 @@ Устройство воспроизведения: - + &Appearance Об&лик - + Anal&ysis &Анализ @@ -6450,7 +7042,7 @@ ProgressDialog - + Cancel Отменить @@ -6458,85 +7050,91 @@ PropertyBox - + Show Показать - Play - Воспроизвести - - - - + Воспроизвести + + Playback Pan / Balance - Панорама/баланс при воспроизведении - - - + Панорама/баланс при воспроизведении + + Playback Gain - Усиление воспроизведения - - - + Усиление воспроизведения + + dB - Дб - - - + Дб + + + + Click to toggle playback + + + + Set playback clip: - + + Adjust playback level and pan of %1 + + + + + Change sound used for playback (currently "%1") + + + + (current value: %1%2) (текущее значение: %1%2) - + (current value: %1) (текущее значение: %1) - + Toggle Visibility of %1 Переключить видимость %1 - + Toggle Playback of %1 Переключить воспроизведение %1 - + Toggle %1 property of %2 Переключить %1 свойство %2 - + Adjust %1 property of %2%3 Скорректировать %1 свойство %2%3 - Add New Colour... - Добавить новый цвет... - - - + Добавить новый цвет... + + Name New Colour - Дайте цвету название - - - + Дайте цвету название + + Enter a name for the new colour: - Введите название нового цвета: - - - + Введите название нового цвета: + + Prefer black background for this colour - Предпочитать черный фон для этого цвета + Предпочитать черный фон для этого цвета @@ -6572,7 +7170,7 @@ ложь - + Set %1 Property Установить свойство %1 @@ -6600,7 +7198,7 @@ QApplication - + Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation. @@ -6627,7 +7225,7 @@ - + Sonic Visualiser Sonic Visualiser @@ -6635,13 +7233,13 @@ QFile - + File "%1" does not exist Файл "%1" не существует - + Failed to open file "%1" Не удалось открыть файл "%1" @@ -6656,18 +7254,18 @@ QMessageBox - - + + Failed to open file Не удалось открыть файл - + File or URL "%1" could not be opened Файл или URL "%1" не мог быть открыт - + <b>Audio required</b><p>Please load at least one audio file before importing annotation data <b>Нужны звуковые данные</b><p>Загрузите хотя бы один звуковой файл перед импортом аннотаций @@ -6675,38 +7273,122 @@ QObject - - <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> - - - - - - Failed to load library - - - - - Failed to query plugins from library after loading - - - - - Unknown failure - - - - - Success: internal error? + + External plugin host executable does not appear to be installed + + + + + Could not start external plugin host + + + + + External plugin host exited unexpectedly while listing plugins + + + + + External plugin host invocation failed: %1 + + + + + <b>Failed to scan for plugins</b><p>Failed to scan for plugins at startup. Possibly the plugin checker program was not correctly installed alongside %1?</p> + + + + + <b>Did not scan for plugins</b><p>Apparently no scan for plugins was attempted (internal error?)</p> + + + + + <b>Failed to load plugins</b><p>Failed to load one or more plugin libraries:</p> + <b>Не удалось загрузить плагины</b><p>Не удалось загрузить одну или больше библиотек плагинов:</p> + + + + <p>These plugins may be incompatible with the system, and will be ignored during this run of %1.</p> + <p>Эти плагины могут быть несовместимы с программой и будут проигнорированы при работе в %1.</p> + + + + + <unknown> + <неизвестно> + + + + Green + Зелёный + + + + White on Black + Белое на чёрном + + + + Black on White + Чёрное на белом + + + + Cherry + Вишня + + + + Wasp + + + + + Ice + Лёд + + + + Sunset + Закат + + + + Fruit Salad + Фруктовый салат + + + + Banded + В полоску + + + + Highlight + Подсветка + + + + Printer + Принтер + + + + High Gain + + + + + Exporting audio data... QuickTimeFileReader - Decoding %1... - Декодируется %1... + Декодируется %1... @@ -6754,73 +7436,73 @@ RegionLayer - + Vertical Scale Верт. масштаб - + Scale Units Единицы шкалы - + Plot Type Тип графика - + Scale Масштаб - + Bars Такты - + Segmentation Сегментация - + Auto-Align Автовыравнивание - + Equal Spaced Равные промежутки - + Linear Линейный - + Log Логарифмический - + In progress В процессе - - + + No local points Нет локальных точек - + %1 %2 %1 %2 - + Time: %1 Value: %2 Duration: %3 @@ -6831,7 +7513,7 @@ Без метки - + Time: %1 Value: %2 Duration: %3 @@ -6842,69 +7524,69 @@ Метка: %4 - + Change Point Value Изменить значение точки - + Drag Selection Перетащить выделение - + Resize Selection Изменить размер выделения - + Delete Selected Points Удалить выбранные точки - + Re-align pasted items? Заново выровнять вставленные объекты? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Paste Вставить - + New Region - + Draw Region - + Erase Region - + Drag Region - - + + Edit Region - + Relocate Region @@ -6955,7 +7637,7 @@ RemoveLayerCommand - + Delete %1 Layer Удалить слой %1 @@ -6976,7 +7658,7 @@ (модель извлечена в SV-XML) - + Opening file or URL... Открывается файл или URL... @@ -6997,113 +7679,113 @@ SliceLayer - - + + %1 - %2 %1 - %2 - + First - - + + Mean Усреднённо - - + + Peak Пик - + 0dB 0 Дб - + -Inf -Inf - + x10 x10 - + Plot Type Тип графика - - + + Scale Масштаб - + Normalize Нормализовать - + Gain Усиление - + Sampling Mode Режим сэмплирования - - + + Linear Линейный - + Meter Счетчик - - + + dB Дб - + Any Любые - + Lines Линии - + Steps Шаги - + Blocks Блоки - + Colours Цвета - + Time: %1 - %2 Range: %3 samples (%4) Bin: %5 @@ -7114,40 +7796,40 @@ %6 значение: %7 - + Time: %1 - %2 Range: %3 samples (%4) Время: %1 - %2 Диапазон: %3 сэмплов (%4) - + Threshold Порог - + Bin Scale - + Bins Бины - - + + Log - - - - + Логарифм. + + + Absolute Абсолютный - + Rev Log @@ -7167,22 +7849,22 @@ Переразметить точку - + Sparse - + Edit Data Изменить данные - + Insert Data Point - + Delete Data Point @@ -7190,7 +7872,7 @@ SparseModel::AddPointCommand - + Add Point Добавить точку @@ -7198,7 +7880,7 @@ SparseModel::DeletePointCommand - + Delete Point Удалить точку @@ -7206,7 +7888,7 @@ SparseModel::RelabelCommand - + Re-Label Point Переразметить точку @@ -7293,18 +7975,18 @@ SpectrogramLayer - - + + Colour Цвет - + Colour Scale - + Window Size Размер окна @@ -7313,234 +7995,249 @@ Нормализовать столбцы - + Bin Display - + Threshold Порог - + Gain Усиление - + Colour Rotation Вращение цвета - + Min Frequency Мин. частота - + Max Frequency Макс. частота - + Frequency Scale - + Window Окно - + Scale Масштаб - - + + Linear Линейный - + Meter Счетчик - - + + dB Дб - + Phase Фаза - + Normalization - + + Col + + + + + View + + + + + Hybrid + + + + No min Без минимума - + 10 Hz 10 Гц - + 20 Hz 20 Гц - + 40 Hz 40 Гц - + 100 Hz 100 Гц - + 250 Hz 250 Гц - - + + 500 Hz 500 Гц - - + + 1 KHz 1 КГц - - + + 4 KHz 4 КГц - + 10 KHz 10 КГц - + 1.5 KHz 1,5 КГц - + 2 KHz 2 КГц - + 6 KHz 6 КГц - + 8 KHz 8 КГц - + 12 KHz 12 КГц - + 16 KHz 16 КГц - + No max Без максимума - + Log Логарифм. - + All Bins Все бины - + Peak Bins Пиковые бины - + Frequencies Частоты - + <unknown> <неизвестно> - + Peak Frequency: %1 - %2 Hz Пиковая частота: %1 - %2 Гц - + Peak Frequency: %1 Hz Пиковая частота: %1 Гц - + Peak Pitch: %3 - %4 Пиковая высота тона: %3 - %4 - + Peak Pitch: %2 Пиковая высота тона: %2 - + Time: %1 - %2 Время: %1 - %2 - + Time: %1 Время: %1 - + %1Bin Frequency: %2 - %3 Hz %4Bin Pitch: %5 - %6 @@ -7549,7 +8246,7 @@ - + %1Bin Frequency: %2 Hz %3Bin Pitch: %4 @@ -7558,73 +8255,66 @@ - - -Inf - -Inf - - - + -Inf + + + dB: %1 - %2 Дб: %1 - %2 - + dB: %1 Дб: %1 - + Phase: %1 - %2 Фаза: %1 - %2 - + Phase: %1 Фаза: %1 - + Window Overlap Перекрытие окон - - Smoothing - - - - - + + None Нет - + 25 % 25 % - + 50 % 50 % - + 75 % 75 % - + 87.5 % 87,5 % - + 93.75 % 93,75 % @@ -7633,39 +8323,39 @@ Нормализовать видимую область - + Bins Бины - + FFT cache failed Не удалось кэшировать FFT - + Failed to create the FFT model for this spectrogram. There may be insufficient memory or disc space to continue. Не удалось создать FFT-модель этой спектрограммы. Вероятно, не хватает памяти или дискового порстранства для продолжения. - + dBV^2 ДбВ^2 - + dBV ДбВ - + 43Hz 43 Гц - + %1Hz %1 Гц @@ -7673,90 +8363,93 @@ SpectrumLayer - + Window Size Размер окна - + Window Overlap Перекрытие окон - + Window Окно - + Mean Усреднённо - + None Ничего - + Bins Бины - + 25 % 25 % - + 50 % 50 % - + 75 % 75 % - + 87.5 % 87,5 % - + 93.75 % 93,75 % - - - + + + %1 - %2 %1 - %2 - + %1 - %2 Hz %1 - %2 Гц - + %1 Hz %1 Гц - - + + Hz + + + -Inf - -Inf - - - + -Inf + + + %1 %1 - + %1 Bin: %2 (%3) %4 value: %5 @@ -7767,17 +8460,17 @@ Дб: %6 - + First - + Peak Пик - + %1 Bin: %2 (%3) Value: %4 @@ -7788,7 +8481,7 @@ Дб: %5 - + Show Peak Frequencies Показывать пиковые частоты @@ -8000,107 +8693,107 @@ TimeInstantLayer - - + + New Point Новая точка - + Plot Type Тип графика - + Instants - + Segmentation Сегментация - + In progress В процессе - + No local points Нет локальных точек - + Time: %1 No label Время: %1 Без метки - + Time: %1 Label: %2 Время: %1 Метка: %2 - + Draw Point Нарисовать точку - + Add Point at %1 s Добавить точку в %1 с - + Drag Point Перетащить точку - + Move Point to %1 s Перетащить точку к %1 с - + Edit Point Изменить точку - + Drag Selection Перетащить выделение - + Resize Selection Изменить размер выделения - + Delete Selection Удалить выделение - + Paste Вставить - + Erase Point Удалить точку - + Re-align pasted instants? Заново выровнять вставленные объекты? - + The instants you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? @@ -8108,80 +8801,80 @@ TimeValueLayer - - + + New Point Новая точка - - + + Plot Type Тип графика - + Vertical Scale Верт. масштаб - + Scale Units Единицы шкалы - + Show Derivative - + Points Точки - + Stems Ножки - + Connected Points Соединённые точки - + Lines Линии - + Curve Кривая - + Segmentation Сегментация - + Discrete Curves - + Auto-Align Автовыравнивание - + In progress В процессе - + No local points Нет локальных точек @@ -8202,111 +8895,111 @@ Метка: %4 - + Draw Point Нарисовать точку - + Drag Point Перетащить точку - - + + Edit Point Изменить точку - + Relocate Point Переместить точку - + Change Point Value Изменить значение точки - + Drag Selection Перетащить выделение - + Resize Selection Изменить размер выделения - + Delete Selected Points Удалить выбранные точки - + Paste Вставить - + The items you are pasting do not have values. What values do you want to use for these items? У вставляемых объектов нет значений. Какие значения вы хотите для них использовать? - + Some of the items you are pasting do not have values. What values do you want to use for these items? У некоторых вставляемых объектов нет значений.Какие значения вы хотите для них использовать? - + Zero for all items Ноль для всех объектов - + Choose value calculation Выбрать вычисление значения - + Scale Масштаб - + Linear Линейный - + Log Логарифмический - + +/-1 +/-1 - + %1 Hz (%2, %3) %1Гц (%2, %3) - + %1 %2 %1 %2 - + %1 %1 - + Time: %1 Value: %2 No label @@ -8317,7 +9010,7 @@ ?} - + Time: %1 Value: %2 Label: %4 @@ -8328,32 +9021,32 @@ ?} - + Erase Point Стереть точку - + Re-align pasted items? Заново выровнять вставленные объекты? - + The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer? - + Select cycle size - + Cycle size: - + Draw Segment Division Lines @@ -8389,136 +9082,141 @@ TransformFactory - - + + %1: %2 %1: %2 - + %1: Output %2 %1: Выход %2 - + Analysis Анализ - + Effects Data Данные эффектов - + Effects Эффекты - + [\(<].*$ [\(<].*$ - - + + Failed to list Vamp plugins: %1 + Не удалось перечислить плагины VAMP: %1 + + + + <unknown maker> <неизвестный производитель> - - + + Extract features using "%1" plugin (from %2) - Извлечь данные при помощи "%1" (из %2) - - - - + Извлечь данные при помощи плагина "%1" (из %2) + + + + Extract features using "%1" output of "%2" plugin (from %3) - Извлечь данные при помощи "%1" вывода из расширения "%2" (из %3) - - - - + Извлечь данные при помощи "%1" вывода из плагина "%2" (из %3) + + + + %1 using "%2" plugin (from %3) - %1 используя расширение "%2" (из %3) - - - - + %1 используя плагин "%2" (из %3) + + + + %1 using "%2" output of "%3" plugin (from %4) - %1 используя вывод "%2" расширения "%3" (из %4) - - - + %1 используя вывод "%2" плагина "%3" (из %4) + + + Extract "%1" data output from "%2" effect plugin (from %3) - Извлечь "%1" данные вывода из расширения эффектов "%2" (из %3) - - - + Извлечь "%1" данные вывода из плагина эффектов "%2" (из %3) + + + Extract data output %1 from "%2" effect plugin (from %3) - Извлечь данные вывода %1 из расширения эффектов "%2" (из %3) - - - + Извлечь данные вывода %1 из плагина эффектов "%2" (из %3) + + + Transform audio signal with "%1" effect plugin (from %2) - Трансформировать звуковой сигнал расширением эффектов "%1" (из %2) - - - + Трансформировать звуковой сигнал плагином эффектов "%1" (из %2) + + + Generate audio signal using "%1" plugin (from %2) - Создать звуковой сигнал при помощи расширения "%1" (из %2) + Создать звуковой сигнал при помощи плагина "%1" (из %2) + + + + + Plugin type + Тип плагина + + + + + Category + Категория + + + + + System Identifier + Системный идентификатор - Plugin type - Тип расширения + Name + Название + + + + + Description + Описание - Category - Категория + Maker + Создатель - System Identifier - Системный идентификатор - - - - - Name - Название - - - - - Description - Описание - - - - - Maker - Создатель - - - - Units Единица измерения - + Generator Генератор - - + + Other Прочее @@ -8528,7 +9226,7 @@ Find a Transform - Поиск расширений для трансформации + Поиск плагинов для трансформации @@ -8605,7 +9303,7 @@ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&mdash; Plugin type: %1 - <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&mdash; Тип расширения: %1 + <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&mdash; Тип плагина: %1 @@ -8625,7 +9323,7 @@ <p>Type some text into the search box to search the descriptions of:<ul><li>All currently installed <a href="http://www.vamp-plugins.org/">Vamp</a> audio feature extraction plugins</li><li>All currently installed <a href="http://www.ladspa.org/">LADSPA</a> audio effects plugins</li><li>Vamp plugins that are not currently installed but that have descriptions published via the semantic web</li></ul> - <p>Введите текст для поиска по описаниям среди:<ul><li>всех установленных расширений <a href="http://www.vamp-plugins.org/">Vamp</a> для извлечения анализируемых данных;</li><li>всех установленных эффектов<a href="http://www.ladspa.org/">LADSPA</a>;</li><li>еще не установленных расширений Vamp, чьё описание опубликовано в семантической сети.</li></ul> + <p>Введите текст для поиска по описаниям среди:<ul><li>всех установленных плагинов <a href="http://www.vamp-plugins.org/">VAMP</a> для извлечения анализируемых данных;</li><li>всех установленных плагинов <a href="http://www.ladspa.org/">LADSPA</a>;</li><li>еще не установленных плагинов VAMP, чьё описание опубликовано в семантической сети.</li></ul> @@ -8635,17 +9333,17 @@ <b>No plugins are currently installed!</b> - <b>Ни одно расширение не установлено!</b> + <b>Ни один плагин не установлен!</b> <p>%1<br>Perhaps the network connection is down, services are responding too slowly, or a processing problem has occurred.<br>Only the descriptions of installed plugins will be searched. - <p>%1<br>Вероятно, не работает сетевое соединение, либо службы отзываются слишком медленно, либо произошла неполадка при обработке.<br>Будет выполнен поиск только по описаниям уже установленных расширений. + <p>%1<br>Вероятно, не работает сетевое соединение, либо службы отзываются слишком медленно, либо произошла неполадка при обработке.<br>Будет выполнен поиск только по описаниям уже установленных плагинов. <p>%1<br>Only the published descriptions of Vamp feature extraction plugins will be searched. - <p>%1<br>Выдет выполнен поиск только по описаниям расширений Vamp, предназначенных для извлечения анализируемых данных. + <p>%1<br>Выдет выполнен поиск только по описаниям плагинов VAMP, предназначенных для извлечения анализируемых данных. @@ -8726,63 +9424,68 @@ View - + Global Scroll Глобальная прокрутка - + Global Zoom Глобальный масштаб - + Follow Playback Следовать за воспроизведением - + Scroll Прокручивать - + Page Постранично - + Off Выключить - + <unknown> <неизвестно> - + Layer rendering error - + Waiting for layers to be ready... Ожидание готовности слоёв... - - + + Cancel Отменить - + Rendering image... Отрисовывается изображение... - + + Exported image from %1 + + + + Alignment Выравнивание @@ -8790,102 +9493,102 @@ ViewManager - + Clear Selection Снять выделение - + Select Multiple Regions Выделить несколько областей - + Select Region Выделить область - + Enter Navigate mode - + Enter Select mode - + Enter Edit mode - + Enter Draw mode - + Enter Erase mode - + Enter Measure mode - + Enter NoteEdit mode - + Switch on Loop mode - + Switch off Loop mode - + Switch on Play Selection mode - + Switch off Play Selection mode - + Switch on Play Solo mode - + Switch off Play Solo mode - + Switch on Alignment mode - + Switch off Alignment mode - + Scroll to %1 - + Zoom to %n sample(s) per pixel @@ -8894,7 +9597,7 @@ - + Change overlay level @@ -8924,120 +9627,117 @@ WaveformLayer - - + + Scale Масштаб по Y - + Gain Усиление - + Normalize Visible Area Нормализовать видимую область - + Channels Каналы - + Linear Линейный - + Meter Счетчик - - + + dB Дб - + Separate Отдельно - + Mean Усреднённо - + Butterfly V-образно - + Time: %1 - %2 Время: %1 - %2 - + Time: %1 Время: %1 - + Level: Уровень: - + Left: Левый: - + Right: Правый: - + Channel %1 Канал %1 - + %1 %2 - %3 (%4 dB peak) %1 %2 - %3 (пик в %4 Дб) - + %1 %2 (%3 dB peak) %1 %2 (пик в %3 Дб) - - - + + + 0dB 0 Дб - - - -Inf - -Inf + -Inf WindowShapePreview - + V / time V / время @@ -9050,7 +9750,7 @@ WritableWaveFileModel - + Writable Wave File Записываемый звуковой файл diff -r 246bdf94ef7b -r 55d9bbf1fe45 icons/sonic-visualiser.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/icons/sonic-visualiser.svg Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/MainWindow.cpp --- a/main/MainWindow.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/MainWindow.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -32,6 +32,7 @@ #include "view/ViewManager.h" #include "base/Preferences.h" #include "base/ResourceFinder.h" +#include "base/RecordDirectory.h" #include "layer/WaveformLayer.h" #include "layer/TimeRulerLayer.h" #include "layer/TimeInstantLayer.h" @@ -42,11 +43,12 @@ #include "layer/SliceableLayer.h" #include "layer/ImageLayer.h" #include "layer/RegionLayer.h" -#include "widgets/Fader.h" #include "view/Overview.h" #include "widgets/PropertyBox.h" #include "widgets/PropertyStack.h" #include "widgets/AudioDial.h" +#include "widgets/LevelPanWidget.h" +#include "widgets/LevelPanToolButton.h" #include "widgets/IconLoader.h" #include "widgets/LayerTreeDialog.h" #include "widgets/ListInputDialog.h" @@ -57,8 +59,10 @@ #include "widgets/LabelCounterInputDialog.h" #include "widgets/ActivityLog.h" #include "widgets/UnitConverter.h" +#include "widgets/ProgressDialog.h" +#include "widgets/CSVAudioFormatDialog.h" #include "audio/AudioCallbackPlaySource.h" -#include "audio/AudioRecordTarget.h" +#include "audio/AudioCallbackRecordTarget.h" #include "audio/PlaySpeedRangeMapper.h" #include "data/fileio/DataFileReaderFactory.h" #include "data/fileio/PlaylistFileReader.h" @@ -119,9 +123,10 @@ #include #include #include -#include +#include #include #include +#include #include #include @@ -173,6 +178,8 @@ { Profiler profiler("MainWindow::MainWindow"); + SVDEBUG << "MainWindow: " << getReleaseText() << endl; + setWindowTitle(QApplication::applicationName()); UnitDatabase *udb = UnitDatabase::getInstance(); @@ -194,6 +201,8 @@ cdb->setUseDarkBackground(cdb->addColour(QColor(225, 74, 255), tr("Bright Purple")), true); cdb->setUseDarkBackground(cdb->addColour(QColor(255, 188, 80), tr("Bright Orange")), true); + SVDEBUG << "MainWindow: Creating main user interface layout" << endl; + QFrame *frame = new QFrame; setCentralWidget(frame); @@ -210,7 +219,9 @@ m_overview = new Overview(frame); m_overview->setViewManager(m_viewManager); - m_overview->setFixedHeight(40); + int overviewHeight = m_viewManager->scalePixelSize(35); + if (overviewHeight < 40) overviewHeight = 40; + m_overview->setFixedHeight(overviewHeight); #ifndef _WIN32 // For some reason, the contents of the overview never appear if we // make this setting on Windows. I have no inclination at the moment @@ -225,24 +236,14 @@ m_panLayer->setAggressiveCacheing(true); m_overview->addLayer(m_panLayer); - if (m_viewManager->getGlobalDarkBackground()) { - m_panLayer->setBaseColour - (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green"))); - } else { - m_panLayer->setBaseColour - (ColourDatabase::getInstance()->getColourIndex(tr("Green"))); - } - - m_fader = new Fader(frame, false); - connect(m_fader, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); - connect(m_fader, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); + coloursChanged(); // sets pan layer colour from preferences m_playSpeed = new AudioDial(frame); m_playSpeed->setMinimum(0); m_playSpeed->setMaximum(120); m_playSpeed->setValue(60); - m_playSpeed->setFixedWidth(32); - m_playSpeed->setFixedHeight(32); + m_playSpeed->setFixedWidth(overviewHeight); + m_playSpeed->setFixedHeight(overviewHeight); m_playSpeed->setNotchesVisible(true); m_playSpeed->setPageStep(10); m_playSpeed->setObjectName(tr("Playback Speed")); @@ -250,38 +251,49 @@ m_playSpeed->setDefaultValue(60); m_playSpeed->setShowToolTip(true); connect(m_playSpeed, SIGNAL(valueChanged(int)), - this, SLOT(playSpeedChanged(int))); + this, SLOT(playSpeedChanged(int))); connect(m_playSpeed, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); connect(m_playSpeed, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); - IconLoader il; + m_mainLevelPan = new LevelPanToolButton(frame); + connect(m_mainLevelPan, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); + connect(m_mainLevelPan, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget())); + m_mainLevelPan->setFixedHeight(overviewHeight); + m_mainLevelPan->setFixedWidth(overviewHeight); + m_mainLevelPan->setImageSize((overviewHeight * 3) / 4); + m_mainLevelPan->setBigImageSize(overviewHeight * 3); m_playControlsSpacer = new QFrame; - layout->setSpacing(4); - layout->addWidget(m_mainScroll, 0, 0, 1, 5); - layout->addWidget(m_overview, 1, 1); + layout->setSpacing(m_viewManager->scalePixelSize(4)); + layout->addWidget(m_mainScroll, 0, 0, 1, 4); + layout->addWidget(m_overview, 1, 0); + layout->addWidget(m_playSpeed, 1, 1); layout->addWidget(m_playControlsSpacer, 1, 2); - layout->addWidget(m_playSpeed, 1, 3); - layout->addWidget(m_fader, 1, 4); + layout->addWidget(m_mainLevelPan, 1, 3); m_playControlsWidth = - m_fader->width() + m_playSpeed->width() + layout->spacing() * 2; - - layout->setColumnMinimumWidth(0, 14); - layout->setColumnStretch(0, 0); + m_mainLevelPan->width() + m_playSpeed->width() + layout->spacing() * 2; m_paneStack->setPropertyStackMinWidth(m_playControlsWidth + 2 + layout->spacing()); m_playControlsSpacer->setFixedSize(QSize(2, 2)); - layout->setColumnStretch(1, 10); + layout->setColumnStretch(0, 10); connect(m_paneStack, SIGNAL(propertyStacksResized(int)), this, SLOT(propertyStacksResized(int))); frame->setLayout(layout); + SVDEBUG << "MainWindow: Creating menus and toolbars" << endl; + +#ifdef Q_OS_MAC + // Mac doesn't align menu labels when icons are shown: result is messy + QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); + setIconsVisibleInMenus(false); +#endif + setupMenus(); setupToolbars(); setupHelpMenu(); @@ -307,21 +319,32 @@ m_unitConverter->hide(); setAudioRecordMode(RecordCreateAdditionalModel); - + + SVDEBUG << "MainWindow: Creating new session" << endl; + newSession(); connect(m_midiInput, SIGNAL(eventsAvailable()), this, SLOT(midiEventsAvailable())); - NetworkPermissionTester tester; + SVDEBUG << "MainWindow: Creating network permission tester" << endl; + + NetworkPermissionTester tester(withOSCSupport); bool networkPermission = tester.havePermission(); if (networkPermission) { if (withOSCSupport) { + SVDEBUG << "MainWindow: Creating OSC queue" << endl; startOSCQueue(); } + + SVDEBUG << "MainWindow: Starting transform population thread" << endl; TransformFactory::getInstance()->startPopulationThread(); + + SVDEBUG << "MainWindow: Creating surveyer" << endl; m_surveyer = new Surveyer ("sonicvisualiser.org", "survey23-present.txt", "survey23.php"); + + SVDEBUG << "MainWindow: Creating version tester" << endl; m_versionTester = new VersionTester ("sonicvisualiser.org", "latest-version.txt", SV_VERSION); connect(m_versionTester, SIGNAL(newerVersionAvailable(QString)), @@ -331,10 +354,16 @@ m_versionTester = 0; } +/* + QTimer::singleShot(500, this, SLOT(betaReleaseWarning())); +*/ + QString warning = PluginScan::getInstance()->getStartupFailureReport(); if (warning != "") { QTimer::singleShot(500, this, SLOT(pluginPopulationWarning())); } + + SVDEBUG << "MainWindow: Constructor done" << endl; } MainWindow::~MainWindow() @@ -363,18 +392,17 @@ // workaround, to remove the appmenu-qt5 package, but that is // awkward and the problem is so severe that it merits disabling // the system menubar integration altogether. Like this: - menuBar()->setNativeMenuBar(false); // fix #1039 + menuBar()->setNativeMenuBar(false); // fix #1039 #endif - + m_rightButtonMenu = new QMenu(); - // No -- we don't want tear-off enabled on the right-button - // menu. If it is enabled, then simply right-clicking and - // releasing will pop up the menu, activate the tear-off, and - // leave the torn-off menu window in front of the main window. - // That isn't desirable. I'm not sure it ever would be, in a - // context menu -- perhaps technically a Qt bug? -// m_rightButtonMenu->setTearOffEnabled(true); + // We don't want tear-off enabled on the right-button menu. + // If it is enabled, then simply right-clicking and releasing + // will pop up the menu, activate the tear-off, and leave the + // torn-off menu window in front of the main window. That + // isn't desirable. + m_rightButtonMenu->setTearOffEnabled(false); } if (m_rightButtonTransformsMenu) { @@ -527,7 +555,7 @@ m_keyReference->registerShortcut(action); menu->addAction(action); toolbar->addAction(action); - + icon = il.load("filesaveas"); action = new QAction(icon, tr("Save Session &As..."), this); action->setShortcut(tr("Ctrl+Shift+S")); @@ -538,16 +566,6 @@ menu->addSeparator(); -/* - icon = il.load("fileopenaudio"); - action = new QAction(icon, tr("&Import Audio File..."), this); - action->setShortcut(tr("Ctrl+I")); - action->setStatusTip(tr("Import an existing audio file")); - connect(action, SIGNAL(triggered()), this, SLOT(importAudio())); - m_keyReference->registerShortcut(action); - menu->addAction(action); -*/ - // the Replace action we made earlier menu->addAction(raction); @@ -560,12 +578,6 @@ connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); menu->addAction(action); - action = new QAction(tr("Export Audio Data..."), this); - action->setStatusTip(tr("Export audio from selection into a data file")); - connect(action, SIGNAL(triggered()), this, SLOT(exportAudioData())); - connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); - menu->addAction(action); - menu->addSeparator(); action = new QAction(tr("Import Annotation &Layer..."), this); @@ -585,6 +597,19 @@ menu->addAction(action); menu->addSeparator(); + + action = new QAction(tr("Convert Audio from Data File..."), this); + action->setStatusTip(tr("Convert and import audio sample values from a CSV data file")); + connect(action, SIGNAL(triggered()), this, SLOT(convertAudio())); + menu->addAction(action); + + action = new QAction(tr("Export Audio to Data File..."), this); + action->setStatusTip(tr("Export audio from selection into a CSV data file")); + connect(action, SIGNAL(triggered()), this, SLOT(exportAudioData())); + connect(this, SIGNAL(canExportAudio(bool)), action, SLOT(setEnabled(bool))); + menu->addAction(action); + + menu->addSeparator(); action = new QAction(tr("Export Image File..."), this); action->setStatusTip(tr("Export a single pane to an image file")); @@ -592,9 +617,15 @@ connect(this, SIGNAL(canExportImage(bool)), action, SLOT(setEnabled(bool))); menu->addAction(action); + action = new QAction(tr("Export SVG File..."), this); + action->setStatusTip(tr("Export a single pane to a scalable SVG image file")); + connect(action, SIGNAL(triggered()), this, SLOT(exportSVG())); + connect(this, SIGNAL(canExportImage(bool)), action, SLOT(setEnabled(bool))); + menu->addAction(action); + menu->addSeparator(); - action = new QAction(tr("Browse Recorded Audio Folder"), this); + action = new QAction(tr("Browse Recorded and Converted Audio"), this); action->setStatusTip(tr("Open the Recorded Audio folder in the system file browser")); connect(action, SIGNAL(triggered()), this, SLOT(browseRecordedAudio())); menu->addAction(action); @@ -627,7 +658,7 @@ action->setStatusTip(tr("Adjust the application preferences")); connect(action, SIGNAL(triggered()), this, SLOT(preferences())); menu->addAction(action); - + menu->addSeparator(); action = new QAction(il.load("exit"), tr("&Quit"), this); @@ -714,7 +745,7 @@ m_keyReference->registerShortcut(action); menu->addAction(action); m_rightButtonMenu->addAction(action); - + action = new QAction(tr("Select &Visible Range"), this); action->setShortcut(tr("Ctrl+Shift+A")); action->setStatusTip(tr("Select the time range corresponding to the current window width")); @@ -722,7 +753,7 @@ connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Select to &Start"), this); action->setShortcut(tr("Shift+Left")); action->setStatusTip(tr("Select from the start of the session to the current playback position")); @@ -730,7 +761,7 @@ connect(this, SIGNAL(canSelect(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Select to &End"), this); action->setShortcut(tr("Shift+Right")); action->setStatusTip(tr("Select from the current playback position to the end of the session")); @@ -753,35 +784,62 @@ m_keyReference->setCategory(tr("Tapping Time Instants")); action = new QAction(tr("&Insert Instant at Playback Position"), this); - action->setShortcut(tr("Enter")); + action->setShortcut(tr(";")); action->setStatusTip(tr("Insert a new time instant at the current playback position, in a new layer if necessary")); connect(action, SIGNAL(triggered()), this, SLOT(insertInstant())); connect(this, SIGNAL(canInsertInstant(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - // Laptop shortcut (no keypad Enter key) - QString shortcut(tr(";")); + // Historically this was the main shortcut for "Insert Instant at + // Playback Position". Note that Enter refers to the keypad key, + // rather than the Return key, so this doesn't actually exist on + // many keyboards now. Accordingly the alternative shortcut ";" + // has been promoted to primary, listed above. Same goes for the + // shifted version below + QString shortcut(tr("Enter")); connect(new QShortcut(shortcut, this), SIGNAL(activated()), this, SLOT(insertInstant())); m_keyReference->registerAlternativeShortcut(action, shortcut); action = new QAction(tr("Insert Instants at Selection &Boundaries"), this); - action->setShortcut(tr("Shift+Enter")); + action->setShortcut(tr("Shift+;")); action->setStatusTip(tr("Insert new time instants at the start and end of the current selected regions, in a new layer if necessary")); connect(action, SIGNAL(triggered()), this, SLOT(insertInstantsAtBoundaries())); connect(this, SIGNAL(canInsertInstantsAtBoundaries(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); + shortcut = QString(tr("Shift+Enter")); + connect(new QShortcut(shortcut, this), SIGNAL(activated()), + this, SLOT(insertInstantsAtBoundaries())); + m_keyReference->registerAlternativeShortcut(action, shortcut); + + // The previous two actions used shortcuts with the (keypad) Enter + // key, while this one I (bizarrely) switched from Enter to Return + // in September 2014. Let's make it consistent with the above by + // making the primary shortcut for it Ctrl+Shift+; and keeping + // both Return and Enter as synonyms for ; action = new QAction(tr("Insert Item at Selection"), this); - action->setShortcut(tr("Ctrl+Shift+Return")); + action->setShortcut(tr("Ctrl+Shift+;")); action->setStatusTip(tr("Insert a new note or region item corresponding to the current selection")); connect(action, SIGNAL(triggered()), this, SLOT(insertItemAtSelection())); connect(this, SIGNAL(canInsertItemAtSelection(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); + shortcut = QString(tr("Ctrl+Shift+Enter")); + connect(new QShortcut(shortcut, this), SIGNAL(activated()), + this, SLOT(insertItemAtSelection())); + m_keyReference->registerAlternativeShortcut(action, shortcut); + + shortcut = QString(tr("Ctrl+Shift+Return")); + connect(new QShortcut(shortcut, this), SIGNAL(activated()), + this, SLOT(insertItemAtSelection())); + // we had that one for historical compatibility, but let's not + // register it publicly; having three shortcuts for such an + // obscure function is really over-egging it + menu->addSeparator(); QMenu *numberingMenu = menu->addMenu(tr("Number New Instants with")); @@ -878,7 +936,7 @@ connect(this, SIGNAL(canScroll(bool)), m_scrollLeftAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_scrollLeftAction); menu->addAction(m_scrollLeftAction); - + m_scrollRightAction = new QAction(tr("Scroll &Right"), this); m_scrollRightAction->setShortcut(tr("Right")); m_scrollRightAction->setStatusTip(tr("Scroll the current pane to the right")); @@ -886,7 +944,7 @@ connect(this, SIGNAL(canScroll(bool)), m_scrollRightAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_scrollRightAction); menu->addAction(m_scrollRightAction); - + action = new QAction(tr("&Jump Left"), this); action->setShortcut(tr("Ctrl+Left")); action->setStatusTip(tr("Scroll the current pane a big step to the left")); @@ -894,7 +952,7 @@ connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("J&ump Right"), this); action->setShortcut(tr("Ctrl+Right")); action->setStatusTip(tr("Scroll the current pane a big step to the right")); @@ -910,7 +968,7 @@ connect(this, SIGNAL(canScroll(bool)), action, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(action); menu->addAction(action); - + action = new QAction(tr("Peek Right"), this); action->setShortcut(tr("Alt+Right")); action->setStatusTip(tr("Scroll the current pane to the right without moving the playback cursor or other panes")); @@ -931,7 +989,7 @@ connect(this, SIGNAL(canZoom(bool)), m_zoomInAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_zoomInAction); menu->addAction(m_zoomInAction); - + m_zoomOutAction = new QAction(il.load("zoom-out"), tr("Zoom &Out"), this); m_zoomOutAction->setShortcut(tr("Down")); @@ -940,7 +998,7 @@ connect(this, SIGNAL(canZoom(bool)), m_zoomOutAction, SLOT(setEnabled(bool))); m_keyReference->registerShortcut(m_zoomOutAction); menu->addAction(m_zoomOutAction); - + action = new QAction(tr("Restore &Default Zoom"), this); action->setStatusTip(tr("Restore the zoom level to the default")); connect(action, SIGNAL(triggered()), this, SLOT(zoomDefault())); @@ -1081,22 +1139,79 @@ #endif } +QString +MainWindow::shortcutFor(LayerFactory::LayerType layer, bool isPaneMenu) +{ + QString shortcutText; + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wswitch-enum" +#endif + + switch (layer) { + case LayerFactory::Waveform: + if (isPaneMenu) { + shortcutText = tr("W"); + } else { + shortcutText = tr("Shift+W"); + } + break; + + case LayerFactory::Spectrogram: + if (isPaneMenu) { + shortcutText = tr("G"); + } else { + shortcutText = tr("Shift+G"); + } + break; + + case LayerFactory::MelodicRangeSpectrogram: + if (isPaneMenu) { + shortcutText = tr("M"); + } else { + shortcutText = tr("Shift+M"); + } + break; + + case LayerFactory::PeakFrequencySpectrogram: + if (isPaneMenu) { + shortcutText = tr("K"); + } else { + shortcutText = tr("Shift+K"); + } + break; + + case LayerFactory::Spectrum: + if (isPaneMenu) { + shortcutText = tr("U"); + } else { + shortcutText = tr("Shift+U"); + } + break; + + default: + break; + } + + return shortcutText; +} + void MainWindow::setupPaneAndLayerMenus() { if (m_paneMenu) { - m_paneActions.clear(); - m_paneMenu->clear(); + m_paneActions.clear(); + m_paneMenu->clear(); } else { - m_paneMenu = menuBar()->addMenu(tr("&Pane")); + m_paneMenu = menuBar()->addMenu(tr("&Pane")); m_paneMenu->setTearOffEnabled(true); } if (m_layerMenu) { - m_layerActions.clear(); - m_layerMenu->clear(); + m_layerActions.clear(); + m_layerMenu->clear(); } else { - m_layerMenu = menuBar()->addMenu(tr("&Layer")); + m_layerMenu = menuBar()->addMenu(tr("&Layer")); m_layerMenu->setTearOffEnabled(true); } @@ -1127,36 +1242,34 @@ menu = m_layerMenu; -// menu->addSeparator(); - LayerFactory::LayerTypeSet emptyLayerTypes = - LayerFactory::getInstance()->getValidEmptyLayerTypes(); + LayerFactory::getInstance()->getValidEmptyLayerTypes(); for (LayerFactory::LayerTypeSet::iterator i = emptyLayerTypes.begin(); - i != emptyLayerTypes.end(); ++i) { - - QIcon icon; - QString mainText, tipText, channelText; - LayerFactory::LayerType type = *i; - QString name = LayerFactory::getInstance()->getLayerPresentationName(type); - - icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); - - mainText = tr("Add New %1 Layer").arg(name); - tipText = tr("Add a new empty layer of type %1").arg(name); - - action = new QAction(icon, mainText, this); - action->setStatusTip(tipText); - - if (type == LayerFactory::Text) { - action->setShortcut(tr("T")); + i != emptyLayerTypes.end(); ++i) { + + QIcon icon; + QString mainText, tipText, channelText; + LayerFactory::LayerType type = *i; + QString name = LayerFactory::getInstance()->getLayerPresentationName(type); + + icon = il.load(LayerFactory::getInstance()->getLayerIconName(type)); + + mainText = tr("Add New %1 Layer").arg(name); + tipText = tr("Add a new empty layer of type %1").arg(name); + + action = new QAction(icon, mainText, this); + action->setStatusTip(tipText); + + if (type == LayerFactory::Text) { + action->setShortcut(tr("T")); m_keyReference->registerShortcut(action); - } - - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - m_layerActions[action] = LayerConfiguration(type); - menu->addAction(action); + } + + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_layerActions[action] = LayerConfiguration(type); + menu->addAction(action); m_rightButtonLayerMenu->addAction(action); } @@ -1164,10 +1277,10 @@ menu->addSeparator(); LayerFactory::LayerType backgroundTypes[] = { - LayerFactory::Waveform, - LayerFactory::Spectrogram, - LayerFactory::MelodicRangeSpectrogram, - LayerFactory::PeakFrequencySpectrogram, + LayerFactory::Waveform, + LayerFactory::Spectrogram, + LayerFactory::MelodicRangeSpectrogram, + LayerFactory::PeakFrequencySpectrogram, LayerFactory::Spectrum }; @@ -1179,22 +1292,24 @@ } for (unsigned int i = 0; - i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { + i < sizeof(backgroundTypes)/sizeof(backgroundTypes[0]); ++i) { const int paneMenuType = 0, layerMenuType = 1; - for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { - - if (menuType == paneMenuType) menu = m_paneMenu; - else menu = m_layerMenu; - - QMenu *submenu = 0; + for (int menuType = paneMenuType; menuType <= layerMenuType; ++menuType) { + + if (menuType == paneMenuType) menu = m_paneMenu; + else menu = m_layerMenu; + + QMenu *submenu = 0; QIcon icon; - QString mainText, shortcutText, tipText, channelText; + QString mainText, tipText, channelText; LayerFactory::LayerType type = backgroundTypes[i]; bool mono = true; + QString shortcutText = shortcutFor(type, menuType == paneMenuType); + // Avoid warnings/errors with -Wextra because we aren't explicitly // handling all layer types (-Wall is OK with this because of the // default but the stricter level insists) @@ -1208,47 +1323,39 @@ icon = il.load("waveform"); mainText = tr("Add &Waveform"); if (menuType == paneMenuType) { - shortcutText = tr("W"); tipText = tr("Add a new pane showing a waveform view"); } else { - shortcutText = tr("Shift+W"); tipText = tr("Add a new layer showing a waveform view"); } mono = false; break; - + case LayerFactory::Spectrogram: icon = il.load("spectrogram"); mainText = tr("Add Spectro&gram"); if (menuType == paneMenuType) { - shortcutText = tr("G"); tipText = tr("Add a new pane showing a spectrogram"); } else { - shortcutText = tr("Shift+G"); tipText = tr("Add a new layer showing a spectrogram"); } break; - + case LayerFactory::MelodicRangeSpectrogram: icon = il.load("spectrogram"); mainText = tr("Add &Melodic Range Spectrogram"); if (menuType == paneMenuType) { - shortcutText = tr("M"); tipText = tr("Add a new pane showing a spectrogram set up for an overview of note pitches"); } else { - shortcutText = tr("Shift+M"); tipText = tr("Add a new layer showing a spectrogram set up for an overview of note pitches"); } break; - + case LayerFactory::PeakFrequencySpectrogram: icon = il.load("spectrogram"); mainText = tr("Add Pea&k Frequency Spectrogram"); if (menuType == paneMenuType) { - shortcutText = tr("K"); tipText = tr("Add a new pane showing a spectrogram set up for tracking frequencies"); } else { - shortcutText = tr("Shift+K"); tipText = tr("Add a new layer showing a spectrogram set up for tracking frequencies"); } break; @@ -1257,10 +1364,8 @@ icon = il.load("spectrum"); mainText = tr("Add Spectr&um"); if (menuType == paneMenuType) { - shortcutText = tr("U"); tipText = tr("Add a new pane showing a frequency spectrum"); } else { - shortcutText = tr("Shift+U"); tipText = tr("Add a new layer showing a frequency spectrum"); } break; @@ -1389,9 +1494,9 @@ m_layerActions[action] = LayerConfiguration(type, 0, 0); m_rightButtonLayerMenu->addAction(action); } - } - } - } + } + } + } } m_rightButtonLayerMenu->addSeparator(); @@ -1499,6 +1604,36 @@ } void +MainWindow::updateLayerShortcutsFor(Model *model) +{ + set seen; + + for (auto &a : m_paneActions) { + if (!a.second.sourceModel) continue; // empty pane/layer shortcut + auto type = a.second.layer; + if (a.second.sourceModel == model && seen.find(type) == seen.end()) { + a.first->setShortcut(shortcutFor(type, true)); + seen.insert(type); + } else { + a.first->setShortcut(QString()); + } + } + + seen.clear(); + + for (auto &a : m_layerActions) { + if (!a.second.sourceModel) continue; // empty pane/layer shortcut + auto type = a.second.layer; + if (a.second.sourceModel == model && seen.find(type) == seen.end()) { + a.first->setShortcut(shortcutFor(type, false)); + seen.insert(type); + } else { + a.first->setShortcut(QString()); + } + } +} + +void MainWindow::setupTransformsMenu() { if (m_transformsMenu) { @@ -1506,7 +1641,7 @@ m_transformActionsReverse.clear(); m_transformsMenu->clear(); } else { - m_transformsMenu = menuBar()->addMenu(tr("&Transform")); + m_transformsMenu = menuBar()->addMenu(tr("&Transform")); m_transformsMenu->setTearOffEnabled(true); m_transformsMenu->setSeparatorsCollapsible(true); } @@ -1639,9 +1774,9 @@ } for (unsigned int i = 0; i < transforms.size(); ++i) { - - QString name = transforms[i].name; - if (name == "") name = transforms[i].identifier; + + QString name = transforms[i].name; + if (name == "") name = transforms[i].identifier; // cerr << "Plugin Name: " << name << endl; @@ -1668,11 +1803,11 @@ .arg(output); } - QAction *action = new QAction(tr("%1...").arg(name), this); - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - m_transformActions[action] = transforms[i].identifier; + QAction *action = new QAction(tr("%1...").arg(name), this); + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + m_transformActions[action] = transforms[i].identifier; m_transformActionsReverse[transforms[i].identifier] = action; - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); action->setStatusTip(transforms[i].longDescription); @@ -1777,6 +1912,11 @@ connect(action, SIGNAL(triggered()), this, SLOT(website())); menu->addAction(action); + action = new QAction(tr("What's &New?"), this); + action->setStatusTip(tr("Show changes in this release of %1").arg(name)); + connect(action, SIGNAL(triggered()), this, SLOT(whatsNew())); + menu->addAction(action); + action = new QAction(tr("&About %1").arg(name), this); action->setStatusTip(tr("Show information about %1").arg(name)); connect(action, SIGNAL(triggered()), this, SLOT(about())); @@ -1801,7 +1941,7 @@ action->shortcut().toString(), tr("Re-open the current or most recently opened file")); } - m_recentFilesMenu->addAction(action); + m_recentFilesMenu->addAction(action); } } @@ -1879,7 +2019,7 @@ } else { ti->second->setShortcut(QString("")); } - m_recentTransformsMenu->addAction(ti->second); + m_recentTransformsMenu->addAction(ti->second); } } @@ -1906,49 +2046,49 @@ for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { - Pane *pane = m_paneStack->getPane(i); - if (!pane) continue; - - for (int j = 0; j < pane->getLayerCount(); ++j) { - - Layer *layer = pane->getLayer(j); - if (!layer) continue; - if (observedLayers.find(layer) != observedLayers.end()) { -// cerr << "found duplicate layer " << layer << endl; - continue; - } - -// cerr << "found new layer " << layer << " (name = " -// << layer->getLayerPresentationName() << ")" << endl; - - orderedLayers.push_back(layer); - observedLayers.insert(layer); + Pane *pane = m_paneStack->getPane(i); + if (!pane) continue; + + for (int j = 0; j < pane->getLayerCount(); ++j) { + + Layer *layer = pane->getLayer(j); + if (!layer) continue; + if (observedLayers.find(layer) != observedLayers.end()) { +// cerr << "found duplicate layer " << layer << endl; + continue; + } + +// cerr << "found new layer " << layer << " (name = " +// << layer->getLayerPresentationName() << ")" << endl; + + orderedLayers.push_back(layer); + observedLayers.insert(layer); if (factory->isLayerSliceable(layer)) { sliceableLayers.insert(layer); } - } + } } map observedNames; for (size_t i = 0; i < orderedLayers.size(); ++i) { - + Layer *layer = orderedLayers[i]; - QString name = layer->getLayerPresentationName(); - int n = ++observedNames[name]; - if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); - - QIcon icon = il.load(factory->getLayerIconName + QString name = layer->getLayerPresentationName(); + int n = ++observedNames[name]; + if (n > 1) name = QString("%1 <%2>").arg(name).arg(n); + + QIcon icon = il.load(factory->getLayerIconName (factory->getLayerType(layer))); - QAction *action = new QAction(icon, name, this); - connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); - connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); - m_existingLayerActions[action] = layer; - - m_existingLayersMenu->addAction(action); + QAction *action = new QAction(icon, name, this); + connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); + connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); + m_existingLayerActions[action] = layer; + + m_existingLayersMenu->addAction(action); if (sliceableLayers.find(layer) != sliceableLayers.end()) { action = new QAction(icon, name, this); @@ -1998,11 +2138,18 @@ m_playAction = toolbar->addAction(il.load("playpause"), tr("Play / Pause")); m_playAction->setCheckable(true); + + /*: This text is a shortcut label referring to the space-bar on + the keyboard. It probably should not be translated, and + certainly should not be translated as if referring to an empty + void or to the extra-terrestrial universe. + */ m_playAction->setShortcut(tr("Space")); + m_playAction->setStatusTip(tr("Start or stop playback from the current position")); connect(m_playAction, SIGNAL(triggered()), this, SLOT(play())); connect(m_playSource, SIGNAL(playStatusChanged(bool)), - m_playAction, SLOT(setChecked(bool))); + m_playAction, SLOT(setChecked(bool))); connect(m_playSource, SIGNAL(playStatusChanged(bool)), this, SLOT(playStatusChanged(bool))); connect(this, SIGNAL(canPlay(bool)), m_playAction, SLOT(setEnabled(bool))); @@ -2034,7 +2181,7 @@ m_recordAction->setStatusTip(tr("Record a new audio file")); connect(m_recordAction, SIGNAL(triggered()), this, SLOT(record())); connect(m_recordTarget, SIGNAL(recordStatusChanged(bool)), - m_recordAction, SLOT(setChecked(bool))); + m_recordAction, SLOT(setChecked(bool))); connect(this, SIGNAL(canRecord(bool)), m_recordAction, SLOT(setEnabled(bool))); @@ -2120,7 +2267,6 @@ menu->addSeparator(); m_rightButtonPlaybackMenu->addAction(m_playAction); - m_rightButtonPlaybackMenu->addAction(m_recordAction); m_rightButtonPlaybackMenu->addAction(m_playSelectionAction); m_rightButtonPlaybackMenu->addAction(m_playLoopAction); m_rightButtonPlaybackMenu->addAction(m_soloAction); @@ -2197,7 +2343,7 @@ m_keyReference->setCategory(tr("Tool Selection")); action = toolbar->addAction(il.load("select"), - tr("Select")); + tr("Select")); action->setCheckable(true); action->setShortcut(tr("2")); action->setStatusTip(tr("Select ranges")); @@ -2226,7 +2372,7 @@ m_keyReference->setCategory(tr("Tool Selection")); action = toolbar->addAction(il.load("move"), - tr("Edit")); + tr("Edit")); action->setCheckable(true); action->setShortcut(tr("3")); action->setStatusTip(tr("Edit items in layer")); @@ -2247,7 +2393,7 @@ m_keyReference->setCategory(tr("Tool Selection")); action = toolbar->addAction(il.load("draw"), - tr("Draw")); + tr("Draw")); action->setCheckable(true); action->setShortcut(tr("4")); action->setStatusTip(tr("Draw new items in layer")); @@ -2265,7 +2411,7 @@ m_keyReference->setCategory(tr("Tool Selection")); action = toolbar->addAction(il.load("erase"), - tr("Erase")); + tr("Erase")); action->setCheckable(true); action->setShortcut(tr("5")); action->setStatusTip(tr("Erase items from layer")); @@ -2340,19 +2486,19 @@ (haveCurrentPane && (currentLayer != 0)); bool havePlayTarget = - (m_playTarget != 0 || m_audioIO != 0); + (m_playTarget != 0 || m_audioIO != 0); bool haveSelection = - (m_viewManager && - !m_viewManager->getSelections().empty()); + (m_viewManager && + !m_viewManager->getSelections().empty()); bool haveCurrentEditableLayer = - (haveCurrentLayer && - currentLayer->isLayerEditable()); + (haveCurrentLayer && + currentLayer->isLayerEditable()); bool haveCurrentTimeInstantsLayer = - (haveCurrentLayer && - dynamic_cast(currentLayer)); + (haveCurrentLayer && + dynamic_cast(currentLayer)); bool haveCurrentTimeValueLayer = - (haveCurrentLayer && - dynamic_cast(currentLayer)); + (haveCurrentLayer && + dynamic_cast(currentLayer)); bool alignMode = m_viewManager && m_viewManager->getAlignMode(); emit canChangeSolo(havePlayTarget && !alignMode); @@ -2398,8 +2544,8 @@ MainWindow::updateDescriptionLabel() { if (!getMainModel()) { - m_descriptionLabel->setText(tr("No audio file loaded.")); - return; + m_descriptionLabel->setText(tr("No audio file loaded.")); + return; } QString description; @@ -2411,15 +2557,15 @@ if (m_playSource) tsr = m_playSource->getDeviceSampleRate(); if (ssr != tsr) { - description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); + description = tr("%1Hz (resampling to %2Hz)").arg(ssr).arg(tsr); } else { - description = QString("%1Hz").arg(ssr); + description = QString("%1Hz").arg(ssr); } description = QString("%1 - %2") - .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) - .toText(false).c_str()) - .arg(description); + .arg(RealTime::frame2RealTime(getMainModel()->getEndFrame(), ssr) + .toText(false).c_str()) + .arg(description); m_descriptionLabel->setText(description); } @@ -2480,11 +2626,11 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, ReplaceSession) == FileOpenFailed) { + if (openAudio(path, ReplaceSession) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); + } } } @@ -2494,11 +2640,11 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { + if (openAudio(path, CreateAdditionalModel) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); + } } } @@ -2508,11 +2654,11 @@ QString path = getOpenFileName(FileFinder::AudioFile); if (path != "") { - if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { + if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { emit hideSplash(); - QMessageBox::critical(this, tr("Failed to open file"), - tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); - } + QMessageBox::critical(this, tr("Failed to open file"), + tr("File open failed

Audio file \"%1\" could not be opened").arg(path)); + } } } @@ -2612,19 +2758,19 @@ if (selections.size() == 1) { - QStringList items; - items << tr("Export the selected region only") - << tr("Export the whole audio file"); - - bool ok = false; - QString item = ListInputDialog::getItem - (this, tr("Select region to export"), - tr("Which region from the original audio file do you want to export?"), - items, 0, &ok); - - if (!ok || item.isEmpty()) return; - - if (item == items[0]) selectionToWrite = &ms; + QStringList items; + items << tr("Export the selected region only") + << tr("Export the whole audio file"); + + bool ok = false; + QString item = ListInputDialog::getItem + (this, tr("Select region to export"), + tr("Which region from the original audio file do you want to export?"), + items, 0, &ok); + + if (!ok || item.isEmpty()) return; + + if (item == items[0]) selectionToWrite = &ms; } else if (selections.size() > 1) { @@ -2639,7 +2785,7 @@ (this, tr("Select region to export"), tr("Multiple regions of the original audio file are selected.\nWhat do you want to export?"), items, 0, &ok); - + if (!ok || item.isEmpty()) return; if (item == items[0]) { @@ -2654,46 +2800,54 @@ if (multiple) { // Can only happen when asData false - int n = 1; - QString base = path; - base.replace(".wav", ""); - - for (MultiSelection::SelectionList::iterator i = selections.begin(); - i != selections.end(); ++i) { - - MultiSelection subms; - subms.setSelection(*i); - - QString subpath = QString("%1.%2.wav").arg(base).arg(n); - ++n; - - if (QFileInfo(subpath).exists()) { - error = tr("Fragment file %1 already exists, aborting").arg(subpath); - break; - } - - WavFileWriter subwriter(subpath, + int n = 1; + QString base = path; + base.replace(".wav", ""); + + for (MultiSelection::SelectionList::iterator i = selections.begin(); + i != selections.end(); ++i) { + + MultiSelection subms; + subms.setSelection(*i); + + QString subpath = QString("%1.%2.wav").arg(base).arg(n); + ++n; + + if (QFileInfo(subpath).exists()) { + error = tr("Fragment file %1 already exists, aborting").arg(subpath); + break; + } + + WavFileWriter subwriter(subpath, model->getSampleRate(), model->getChannelCount(), WavFileWriter::WriteToTemporary); subwriter.writeModel(model, &subms); - ok = subwriter.isOK(); - - if (!ok) { - error = subwriter.getError(); - break; - } - } - } + ok = subwriter.isOK(); + + if (!ok) { + error = subwriter.getError(); + break; + } + } + } } if (!multiple) { if (asData) { - CSVFileWriter writer(path, model, + stop(); + ProgressDialog dialog { + QObject::tr("Exporting audio data..."), + true, + 0, + this, + Qt::ApplicationModal + }; + CSVFileWriter writer(path, model, &dialog, ((QFileInfo(path).suffix() == "csv") ? "," : "\t")); if (selectionToWrite) { - writer.writeSelection(selectionToWrite); + writer.writeSelection(*selectionToWrite); } else { writer.write(); } @@ -2718,7 +2872,70 @@ m_recentFiles.addFile(path); } } else { - QMessageBox::critical(this, tr("Failed to write file"), error); + QMessageBox::critical(this, tr("Failed to write file"), error); + } +} + +void +MainWindow::convertAudio() +{ + QString path = getOpenFileName(FileFinder::CSVFile); + if (path == "") return; + + sv_samplerate_t defaultRate = 44100; + + CSVFormat format(path); + format.setModelType(CSVFormat::WaveFileModel); + format.setTimingType(CSVFormat::ImplicitTiming); + format.setTimeUnits(CSVFormat::TimeAudioFrames); + format.setSampleRate(defaultRate); // as a default for the dialog + + { + CSVAudioFormatDialog *dialog = new CSVAudioFormatDialog(this, format); + if (dialog->exec() != QDialog::Accepted) { + delete dialog; + return; + } + format = dialog->getFormat(); + delete dialog; + } + + FileOpenStatus status = FileOpenSucceeded; + + ProgressDialog *progress = new ProgressDialog + (tr("Converting audio data..."), true, 0, this, Qt::ApplicationModal); + + WaveFileModel *model = qobject_cast + (DataFileReaderFactory::loadCSV + (path, format, + getMainModel() ? getMainModel()->getSampleRate() : defaultRate, + progress)); + + if (progress->wasCancelled()) { + + delete model; + status = FileOpenCancelled; + + } else if (!model || !model->isOK()) { + + delete model; + status = FileOpenFailed; + + } else { + + status = addOpenedAudioModel(path, + model, + CreateAdditionalModel, + getDefaultSessionTemplate(), + false); + } + + delete progress; + + if (status == FileOpenFailed) { + emit hideSplash(); + QMessageBox::critical(this, tr("Failed to open file"), + tr("File open failed

Audio data file %1 could not be opened.").arg(path)); } } @@ -2728,15 +2945,15 @@ Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { - // shouldn't happen, as the menu action should have been disabled - cerr << "WARNING: MainWindow::importLayer: no current pane" << endl; - return; + // shouldn't happen, as the menu action should have been disabled + cerr << "WARNING: MainWindow::importLayer: no current pane" << endl; + return; } if (!getMainModel()) { - // shouldn't happen, as the menu action should have been disabled - cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << endl; - return; + // shouldn't happen, as the menu action should have been disabled + cerr << "WARNING: MainWindow::importLayer: No main model -- hence no default sample rate available" << endl; + return; } QString path = getOpenFileName(FileFinder::LayerFile); @@ -2860,17 +3077,15 @@ if (!pane) return; QString path = getSaveFileName(FileFinder::ImageFile); - if (path == "") return; - if (QFileInfo(path).suffix() == "") path += ".png"; - + bool haveSelection = m_viewManager && !m_viewManager->getSelections().empty(); QSize total, visible, selected; - total = pane->getImageSize(); - visible = pane->getImageSize(pane->getFirstVisibleFrame(), - pane->getLastVisibleFrame()); + total = pane->getRenderedImageSize(); + visible = pane->getRenderedPartImageSize(pane->getFirstVisibleFrame(), + pane->getLastVisibleFrame()); sv_frame_t sf0 = 0, sf1 = 0; @@ -2880,7 +3095,7 @@ MultiSelection::SelectionList::iterator e = selections.end(); --e; sf1 = e->getEndFrame(); - selected = pane->getImageSize(sf0, sf1); + selected = pane->getRenderedPartImageSize(sf0, sf1); } QStringList items; @@ -2909,7 +3124,7 @@ if (!haveSelection) { lid->setItemAvailability(2, false); } - if (total.width() > 32767) { // appears to be the limit of a QImage + if (total.width() > 32767) { // appears to be limit of a QImage lid->setItemAvailability(0, false); lid->setFootnote(tr("Note: the whole pane is too wide to be exported as a single image.")); } @@ -2917,24 +3132,24 @@ bool ok = lid->exec(); QString item = lid->getCurrentString(); delete lid; - + if (!ok || item.isEmpty()) return; settings.setValue("lastimageexportregion", deflt); QImage *image = 0; - + if (item == items[0]) { - image = pane->toNewImage(); + image = pane->renderToNewImage(); } else if (item == items[1]) { - image = pane->toNewImage(pane->getFirstVisibleFrame(), - pane->getLastVisibleFrame()); + image = pane->renderPartToNewImage(pane->getFirstVisibleFrame(), + pane->getLastVisibleFrame()); } else if (haveSelection) { - image = pane->toNewImage(sf0, sf1); + image = pane->renderPartToNewImage(sf0, sf1); } - + if (!image) return; - + if (!image->save(path, "PNG")) { QMessageBox::critical(this, tr("Failed to save image file"), tr("Failed to save image file %1").arg(path)); @@ -2944,11 +3159,79 @@ } void +MainWindow::exportSVG() +{ + Pane *pane = m_paneStack->getCurrentPane(); + if (!pane) return; + + QString path = getSaveFileName(FileFinder::SVGFile); + if (path == "") return; + if (QFileInfo(path).suffix() == "") path += ".svg"; + + bool haveSelection = m_viewManager && !m_viewManager->getSelections().empty(); + + sv_frame_t sf0 = 0, sf1 = 0; + + if (haveSelection) { + MultiSelection::SelectionList selections = m_viewManager->getSelections(); + sf0 = selections.begin()->getStartFrame(); + MultiSelection::SelectionList::iterator e = selections.end(); + --e; + sf1 = e->getEndFrame(); + } + + QStringList items; + items << tr("Export the whole pane"); + items << tr("Export the visible area only"); + items << tr("Export the selection extent"); + + QSettings settings; + settings.beginGroup("MainWindow"); + int deflt = settings.value("lastsvgexportregion", 0).toInt(); + if (deflt == 2 && !haveSelection) deflt = 1; + + ListInputDialog *lid = new ListInputDialog + (this, tr("Select region to export"), + tr("Which region of the current pane do you want to export as a scalable SVG image?"), + items, deflt); + + if (!haveSelection) { + lid->setItemAvailability(2, false); + } + + bool ok = lid->exec(); + QString item = lid->getCurrentString(); + delete lid; + + if (!ok || item.isEmpty()) return; + + settings.setValue("lastsvgexportregion", deflt); + + bool result = false; + + if (item == items[0]) { + result = pane->renderToSvgFile(path ); + } else if (item == items[1]) { + result = pane->renderPartToSvgFile(path, + pane->getFirstVisibleFrame(), + pane->getLastVisibleFrame()); + } else if (haveSelection) { + result = pane->renderPartToSvgFile(path, sf0, sf1); + } + + if (!result) { + QMessageBox::critical(this, tr("Failed to save SVG file"), + tr("Failed to save SVG file %1").arg(path)); + } +} + +void MainWindow::browseRecordedAudio() { if (!m_recordTarget) return; - QString path = m_recordTarget->getRecordFolder(); + QString path = RecordDirectory::getRecordContainerDirectory(); + if (path == "") path = RecordDirectory::getRecordDirectory(); if (path == "") return; openLocalFolder(path); @@ -2968,8 +3251,8 @@ this, SLOT(contextHelpChanged(const QString &))); if (!m_timeRulerLayer) { - m_timeRulerLayer = m_document->createMainModelLayer - (LayerFactory::TimeRuler); + m_timeRulerLayer = m_document->createMainModelLayer + (LayerFactory::TimeRuler); } m_document->addLayerToView(pane, m_timeRulerLayer); @@ -3001,29 +3284,29 @@ while (m_paneStack->getPaneCount() > 0) { - Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); - - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + Pane *pane = m_paneStack->getPane(m_paneStack->getPaneCount() - 1); + + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); + } + + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); } while (m_paneStack->getHiddenPaneCount() > 0) { - Pane *pane = m_paneStack->getHiddenPane - (m_paneStack->getHiddenPaneCount() - 1); - - while (pane->getLayerCount() > 0) { - m_document->removeLayerFromView - (pane, pane->getLayer(pane->getLayerCount() - 1)); - } - - m_overview->unregisterView(pane); - m_paneStack->deletePane(pane); + Pane *pane = m_paneStack->getHiddenPane + (m_paneStack->getHiddenPaneCount() - 1); + + while (pane->getLayerCount() > 0) { + m_document->removeLayerFromView + (pane, pane->getLayer(pane->getLayerCount() - 1)); + } + + m_overview->unregisterView(pane); + m_paneStack->deletePane(pane); } delete m_layerTreeDialog.data(); @@ -3111,9 +3394,9 @@ QAction *action = dynamic_cast(obj); if (!action) { - cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" - << endl; - return; + cerr << "WARNING: MainWindow::openRecentFile: sender is not an action" + << endl; + return; } QString path = action->text(); @@ -3142,9 +3425,9 @@ QAction *action = qobject_cast(s); if (!action) { - cerr << "WARNING: MainWindow::applyTemplate: sender is not an action" - << endl; - return; + cerr << "WARNING: MainWindow::applyTemplate: sender is not an action" + << endl; + return; } QString n = action->objectName(); @@ -3203,6 +3486,7 @@ tr("Template file exists

The template \"%1\" already exists.
Overwrite it?").arg(name), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel) != QMessageBox::Ok) { + delete d; return; } } @@ -3213,13 +3497,15 @@ } } } + + delete d; } void MainWindow::manageSavedTemplates() { ResourceFinder rf; - QDesktopServices::openUrl("file:" + rf.getResourceSaveDir("templates")); + openLocalFolder(rf.getResourceSaveDir("templates")); } void @@ -3297,14 +3583,14 @@ if (m_openingAudioFile) { // cerr << "Busy - ignoring close event" << endl; - e->ignore(); - return; + e->ignore(); + return; } if (!m_abandoning && !checkSaveModified()) { // cerr << "Close refused by user - ignoring close event" << endl; - e->ignore(); - return; + e->ignore(); + return; } QSettings settings; @@ -3318,8 +3604,7 @@ if (m_preferencesDialog && m_preferencesDialog->isVisible()) { - closeSession(); // otherwise we'll have to wait for prefs changes - m_preferencesDialog->applicationClosing(false); + m_preferencesDialog->applicationClosing(true); } closeSession(); @@ -3393,22 +3678,22 @@ emit hideSplash(); int button = - QMessageBox::warning(this, - tr("Session modified"), - tr("Session modified

The current session has been modified.
Do you want to save it?"), - QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, + QMessageBox::warning(this, + tr("Session modified"), + tr("Session modified

The current session has been modified.
Do you want to save it?"), + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::Yes); if (button == QMessageBox::Yes) { - saveSession(); - if (m_documentModified) { // save failed -- don't proceed! - return false; - } else { + saveSession(); + if (m_documentModified) { // save failed -- don't proceed! + return false; + } else { return true; // saved, so it's safe to continue now } } else if (button == QMessageBox::No) { - m_documentModified = false; // so we know to abandon it - return true; + m_documentModified = false; // so we know to abandon it + return true; } // else cancel @@ -3455,15 +3740,15 @@ MainWindow::saveSession() { if (m_sessionFile != "") { - if (!saveSessionFile(m_sessionFile)) { - QMessageBox::critical(this, tr("Failed to save file"), - tr("Save failed

Session file \"%1\" could not be saved.").arg(m_sessionFile)); - } else { - CommandHistory::getInstance()->documentSaved(); - documentRestored(); - } + if (!saveSessionFile(m_sessionFile)) { + QMessageBox::critical(this, tr("Failed to save file"), + tr("Save failed

Session file \"%1\" could not be saved.").arg(m_sessionFile)); + } else { + CommandHistory::getInstance()->documentSaved(); + documentRestored(); + } } else { - saveSessionAs(); + saveSessionAs(); } } @@ -3479,15 +3764,15 @@ if (path == "") return; if (!saveSessionFile(path)) { - QMessageBox::critical(this, tr("Failed to save file"), - tr("Save failed

Session file \"%1\" could not be saved.").arg(path)); + QMessageBox::critical(this, tr("Failed to save file"), + tr("Save failed

Session file \"%1\" could not be saved.").arg(path)); } else { - setWindowTitle(tr("%1: %2") + setWindowTitle(tr("%1: %2") .arg(QApplication::applicationName()) - .arg(QFileInfo(path).fileName())); - m_sessionFile = path; - CommandHistory::getInstance()->documentSaved(); - documentRestored(); + .arg(QFileInfo(path).fileName())); + m_sessionFile = path; + CommandHistory::getInstance()->documentSaved(); + documentRestored(); m_recentFiles.addFile(path); emit activity(tr("Save session as \"%1\"").arg(path)); } @@ -3498,18 +3783,33 @@ { MainWindowBase::preferenceChanged(name); - if (name == "Background Mode" && m_viewManager) { - if (m_viewManager->getGlobalDarkBackground()) { - m_panLayer->setBaseColour - (ColourDatabase::getInstance()->getColourIndex(tr("Bright Green"))); - } else { - m_panLayer->setBaseColour - (ColourDatabase::getInstance()->getColourIndex(tr("Green"))); - } + if (name == "Background Mode") { + coloursChanged(); } } void +MainWindow::coloursChanged() +{ + QSettings settings; + settings.beginGroup("Preferences"); + QString defaultColourName(tr("Green")); + if (m_viewManager && m_viewManager->getGlobalDarkBackground()) { + defaultColourName = tr("Bright Green"); + } + ColourDatabase *cdb = ColourDatabase::getInstance(); + QColor colour = QColor + (settings.value("overview-colour", + cdb->getColour(defaultColourName).name()).toString()); + settings.endGroup(); + + int index = cdb->getColourIndex(colour); + if (index >= 0) { + m_panLayer->setBaseColour(index); + } +} + +void MainWindow::propertyStacksResized(int width) { // SVDEBUG << "MainWindow::propertyStacksResized(" << width << ")" << endl; @@ -3532,22 +3832,22 @@ cerr << "addPane: sender is " << s << ", action is " << action << ", name " << action->text() << endl; if (!action) { - cerr << "WARNING: MainWindow::addPane: sender is not an action" - << endl; - return; + cerr << "WARNING: MainWindow::addPane: sender is not an action" + << endl; + return; } PaneActionMap::iterator i = m_paneActions.find(action); if (i == m_paneActions.end()) { - cerr << "WARNING: MainWindow::addPane: unknown action " - << action->objectName() << endl; + cerr << "WARNING: MainWindow::addPane: unknown action " + << action->objectName() << endl; cerr << "known actions are:" << endl; for (PaneActionMap::const_iterator i = m_paneActions.begin(); i != m_paneActions.end(); ++i) { cerr << i->first << ", name " << i->first->text() << endl; } - return; + return; } addPane(i->second, action->text()); @@ -3572,15 +3872,15 @@ if (configuration.layer != LayerFactory::TimeRuler && configuration.layer != LayerFactory::Spectrum) { - if (!m_timeRulerLayer) { -// cerr << "no time ruler layer, creating one" << endl; - m_timeRulerLayer = m_document->createMainModelLayer - (LayerFactory::TimeRuler); - } - -// SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl; - - m_document->addLayerToView(pane, m_timeRulerLayer); + if (!m_timeRulerLayer) { +// cerr << "no time ruler layer, creating one" << endl; + m_timeRulerLayer = m_document->createMainModelLayer + (LayerFactory::TimeRuler); + } + +// SVDEBUG << "adding time ruler layer " << m_timeRulerLayer << endl; + + m_document->addLayerToView(pane, m_timeRulerLayer); } Layer *newLayer = m_document->createLayer(configuration.layer); @@ -3634,25 +3934,25 @@ QAction *action = dynamic_cast(s); if (!action) { - cerr << "WARNING: MainWindow::addLayer: sender is not an action" - << endl; - return; + cerr << "WARNING: MainWindow::addLayer: sender is not an action" + << endl; + return; } Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { - cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; - return; + cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; + return; } ExistingLayerActionMap::iterator ei = m_existingLayerActions.find(action); if (ei != m_existingLayerActions.end()) { - Layer *newLayer = ei->second; - m_document->addLayerToView(pane, newLayer); - m_paneStack->setCurrentLayer(pane, newLayer); - return; + Layer *newLayer = ei->second; + m_document->addLayerToView(pane, newLayer); + m_paneStack->setCurrentLayer(pane, newLayer); + return; } ei = m_sliceActions.find(action); @@ -3670,38 +3970,38 @@ connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), dest, SLOT(modelAboutToBeDeleted(Model *))); } - m_document->addLayerToView(pane, newLayer); - m_paneStack->setCurrentLayer(pane, newLayer); - return; + m_document->addLayerToView(pane, newLayer); + m_paneStack->setCurrentLayer(pane, newLayer); + return; } TransformActionMap::iterator i = m_transformActions.find(action); if (i == m_transformActions.end()) { - LayerActionMap::iterator i = m_layerActions.find(action); - - if (i == m_layerActions.end()) { - cerr << "WARNING: MainWindow::addLayer: unknown action " - << action->objectName() << endl; - return; - } - - LayerFactory::LayerType type = i->second.layer; - - LayerFactory::LayerTypeSet emptyTypes = - LayerFactory::getInstance()->getValidEmptyLayerTypes(); - - Layer *newLayer = 0; - - if (emptyTypes.find(type) != emptyTypes.end()) { - - newLayer = m_document->createEmptyLayer(type); + LayerActionMap::iterator i = m_layerActions.find(action); + + if (i == m_layerActions.end()) { + cerr << "WARNING: MainWindow::addLayer: unknown action " + << action->objectName() << endl; + return; + } + + LayerFactory::LayerType type = i->second.layer; + + LayerFactory::LayerTypeSet emptyTypes = + LayerFactory::getInstance()->getValidEmptyLayerTypes(); + + Layer *newLayer = 0; + + if (emptyTypes.find(type) != emptyTypes.end()) { + + newLayer = m_document->createEmptyLayer(type); if (newLayer) { m_toolActions[ViewManager::DrawMode]->trigger(); } - } else { + } else { Model *model = i->second.sourceModel; @@ -3746,7 +4046,7 @@ m_paneStack->setCurrentLayer(pane, newLayer); } - return; + return; } //!!! want to do something like this, but it's not supported in @@ -3755,11 +4055,11 @@ int channel = -1; // pick up the default channel from any existing layers on the same pane for (int j = 0; j < pane->getLayerCount(); ++j) { - int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); - if (c != -1) { - channel = c; - break; - } + int c = LayerFactory::getInstance()->getChannel(pane->getLayer(j)); + if (c != -1) { + channel = c; + break; + } } */ @@ -3777,12 +4077,21 @@ { Pane *pane = m_paneStack->getCurrentPane(); if (!pane) { - cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; - return; + cerr << "WARNING: MainWindow::addLayer: no current pane" << endl; + return; } - Transform transform = TransformFactory::getInstance()-> - getDefaultTransformFor(transformId); + Transform transform; + try { + transform = TransformFactory::getInstance()-> + getDefaultTransformFor(transformId); + } catch (std::exception &e) { // e.g. Piper server failure + QMessageBox::critical + (this, tr("Failed to query transform attributes"), + tr("Failed to query transform attributes

Plugin or server error: %1

") + .arg(e.what())); + return; + } std::vector candidateInputModels = m_document->getTransformInputModels(); @@ -3811,6 +4120,8 @@ if (defaultInputModel) break; } + AggregateWaveModel *aggregate = 0; + if (candidateInputModels.size() > 1) { // Add an aggregate model as another option AggregateWaveModel::ChannelSpecList sl; @@ -3822,10 +4133,9 @@ } } if (!sl.empty()) { - AggregateWaveModel *aggregate = new AggregateWaveModel(sl); + aggregate = new AggregateWaveModel(sl); aggregate->setObjectName(tr("Multiplex all of the above")); candidateInputModels.push_back(aggregate); - //!!! but it leaks } } @@ -3847,19 +4157,36 @@ duration, &configurator); + if (aggregate) { + if (input.getModel() == aggregate) { + aggregate->setObjectName(tr("Multiplexed audio")); + m_document->addAggregateModel(aggregate); + } else { + aggregate->aboutToDelete(); + delete aggregate; + } + } + if (!input.getModel()) return; // SVDEBUG << "MainWindow::addLayer: Input model is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl << "transform:" << endl << transform.toXmlString() << endl; - Layer *newLayer = m_document->createDerivedLayer(transform, input); - - if (newLayer) { - m_document->addLayerToView(pane, newLayer); - m_document->setChannel(newLayer, input.getChannel()); - m_recentTransforms.add(transformId); - m_paneStack->setCurrentLayer(pane, newLayer); + try { + Layer *newLayer = m_document->createDerivedLayer(transform, input); + if (newLayer) { + m_document->addLayerToView(pane, newLayer); + m_document->setChannel(newLayer, input.getChannel()); + m_recentTransforms.add(transformId); + m_paneStack->setCurrentLayer(pane, newLayer); + } + } catch (std::exception &e) { // e.g. Piper server failure + QMessageBox::critical + (this, tr("Transform failed"), + tr("Failed to run transform

Plugin or server error: %1

") + .arg(e.what())); + return; } - + updateMenuStates(); } @@ -3868,18 +4195,18 @@ { Pane *pane = m_paneStack->getCurrentPane(); if (pane) { - Layer *layer = pane->getSelectedLayer(); - if (layer) { - bool ok = false; - QString newName = QInputDialog::getText - (this, tr("Rename Layer"), - tr("New name for this layer:"), - QLineEdit::Normal, layer->objectName(), &ok); - if (ok) { - layer->setPresentationName(newName); - setupExistingLayersMenus(); - } - } + Layer *layer = pane->getSelectedLayer(); + if (layer) { + bool ok = false; + QString newName = QInputDialog::getText + (this, tr("Rename Layer"), + tr("New name for this layer:"), + QLineEdit::Normal, layer->objectName(), &ok); + if (ok) { + layer->setPresentationName(newName); + setupExistingLayersMenus(); + } + } } } @@ -3914,9 +4241,9 @@ if (!m_viewManager) return; if (action) { - m_viewManager->setAlignMode(action->isChecked()); + m_viewManager->setAlignMode(action->isChecked()); } else { - m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); + m_viewManager->setAlignMode(!m_viewManager->getAlignMode()); } if (m_viewManager->getAlignMode()) { @@ -3942,8 +4269,8 @@ for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { - Pane *pane = m_paneStack->getPane(i); - if (!pane) continue; + Pane *pane = m_paneStack->getPane(i); + if (!pane) continue; pane->update(); } @@ -4036,24 +4363,29 @@ } } - if (containsMainModel) { - m_panLayer->setModel(getMainModel()); - return; - } - + bool panLayerSet = false; + for (int i = pane->getLayerCount(); i > 0; ) { --i; Layer *layer = pane->getLayer(i); - if (LayerFactory::getInstance()->getLayerType(layer) == - LayerFactory::Waveform) { - RangeSummarisableTimeValueModel *tvm = - dynamic_cast(layer->getModel()); - if (tvm) { + RangeSummarisableTimeValueModel *tvm = + qobject_cast(layer->getModel()); + if (tvm) { + auto type = LayerFactory::getInstance()->getLayerType(layer); + if (type != LayerFactory::TimeRuler) { + updateLayerShortcutsFor(tvm); + } + if (type == LayerFactory::Waveform) { m_panLayer->setModel(tvm); - return; + panLayerSet = true; + break; } } } + + if (containsMainModel && !panLayerSet) { + m_panLayer->setModel(getMainModel()); + } } void @@ -4137,10 +4469,9 @@ } void -MainWindow::outputLevelsChanged(float left, float right) +MainWindow::monitoringLevelsChanged(float left, float right) { - m_fader->setPeakLeft(left); - m_fader->setPeakRight(right); + m_mainLevelPan->setMonitoringLevels(left, right); } void @@ -4178,6 +4509,16 @@ shownOnce = true; } +/* +void +MainWindow::betaReleaseWarning() +{ + QMessageBox::information + (this, tr("Beta release"), + tr("This is a beta release of Sonic Visualiser

Please see the \"What's New\" option in the Help menu for a list of changes since the last proper release.

")); +} +*/ + void MainWindow::pluginPopulationWarning() { @@ -4270,7 +4611,9 @@ SparseTimeValueModel *tvm = dynamic_cast(model); if (tvm) { - SparseTimeValueModel::Point point(frame, ev.getPitch() % 12, ""); + SparseTimeValueModel::Point point(frame, + float(ev.getPitch() % 12), + ""); SparseTimeValueModel::AddPointCommand *command = new SparseTimeValueModel::AddPointCommand (tvm, point, tr("Add Point")); @@ -4336,8 +4679,10 @@ MainWindowBase::mainModelChanged(model); if (m_playTarget || m_audioIO) { - connect(m_fader, SIGNAL(valueChanged(float)), + connect(m_mainLevelPan, SIGNAL(levelChanged(float)), this, SLOT(mainModelGainChanged(float))); + connect(m_mainLevelPan, SIGNAL(panChanged(float)), + this, SLOT(mainModelPanChanged(float))); } } @@ -4352,6 +4697,17 @@ } void +MainWindow::mainModelPanChanged(float balance) +{ + // this is indeed stereo balance rather than pan + if (m_playTarget) { + m_playTarget->setOutputBalance(balance); + } else if (m_audioIO) { + m_audioIO->setOutputBalance(balance); + } +} + +void MainWindow::modelAboutToBeDeleted(Model *model) { if (model == m_panLayer->getModel()) { @@ -4592,6 +4948,11 @@ m_preferencesDialog = new PreferencesDialog(this); + connect(m_preferencesDialog, SIGNAL(audioDeviceChanged()), + this, SLOT(recreateAudioIO())); + connect(m_preferencesDialog, SIGNAL(coloursChanged()), + this, SLOT(coloursChanged())); + // DeleteOnClose is safe here, because m_preferencesDialog is a // QPointer that will be zeroed when the dialog is deleted. We // use it in preference to leaving the dialog lying around because @@ -4612,8 +4973,8 @@ QWidget *w = dynamic_cast(sender()); if (!w) return; - if (w == m_fader) { - contextHelpChanged(tr("Adjust the master playback level")); + if (w == m_mainLevelPan) { + contextHelpChanged(tr("Adjust the master playback level and pan")); } else if (w == m_playSpeed) { contextHelpChanged(tr("Adjust the master playback speed")); } @@ -4638,7 +4999,62 @@ } void -MainWindow::about() +MainWindow::whatsNew() +{ + QFile changelog(":CHANGELOG"); + changelog.open(QFile::ReadOnly); + QByteArray content = changelog.readAll(); + QString text = QString::fromUtf8(content); + + QDialog *d = new QDialog(this); + d->setWindowTitle(tr("What's New")); + + QGridLayout *layout = new QGridLayout; + d->setLayout(layout); + + int row = 0; + + QLabel *iconLabel = new QLabel; + iconLabel->setPixmap(QApplication::windowIcon().pixmap(64, 64)); + layout->addWidget(iconLabel, row, 0); + + layout->addWidget + (new QLabel(tr("

What's New in %1

") + .arg(QApplication::applicationName())), + row++, 1); + layout->setColumnStretch(2, 10); + + QTextEdit *textEdit = new QTextEdit; + layout->addWidget(textEdit, row++, 1, 1, 2); + + if (m_newerVersionIs != "") { + layout->addWidget(new QLabel(tr("Note: A newer version of Sonic Visualiser is available.
(Version %1 is available; you are using version %2)").arg(m_newerVersionIs).arg(SV_VERSION)), row++, 1, 1, 2); + } + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); + layout->addWidget(bb, row++, 0, 1, 3); + connect(bb, SIGNAL(accepted()), d, SLOT(accept())); + + text.replace(QRegExp("(.)\n +(.)"), "\\1 \\2"); + text.replace(QRegExp("\n - ([^\n]+)"), "\n
  • \\1
  • "); + text.replace(QRegExp(": *\n"), ":\n
      \n"); + text.replace(QRegExp("\n\\s*\n"), "\n
    \n\n"); + text.replace(QRegExp("\n(\\w[^:\n]+:)"), "\n

    \\1

    "); +// text.replace(QRegExp("
  • ([^,.\n]+)([,.] +\\w)"), "
  • \\1\\2"); + + textEdit->setHtml(text); + textEdit->setReadOnly(true); + + d->setMinimumSize(m_viewManager->scalePixelSize(520), + m_viewManager->scalePixelSize(450)); + + d->exec(); + + delete d; +} + +QString +MainWindow::getReleaseText() const { bool debug = false; QString version = "(unknown version)"; @@ -4658,19 +5074,31 @@ #endif // SVNREV #endif // SV_VERSION - QString aboutText; - - aboutText += tr("

    About Sonic Visualiser

    "); - aboutText += tr("

    Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.
    http://www.sonicvisualiser.org/

    "); - aboutText += tr("

    %1 : %2 configuration, %3-bit build

    ") + return tr("%1 : %2 configuration, %3-bit build") .arg(version) .arg(debug ? tr("Debug") : tr("Release")) .arg(sizeof(void *) * 8); - - aboutText += ""; +} + +void +MainWindow::about() +{ + QString aboutText; + + aboutText += tr("

    About Sonic Visualiser

    "); + aboutText += tr("

    Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.
    http://www.sonicvisualiser.org/

    "); + aboutText += QString("

    %1

    ").arg(getReleaseText()); + + if (m_oscQueue && m_oscQueue->isOK()) { + aboutText += tr("

    The OSC URL for this instance is: \"%1\"").arg(m_oscQueue->getOSCURL()); + } + + aboutText += "

    "; aboutText += tr("With Qt v%1 © The Qt Company").arg(QT_VERSION_STR); + aboutText += ""; + #ifdef HAVE_JACK #ifdef JACK_VERSION aboutText += tr("
    With JACK audio output library v%1 © Paul Davis and Jack O'Quin").arg(JACK_VERSION); @@ -4731,6 +5159,7 @@ #endif // RUBBERBAND_VERSION #endif // HAVE_RUBBERBAND aboutText += tr("
    With Vamp plugin support (API v%1, host SDK v%2) © Chris Cannam and QMUL").arg(VAMP_API_VERSION).arg(VAMP_SDK_VERSION); + aboutText += tr("
    With Piper Vamp protocol bridge © QMUL"); aboutText += tr("
    With LADSPA plugin support (API v%1) © Richard Furse, Paul Davis, Stefan Westerfeld").arg(LADSPA_VERSION); aboutText += tr("
    With DSSI plugin support (API v%1) © Chris Cannam, Steve Harris, Sean Bolton").arg(DSSI_VERSION); #ifdef REDLAND_VERSION @@ -4750,27 +5179,81 @@ aboutText += tr("
    With liblo Lite OSC library © Steve Harris"); #endif // LIBLO_VERSION - if (m_oscQueue && m_oscQueue->isOK()) { - aboutText += tr("

    The OSC URL for this instance is: \"%1\"").arg(m_oscQueue->getOSCURL()); - } - aboutText += "

    "; #endif // HAVE_LIBLO -#ifndef BUILD_STATIC - aboutText.replace(tr("With "), tr("Using ")); -#endif + aboutText += "

    "; + aboutText += tr("Russian UI translation contributed by Alexandre Prokoudine."); + aboutText += "
    "; + aboutText += tr("Czech UI translation contributed by Pavel Fric."); + aboutText += "

    "; aboutText += - "

    Sonic Visualiser Copyright © 2005–2016 Chris Cannam and " - "Queen Mary, University of London.

    " + "

    Sonic Visualiser Copyright © 2005–2018 Chris Cannam and " + "Queen Mary, University of London.

    "; + + aboutText += "

    This program is free software; you can redistribute it and/or " "modify it under the terms of the 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 the file " "COPYING included with this distribution for more information.

    "; + + // use our own dialog so we can influence the size + + QDialog *d = new QDialog(this); + + d->setWindowTitle(tr("About %1").arg(QApplication::applicationName())); + + QGridLayout *layout = new QGridLayout; + d->setLayout(layout); + + int row = 0; - QMessageBox::about(this, tr("About Sonic Visualiser"), aboutText); + QLabel *iconLabel = new QLabel; + iconLabel->setPixmap(QApplication::windowIcon().pixmap(64, 64)); + layout->addWidget(iconLabel, row, 0, Qt::AlignTop); + + QLabel *mainText = new QLabel(); + layout->addWidget(mainText, row, 1, 1, 2); + + layout->setRowStretch(row, 10); + layout->setColumnStretch(1, 10); + + ++row; + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); + layout->addWidget(bb, row++, 0, 1, 3); + connect(bb, SIGNAL(accepted()), d, SLOT(accept())); + +// mainText->setHtml(aboutText); +// mainText->setReadOnly(true); + mainText->setWordWrap(true); + mainText->setOpenExternalLinks(true); + mainText->setText(aboutText); + + d->setMinimumSize(m_viewManager->scalePixelSize(420), + m_viewManager->scalePixelSize(200)); + + d->exec(); + + delete d; + /* + QMessageBox about(QMessageBox::Information, + tr("About Sonic Visualiser"), + aboutText, + QMessageBox::StandardButtons(QMessageBox::Ok), + this); + + QIcon icon = QApplication::windowIcon(); + QSize size = icon.actualSize(QSize(64, 64)); + about.setIconPixmap(icon.pixmap(size)); + + about.setMinimumSize(m_viewManager->scalePixelSize(400), + m_viewManager->scalePixelSize(400)); + + about.exec(); + */ } void @@ -4782,6 +5265,8 @@ void MainWindow::newerVersionAvailable(QString version) { + m_newerVersionIs = version; + QSettings settings; settings.beginGroup("NewerVersionWarning"); QString tag = QString("version-%1-available-show").arg(version); diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/MainWindow.h --- a/main/MainWindow.h Mon Sep 17 13:53:25 2018 +0100 +++ b/main/MainWindow.h Mon Sep 17 14:05:41 2018 +0100 @@ -41,6 +41,8 @@ public slots: virtual void preferenceChanged(PropertyContainer::PropertyName); + virtual void coloursChanged(); + virtual bool commitData(bool mayAskUser); void goFullScreen(); @@ -58,9 +60,11 @@ virtual void applyTemplate(); virtual void exportAudio(); virtual void exportAudioData(); + virtual void convertAudio(); virtual void importLayer(); virtual void exportLayer(); virtual void exportImage(); + virtual void exportSVG(); virtual void browseRecordedAudio(); virtual void saveSession(); virtual void saveSessionAs(); @@ -130,13 +134,14 @@ virtual void slowDownPlayback(); virtual void restoreNormalPlayback(); - virtual void outputLevelsChanged(float, float); + virtual void monitoringLevelsChanged(float, float); virtual void layerRemoved(Layer *); virtual void layerInAView(Layer *, bool); virtual void mainModelChanged(WaveFileModel *); virtual void mainModelGainChanged(float); + virtual void mainModelPanChanged(float); virtual void modelAdded(Model *); virtual void modelAboutToBeDeleted(Model *); @@ -151,6 +156,9 @@ virtual void midiEventsAvailable(); virtual void playStatusChanged(bool); +/* + virtual void betaReleaseWarning(); +*/ virtual void pluginPopulationWarning(); virtual void saveSessionAsTemplate(); @@ -159,12 +167,13 @@ virtual void website(); virtual void help(); virtual void about(); + virtual void whatsNew(); virtual void keyReference(); virtual void newerVersionAvailable(QString); protected: Overview *m_overview; - Fader *m_fader; + LevelPanToolButton *m_mainLevelPan; AudioDial *m_playSpeed; WaveformLayer *m_panLayer; @@ -225,18 +234,22 @@ Surveyer *m_surveyer; VersionTester *m_versionTester; + QString m_newerVersionIs; struct LayerConfiguration { - LayerConfiguration(LayerFactory::LayerType _layer - = LayerFactory::TimeRuler, + LayerConfiguration(LayerFactory::LayerType _layer + = LayerFactory::TimeRuler, Model *_source = 0, int _channel = -1) : - layer(_layer), sourceModel(_source), channel(_channel) { } - LayerFactory::LayerType layer; + layer(_layer), sourceModel(_source), channel(_channel) { } + LayerFactory::LayerType layer; Model *sourceModel; - int channel; + int channel; }; + QString shortcutFor(LayerFactory::LayerType, bool isPaneMenu); + void updateLayerShortcutsFor(Model *); + typedef std::map PaneActionMap; PaneActionMap m_paneActions; @@ -259,6 +272,8 @@ typedef std::map NumberingActionMap; NumberingActionMap m_numberingActions; + QString getReleaseText() const; + virtual void setupMenus(); virtual void setupFileMenu(); virtual void setupEditMenu(); diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/NetworkPermissionTester.cpp --- a/main/NetworkPermissionTester.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/NetworkPermissionTester.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -16,6 +16,8 @@ #include "../version.h" +#include "base/Debug.h" + #include #include #include @@ -37,47 +39,70 @@ bool permish = false; if (settings.contains(tag)) { - permish = settings.value(tag, false).toBool(); + permish = settings.value(tag, false).toBool(); + SVDEBUG << "NetworkPermissionTester: Asked already, result was " << permish << endl; } else { + SVDEBUG << "NetworkPermissionTester: Asking for permission" << endl; - QDialog d; - d.setWindowTitle(QCoreApplication::translate("NetworkPermissionTester", "Welcome to Sonic Visualiser")); + QDialog d; + d.setWindowTitle(QCoreApplication::translate("NetworkPermissionTester", "Welcome to Sonic Visualiser")); - QGridLayout *layout = new QGridLayout; - d.setLayout(layout); + QGridLayout *layout = new QGridLayout; + d.setLayout(layout); - QLabel *label = new QLabel; - label->setWordWrap(true); - label->setText - (QCoreApplication::translate - ("NetworkPermissionTester", - "

    Welcome to Sonic Visualiser!

    " - "

    Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.

    " - "

    Developed in the Centre for Digital Music at Queen Mary, University of London, Sonic Visualiser is provided free as open source software under the GNU General Public License.

    " - "


    " - "

    Before we go on...

    " - "

    Sonic Visualiser would like to make networking connections and open a network port.

    " - "

    This is to:

    " - "
    • Find information about available and installed plugins;
    • " - "
    • Support the use of Open Sound Control, where configured; and
    • " - "
    • Tell you when updates are available.
    • " - "
    " - "

    No personal information will be sent, no tracking is carried out, and all requests happen in the background without interrupting your work.

    " - "

    We recommend that you allow this, because it makes Sonic Visualiser more useful. But if you do not wish to do so, please un-check the box below.

    ")); - layout->addWidget(label, 0, 0); + QString preamble; + preamble = QCoreApplication::translate + ("NetworkPermissionTester", + "

    Welcome to Sonic Visualiser!

    " + "

    Sonic Visualiser is a program for viewing and exploring audio data for semantic music analysis and annotation.

    " + "

    Developed in the Centre for Digital Music at Queen Mary University of London, Sonic Visualiser is open source software under the GNU General Public License.

    " + "


    " + "

    Before we go on...

    " + "

    Sonic Visualiser would like permission to use the network.

    "); - QCheckBox *cb = new QCheckBox(QCoreApplication::translate("NetworkPermissionTester", "Allow this")); - cb->setChecked(true); - layout->addWidget(cb, 1, 0); - - QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); - QObject::connect(bb, SIGNAL(accepted()), &d, SLOT(accept())); - layout->addWidget(bb, 2, 0); - - d.exec(); + QString bullets; + if (m_withOSC) { + bullets = QCoreApplication::translate + ("NetworkPermissionTester", + "

    This is to:

    " + "
    • Find information about available and installed plugins;
    • " + "
    • Support the use of Open Sound Control; and
    • " + "
    • Tell you when updates are available.
    • " + "
    "); + } else { + bullets = QCoreApplication::translate + ("NetworkPermissionTester", + "

    This is to:

    " + "
    • Find information about available and installed plugins; and
    • " + "
    • Tell you when updates are available.
    • " + "
    "); + } + + QString postamble; + postamble = QCoreApplication::translate + ("NetworkPermissionTester", + "

    No personal information will be sent, no tracking is carried out, and no individual information will be shared with anyone else. We will however make aggregate counts of distinct requests for usage reporting.

    " + "

    We recommend that you allow this, because it makes Sonic Visualiser more useful to you and supports the public funding of this work. But if you do not wish to allow it, please un-check the box below.

    "); + + QLabel *label = new QLabel; + label->setWordWrap(true); + label->setText(preamble + bullets + postamble); + layout->addWidget(label, 0, 0); + + QCheckBox *cb = new QCheckBox(QCoreApplication::translate("NetworkPermissionTester", "Allow this")); + cb->setChecked(true); + layout->addWidget(cb, 1, 0); + + QDialogButtonBox *bb = new QDialogButtonBox(QDialogButtonBox::Ok); + QObject::connect(bb, SIGNAL(accepted()), &d, SLOT(accept())); + layout->addWidget(bb, 2, 0); + + d.exec(); permish = cb->isChecked(); - settings.setValue(tag, permish); + settings.setValue(tag, permish); + + SVDEBUG << "NetworkPermissionTester: asked, answer was " << permish << endl; } settings.endGroup(); diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/NetworkPermissionTester.h --- a/main/NetworkPermissionTester.h Mon Sep 17 13:53:25 2018 +0100 +++ b/main/NetworkPermissionTester.h Mon Sep 17 14:05:41 2018 +0100 @@ -18,8 +18,11 @@ class NetworkPermissionTester { public: - NetworkPermissionTester() { } + NetworkPermissionTester(bool withOSCSupport) : m_withOSC(withOSCSupport) { } bool havePermission(); + +private: + bool m_withOSC; }; #endif diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/OSCHandler.cpp --- a/main/OSCHandler.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/OSCHandler.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -26,7 +26,8 @@ #include "framework/Document.h" #include "data/fileio/WavFileWriter.h" #include "transform/TransformFactory.h" -#include "widgets/Fader.h" +#include "widgets/LevelPanWidget.h" +#include "widgets/LevelPanToolButton.h" #include "widgets/AudioDial.h" #include @@ -36,8 +37,8 @@ void MainWindow::handleOSCMessage(const OSCMessage &message) { - SVDEBUG << "MainWindow::handleOSCMessage: thread id = " - << QThread::currentThreadId() << endl; + SVDEBUG << "OSCHandler: method = \"" + << message.getMethod() << "\"" << endl; // This large function should really be abstracted out. @@ -47,7 +48,7 @@ message.getArg(0).canConvert(QVariant::String)) { QString path = message.getArg(0).toString(); if (open(path, ReplaceMainModel) != FileOpenSucceeded) { - cerr << "MainWindow::handleOSCMessage: File open failed for path \"" + cerr << "OSCHandler: File open failed for path \"" << path << "\"" << endl; } //!!! we really need to spin here and not return until the @@ -60,7 +61,7 @@ message.getArg(0).canConvert(QVariant::String)) { QString path = message.getArg(0).toString(); if (open(path, CreateAdditionalModel) != FileOpenSucceeded) { - cerr << "MainWindow::handleOSCMessage: File open failed for path \"" + cerr << "OSCHandler: File open failed for path \"" << path << "\"" << endl; } } @@ -77,7 +78,7 @@ std::vector recent = m_recentFiles.getRecent(); if (n >= 0 && n < int(recent.size())) { if (open(recent[n], ReplaceMainModel) != FileOpenSucceeded) { - cerr << "MainWindow::handleOSCMessage: File open failed for path \"" + cerr << "OSCHandler: File open failed for path \"" << recent[n] << "\"" << endl; } } @@ -89,7 +90,7 @@ message.getArg(0).canConvert(QVariant::String)) { path = message.getArg(0).toString(); if (QFileInfo(path).exists()) { - SVDEBUG << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in save" << endl; + SVDEBUG << "OSCHandler: Refusing to overwrite existing file in save" << endl; } else { saveSessionFile(path); } @@ -103,7 +104,7 @@ message.getArg(0).canConvert(QVariant::String)) { path = message.getArg(0).toString(); if (QFileInfo(path).exists()) { - SVDEBUG << "MainWindow::handleOSCMessage: Refusing to overwrite existing file in export" << endl; + SVDEBUG << "OSCHandler: Refusing to overwrite existing file in export" << endl; } else { WavFileWriter writer(path, getMainModel()->getSampleRate(), @@ -164,10 +165,21 @@ } } + SVDEBUG << "OSCHandler: Setting playback frame to " << frame << endl; + m_viewManager->setPlaybackFrame(frame); - if (play && !m_playSource->isPlaying()) { - m_playSource->play(frame); + if (play) { + if (!m_playSource->isPlaying()) { + SVDEBUG << "OSCHandler: Play source is not yet playing, calling play()" << endl; + // handles audio device suspend/resume etc, as + // well as calling m_playSource->play(frame) + MainWindow::play(); + } else { + SVDEBUG << "OSCHandler: Play source is already playing, not starting it" << endl; + } + } else { + SVDEBUG << "OSCHandler: Jump only requested, not starting playback" << endl; } } @@ -201,7 +213,13 @@ } else if (message.getMethod() == "stop") { - if (m_playSource->isPlaying()) m_playSource->stop(); + if (m_playSource->isPlaying()) { + // As with play, we want to use the MainWindow + // function rather than call m_playSource directly + // because that way the audio driver suspend/resume + // etc is handled properly + MainWindow::stop(); + } } else if (message.getMethod() == "loop") { @@ -295,7 +313,7 @@ channel = message.getArg(0).toInt(); if (channel < -1 || channel > int(getMainModel()->getChannelCount())) { - cerr << "WARNING: MainWindow::handleOSCMessage: channel " + cerr << "WARNING: OSCHandler: channel " << channel << " out of range" << endl; channel = -1; } @@ -307,7 +325,7 @@ LayerFactory::getInstance()->getLayerTypeForName(str); if (type == LayerFactory::UnknownLayer) { - cerr << "WARNING: MainWindow::handleOSCMessage: unknown layer " + cerr << "WARNING: OSCHandler: unknown layer " << "type " << str << endl; } else { @@ -342,10 +360,37 @@ if (property == "gain") { if (value < 0.0) value = 0.0; - m_fader->setValue(value); + m_mainLevelPan->setLevel(value); if (m_playTarget) m_playTarget->setOutputGain(value); + } else if (property == "speed") { + m_playSpeed->setMappedValue(value); } else if (property == "speedup") { - m_playSpeed->setMappedValue(value); + + // The speedup method existed before the speed method + // and is a bit weirder. + // + // For speed(x), x is a percentage of normal speed, so + // x=100 means play at the normal speed, x=50 means + // half speed, x=200 double speed etc. + // + // For speedup(x), x was some sort of modifier of + // percentage thing, so x=0 meant play at the normal + // speed, x=50 meant play at 150% of normal speed, + // x=100 meant play at double speed, and x=-100 rather + // bizarrely meant play at half speed. We handle this + // now by converting to speed percentage as follows: + + double percentage = 100.0; + if (value > 0.f) { + percentage = percentage + value; + } else { + percentage = 10000.0 / (percentage - value); + } + SVDEBUG << "OSCHandler: converted speedup(" << value + << ") into speed(" << percentage << ")" << endl; + + m_playSpeed->setMappedValue(percentage); + } else if (property == "overlays") { if (value < 0.5) { m_viewManager->setOverlayMode(ViewManager::NoOverlays); @@ -430,7 +475,7 @@ } else { - cerr << "WARNING: MainWindow::handleOSCMessage: Unknown delete target " << target << endl; + cerr << "WARNING: OSCHandler: Unknown delete target " << target << endl; } } @@ -531,9 +576,9 @@ TransformId transformId = message.getArg(0).toString(); - Transform transform = TransformFactory::getInstance()-> + Transform transform = TransformFactory::getInstance()-> getDefaultTransformFor(transformId); - + Layer *newLayer = m_document->createDerivedLayer (transform, getMainModel()); @@ -545,9 +590,8 @@ } } else { - cerr << "WARNING: MainWindow::handleOSCMessage: Unknown or unsupported " + cerr << "WARNING: OSCHandler: Unknown or unsupported " << "method \"" << message.getMethod() << "\"" << endl; } - } diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/PreferencesDialog.cpp --- a/main/PreferencesDialog.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/PreferencesDialog.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -38,13 +37,18 @@ #include "widgets/WindowTypeSelector.h" #include "widgets/IconLoader.h" +#include "widgets/ColourMapComboBox.h" +#include "widgets/ColourComboBox.h" +#include "widgets/PluginPathConfigurator.h" +#include "widgets/WidgetScale.h" #include "base/Preferences.h" #include "base/ResourceFinder.h" #include "layer/ColourMapper.h" +#include "layer/ColourDatabase.h" #include "bqaudioio/AudioFactory.h" -#include "version.h" +#include "../version.h" using namespace std; @@ -53,6 +57,8 @@ m_audioImplementation(0), m_audioPlaybackDevice(0), m_audioRecordDevice(0), + m_audioDeviceChanged(false), + m_coloursChanged(false), m_changesOnRestart(false) { setWindowTitle(tr("Sonic Visualiser: Application Preferences")); @@ -143,24 +149,42 @@ int(ColourMapper::Sunset)).toInt()); m_colour3DColour = (settings.value("colour-3d-plot-colour", int(ColourMapper::Green)).toInt()); + m_overviewColour = ColourDatabase::getInstance()->getColour(tr("Green")); + if (settings.contains("overview-colour")) { + QString qcolorName = + settings.value("overview-colour", m_overviewColour.name()) + .toString(); + m_overviewColour.setNamedColor(qcolorName); + SVCERR << "loaded colour " << m_overviewColour.name() << " from settings" << endl; + } settings.endGroup(); - QComboBox *spectrogramGColour = new QComboBox; - QComboBox *spectrogramMColour = new QComboBox; - QComboBox *colour3DColour = new QComboBox; - for (i = 0; i < ColourMapper::getColourMapCount(); ++i) { - spectrogramGColour->addItem(ColourMapper::getColourMapName(i)); - spectrogramMColour->addItem(ColourMapper::getColourMapName(i)); - colour3DColour->addItem(ColourMapper::getColourMapName(i)); - if (i == m_spectrogramGColour) spectrogramGColour->setCurrentIndex(i); - if (i == m_spectrogramMColour) spectrogramMColour->setCurrentIndex(i); - if (i == m_colour3DColour) colour3DColour->setCurrentIndex(i); + + ColourMapComboBox *spectrogramGColour = new ColourMapComboBox(true); + spectrogramGColour->setCurrentIndex(m_spectrogramGColour); + + ColourMapComboBox *spectrogramMColour = new ColourMapComboBox(true); + spectrogramMColour->setCurrentIndex(m_spectrogramMColour); + + ColourMapComboBox *colour3DColour = new ColourMapComboBox(true); + colour3DColour->setCurrentIndex(m_colour3DColour); + + // can't have "add new colour", as it gets saved in the session not in prefs + ColourComboBox *overviewColour = new ColourComboBox(false); + int overviewColourIndex = + ColourDatabase::getInstance()->getColourIndex(m_overviewColour); + SVCERR << "index = " << overviewColourIndex << " for colour " << m_overviewColour.name() << endl; + if (overviewColourIndex >= 0) { + overviewColour->setCurrentIndex(overviewColourIndex); } - connect(spectrogramGColour, SIGNAL(currentIndexChanged(int)), + + connect(spectrogramGColour, SIGNAL(colourMapChanged(int)), this, SLOT(spectrogramGColourChanged(int))); - connect(spectrogramMColour, SIGNAL(currentIndexChanged(int)), + connect(spectrogramMColour, SIGNAL(colourMapChanged(int)), this, SLOT(spectrogramMColourChanged(int))); - connect(colour3DColour, SIGNAL(currentIndexChanged(int)), + connect(colour3DColour, SIGNAL(colourMapChanged(int)), this, SLOT(colour3DColourChanged(int))); + connect(overviewColour, SIGNAL(colourChanged(int)), + this, SLOT(overviewColourChanged(int))); m_tuningFrequency = prefs->getTuningFrequency(); @@ -202,24 +226,33 @@ connect(m_audioRecordDeviceCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(audioRecordDeviceChanged(int))); - vector names = breakfastquay::AudioFactory::getImplementationNames(); + vector implementationNames = + breakfastquay::AudioFactory::getImplementationNames(); + QString implementationName = settings.value("audio-target", "").toString(); if (implementationName == "auto") implementationName = ""; + if (implementationName == "" && implementationNames.size() == 1) { + // We won't be showing the implementations menu in this case + implementationName = implementationNames[0].c_str(); + } + audioImplementation->addItem(tr("(auto)")); m_audioImplementation = 0; - for (int i = 0; in_range_for(names, i); ++i) { + + for (int i = 0; in_range_for(implementationNames, i); ++i) { audioImplementation->addItem - (breakfastquay::AudioFactory::getImplementationDescription(names[i]). - c_str()); - if (implementationName.toStdString() == names[i]) { + (breakfastquay::AudioFactory::getImplementationDescription + (implementationNames[i]).c_str()); + if (implementationName.toStdString() == implementationNames[i]) { audioImplementation->setCurrentIndex(i+1); m_audioImplementation = i+1; } } + settings.endGroup(); rebuildDeviceCombos(); - m_changesOnRestart = false; // the rebuild will have changed this + m_audioDeviceChanged = false; // the rebuild will have changed this QCheckBox *resampleOnLoad = new QCheckBox; m_resampleOnLoad = prefs->getResampleOnLoad(); @@ -244,7 +277,7 @@ tempDirButton->setIcon(IconLoader().load("fileopen")); connect(tempDirButton, SIGNAL(clicked()), this, SLOT(tempDirButtonClicked())); - tempDirButton->setFixedSize(QSize(24, 24)); + tempDirButton->setFixedSize(WidgetScale::scaleQSize(QSize(24, 24))); QCheckBox *showSplash = new QCheckBox; m_showSplash = prefs->getShowSplash(); @@ -296,7 +329,7 @@ QString f0 = f; f.replace("sonic-visualiser_", "").replace(".qm", ""); if (f == f0) { // our expectations about filename format were not met - cerr << "INFO: Unexpected filename " << f << " in i18n resource directory" << endl; + SVCERR << "INFO: Unexpected filename " << f << " in i18n resource directory" << endl; } else { m_locales.push_back(f); QString displayText; @@ -352,55 +385,11 @@ hms->setCheckState(m_showHMS ? Qt::Checked : Qt::Unchecked); connect(hms, SIGNAL(stateChanged(int)), this, SLOT(showHMSChanged(int))); - - // General tab - QFrame *frame = new QFrame; - - QGridLayout *subgrid = new QGridLayout; - frame->setLayout(subgrid); - + QFrame *frame = 0; + QGridLayout *subgrid = 0; int row = 0; - subgrid->addWidget(new QLabel(tr("%1:").arg(tr("User interface language"))), - row, 0); - subgrid->addWidget(locale, row++, 1, 1, 1); - - subgrid->addWidget(new QLabel(tr("%1:").arg(tr("Allow network usage"))), - row, 0); - subgrid->addWidget(networkPermish, row++, 1, 1, 1); - - subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel - ("Temporary Directory Root"))), - row, 0); - subgrid->addWidget(m_tempDirRootEdit, row, 1, 1, 1); - subgrid->addWidget(tempDirButton, row, 2, 1, 1); - row++; - - subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel - ("Resample On Load"))), - row, 0); - subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1); - - subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel - ("Use Gapless Mode"))), - row, 0); - subgrid->addWidget(gaplessMode, row++, 1, 1, 1); - - subgrid->addWidget(new QLabel(tr("Audio service:")), row, 0); - subgrid->addWidget(audioImplementation, row++, 1, 1, 2); - - subgrid->addWidget(new QLabel(tr("Audio playback device:")), row, 0); - subgrid->addWidget(m_audioPlaybackDeviceCombo, row++, 1, 1, 2); - - subgrid->addWidget(new QLabel(tr("Audio record device:")), row, 0); - subgrid->addWidget(m_audioRecordDeviceCombo, row++, 1, 1, 2); - - subgrid->setRowStretch(row, 10); - - m_tabOrdering[GeneralTab] = m_tabs->count(); - m_tabs->addTab(frame, tr("&General")); - // Appearance tab frame = new QFrame; @@ -408,11 +397,6 @@ frame->setLayout(subgrid); row = 0; - subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel - ("Show Splash Screen"))), - row, 0); - subgrid->addWidget(showSplash, row++, 1, 1, 1); - #ifdef Q_OS_MAC if (devicePixelRatio() > 1) { subgrid->addWidget(new QLabel(tr("Draw layers at Retina resolution:")), row, 0); @@ -437,6 +421,10 @@ row, 0); subgrid->addWidget(colour3DColour, row++, 1, 1, 2); + subgrid->addWidget(new QLabel(tr("Overview waveform colour:")), + row, 0); + subgrid->addWidget(overviewColour, row++, 1, 1, 2); + #ifdef NOT_DEFINED // see earlier subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel ("Background Mode"))), @@ -515,13 +503,17 @@ frame->setLayout(subgrid); row = 0; - subgrid->addWidget(new QLabel(tr("Default session template for audio files:")), row++, 0); + subgrid->addWidget(new QLabel(tr("Default session template when loading audio files:")), row++, 0); QListWidget *lw = new QListWidget(); subgrid->addWidget(lw, row, 0); subgrid->setRowStretch(row, 10); row++; + subgrid->addWidget(new QLabel(tr("(Use \"%1\" in the File menu to add to these.)") + .arg(tr("Export Session as Template..."))), + row++, 0); + settings.beginGroup("MainWindow"); m_currentTemplate = settings.value("sessiontemplate", "").toString(); settings.endGroup(); @@ -553,6 +545,81 @@ m_tabOrdering[TemplateTab] = m_tabs->count(); m_tabs->addTab(frame, tr("Session &Template")); + // Audio IO tab + + frame = new QFrame; + subgrid = new QGridLayout; + frame->setLayout(subgrid); + row = 0; + + if (implementationNames.size() > 1) { + subgrid->addWidget(new QLabel(tr("Audio service:")), row, 0); + subgrid->addWidget(audioImplementation, row++, 1, 1, 2); + } + + subgrid->addWidget(new QLabel(tr("Audio playback device:")), row, 0); + subgrid->addWidget(m_audioPlaybackDeviceCombo, row++, 1, 1, 2); + + subgrid->addWidget(new QLabel(tr("Audio record device:")), row, 0); + subgrid->addWidget(m_audioRecordDeviceCombo, row++, 1, 1, 2); + + subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel + ("Use Gapless Mode"))), + row, 0); + subgrid->addWidget(gaplessMode, row++, 1, 1, 1); + + subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel + ("Resample On Load"))), + row, 0); + subgrid->addWidget(resampleOnLoad, row++, 1, 1, 1); + + subgrid->setRowStretch(row, 10); + + m_tabOrdering[AudioIOTab] = m_tabs->count(); + m_tabs->addTab(frame, tr("A&udio I/O")); + + // Plugins tab + + m_pluginPathConfigurator = new PluginPathConfigurator(this); + m_pluginPathConfigurator->setPaths(PluginPathSetter::getPaths()); + connect(m_pluginPathConfigurator, SIGNAL(pathsChanged()), + this, SLOT(pluginPathsChanged())); + + m_tabOrdering[PluginTab] = m_tabs->count(); + m_tabs->addTab(m_pluginPathConfigurator, tr("&Plugins")); + + // General tab + + frame = new QFrame; + subgrid = new QGridLayout; + frame->setLayout(subgrid); + row = 0; + + subgrid->addWidget(new QLabel(tr("%1:").arg(tr("User interface language"))), + row, 0); + subgrid->addWidget(locale, row++, 1, 1, 1); + + subgrid->addWidget(new QLabel(tr("%1:").arg(tr("Allow network usage"))), + row, 0); + subgrid->addWidget(networkPermish, row++, 1, 1, 1); + + subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel + ("Show Splash Screen"))), + row, 0); + subgrid->addWidget(showSplash, row++, 1, 1, 1); + + subgrid->addWidget(new QLabel(tr("%1:").arg(prefs->getPropertyLabel + ("Temporary Directory Root"))), + row, 0); + subgrid->addWidget(m_tempDirRootEdit, row, 1, 1, 1); + subgrid->addWidget(tempDirButton, row, 2, 1, 1); + row++; + + subgrid->setRowStretch(row, 10); + + m_tabOrdering[GeneralTab] = m_tabs->count(); + m_tabs->addTab(frame, tr("&Other")); + QDialogButtonBox *bb = new QDialogButtonBox(Qt::Horizontal); grid->addWidget(bb, 1, 0); @@ -581,13 +648,11 @@ vector names = breakfastquay::AudioFactory::getImplementationNames(); string implementationName; + if (in_range_for(names, m_audioImplementation-1)) { implementationName = names[m_audioImplementation-1]; } - m_audioPlaybackDeviceCombo->clear(); - m_audioRecordDeviceCombo->clear(); - QString suffix; if (implementationName != "") { suffix = "-" + QString(implementationName.c_str()); @@ -596,6 +661,7 @@ names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName); QString playbackDeviceName = settings.value ("audio-playback-device" + suffix, "").toString(); + m_audioPlaybackDeviceCombo->clear(); m_audioPlaybackDeviceCombo->addItem(tr("(auto)")); m_audioPlaybackDeviceCombo->setCurrentIndex(0); m_audioPlaybackDevice = 0; @@ -610,6 +676,7 @@ names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName); QString recordDeviceName = settings.value ("audio-record-device" + suffix, "").toString(); + m_audioRecordDeviceCombo->clear(); m_audioRecordDeviceCombo->addItem(tr("(auto)")); m_audioRecordDeviceCombo->setCurrentIndex(0); m_audioRecordDevice = 0; @@ -657,6 +724,7 @@ PreferencesDialog::spectrogramGColourChanged(int colour) { m_spectrogramGColour = colour; + m_coloursChanged = true; m_applyButton->setEnabled(true); } @@ -664,6 +732,7 @@ PreferencesDialog::spectrogramMColourChanged(int colour) { m_spectrogramMColour = colour; + m_coloursChanged = true; m_applyButton->setEnabled(true); } @@ -671,6 +740,15 @@ PreferencesDialog::colour3DColourChanged(int colour) { m_colour3DColour = colour; + m_coloursChanged = true; + m_applyButton->setEnabled(true); +} + +void +PreferencesDialog::overviewColourChanged(int colour) +{ + m_overviewColour = ColourDatabase::getInstance()->getColour(colour); + m_coloursChanged = true; m_applyButton->setEnabled(true); } @@ -695,7 +773,7 @@ m_audioImplementation = s; rebuildDeviceCombos(); m_applyButton->setEnabled(true); - m_changesOnRestart = true; + m_audioDeviceChanged = true; } } @@ -705,7 +783,7 @@ if (m_audioPlaybackDevice != s) { m_audioPlaybackDevice = s; m_applyButton->setEnabled(true); - m_changesOnRestart = true; + m_audioDeviceChanged = true; } } @@ -715,7 +793,7 @@ if (m_audioRecordDevice != s) { m_audioRecordDevice = s; m_applyButton->setEnabled(true); - m_changesOnRestart = true; + m_audioDeviceChanged = true; } } @@ -837,6 +915,13 @@ } void +PreferencesDialog::pluginPathsChanged() +{ + m_applyButton->setEnabled(true); + m_changesOnRestart = true; +} + +void PreferencesDialog::okClicked() { applyClicked(); @@ -874,6 +959,9 @@ vector names = breakfastquay::AudioFactory::getImplementationNames(); string implementationName; + if (m_audioImplementation > int(names.size())) { + m_audioImplementation = 0; + } if (m_audioImplementation > 0) { implementationName = names[m_audioImplementation-1]; } @@ -886,6 +974,9 @@ names = breakfastquay::AudioFactory::getPlaybackDeviceNames(implementationName); string deviceName; + if (m_audioPlaybackDevice > int(names.size())) { + m_audioPlaybackDevice = 0; + } if (m_audioPlaybackDevice > 0) { deviceName = names[m_audioPlaybackDevice-1]; } @@ -893,6 +984,9 @@ names = breakfastquay::AudioFactory::getRecordDeviceNames(implementationName); deviceName = ""; + if (m_audioRecordDevice > int(names.size())) { + m_audioRecordDevice = 0; + } if (m_audioRecordDevice > 0) { deviceName = names[m_audioRecordDevice-1]; } @@ -905,6 +999,7 @@ settings.setValue("spectrogram-colour", m_spectrogramGColour); settings.setValue("spectrogram-melodic-colour", m_spectrogramMColour); settings.setValue("colour-3d-plot-colour", m_colour3DColour); + settings.setValue("overview-colour", m_overviewColour.name()); settings.endGroup(); settings.beginGroup("MainWindow"); @@ -918,6 +1013,18 @@ tr("Restart required

    One or more of the application preferences you have changed may not take full effect until Sonic Visualiser is restarted.

    Please exit and restart the application now if you want these changes to take effect immediately.

    ")); m_changesOnRestart = false; } + + if (m_audioDeviceChanged) { + emit audioDeviceChanged(); + m_audioDeviceChanged = false; + } + + if (m_coloursChanged) { + emit coloursChanged(); + m_coloursChanged = false; + } + + PluginPathSetter::savePathSettings(m_pluginPathConfigurator->getPaths()); } void diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/PreferencesDialog.h --- a/main/PreferencesDialog.h Mon Sep 17 13:53:25 2018 +0100 +++ b/main/PreferencesDialog.h Mon Sep 17 14:05:41 2018 +0100 @@ -13,11 +13,12 @@ COPYING included with this distribution for more information. */ -#ifndef _PREFERENCES_DIALOG_H_ -#define _PREFERENCES_DIALOG_H_ +#ifndef SV_PREFERENCES_DIALOG_H +#define SV_PREFERENCES_DIALOG_H #include #include +#include #include "base/Window.h" @@ -26,6 +27,7 @@ class QLineEdit; class QTabWidget; class QComboBox; +class PluginPathConfigurator; class PreferencesDialog : public QDialog { @@ -37,12 +39,18 @@ enum Tab { GeneralTab, + AudioIOTab, AppearanceTab, AnalysisTab, - TemplateTab + TemplateTab, + PluginTab }; void switchToTab(Tab tab); +signals: + void audioDeviceChanged(); + void coloursChanged(); + public slots: void applicationClosing(bool quickly); @@ -53,6 +61,7 @@ void spectrogramGColourChanged(int state); void spectrogramMColourChanged(int state); void colour3DColourChanged(int state); + void overviewColourChanged(int state); void propertyLayoutChanged(int layout); void tuningFrequencyChanged(double freq); void audioImplementationChanged(int impl); @@ -72,6 +81,7 @@ void localeChanged(int); void networkPermissionChanged(int state); void retinaChanged(int state); + void pluginPathsChanged(); void tempDirButtonClicked(); @@ -91,6 +101,8 @@ QComboBox *m_audioPlaybackDeviceCombo; QComboBox *m_audioRecordDeviceCombo; void rebuildDeviceCombos(); + + PluginPathConfigurator *m_pluginPathConfigurator; QString m_currentTemplate; QStringList m_templates; @@ -104,6 +116,7 @@ int m_spectrogramGColour; int m_spectrogramMColour; int m_colour3DColour; + QColor m_overviewColour; int m_propertyLayout; double m_tuningFrequency; int m_audioImplementation; @@ -122,6 +135,8 @@ int m_viewFontSize; bool m_showSplash; + bool m_audioDeviceChanged; + bool m_coloursChanged; bool m_changesOnRestart; }; diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/SVSplash.cpp --- a/main/SVSplash.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/SVSplash.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -42,37 +42,37 @@ if (widthMultiple > 2.5 || dpratio > 1.0) { - // Hi-dpi either via pixel doubling or simply via lots of - // pixels + // Hi-dpi either via pixel doubling or simply via lots of + // pixels - double factor = widthMultiple / 2.5; - if (factor < 1.0) factor = 1.0; - sw = int(floor(w * factor)); - sh = int(floor(h * factor)); + double factor = widthMultiple / 2.5; + if (factor < 1.0) factor = 1.0; + sw = int(floor(w * factor)); + sh = int(floor(h * factor)); - delete p1; - m_pixmap = new QPixmap(int(floor(sw * dpratio)), - int(floor(sh * dpratio))); + delete p1; + m_pixmap = new QPixmap(int(floor(sw * dpratio)), + int(floor(sh * dpratio))); -// cerr << "pixmap size = " << m_pixmap->width() << " * " -// << m_pixmap->height() << endl; - - m_pixmap->fill(Qt::red); - QSvgRenderer renderer(QString(":icons/scalable/sv-splash.svg")); - QPainter painter(m_pixmap); - renderer.render(&painter); - painter.end(); +// cerr << "pixmap size = " << m_pixmap->width() << " * " +// << m_pixmap->height() << endl; + + m_pixmap->fill(Qt::red); + QSvgRenderer renderer(QString(":icons/scalable/sv-splash.svg")); + QPainter painter(m_pixmap); + renderer.render(&painter); + painter.end(); } else { - // The "low dpi" case - m_pixmap = p1; + // The "low dpi" case + m_pixmap = p1; } setFixedWidth(sw); setFixedHeight(sh); setGeometry(desk.x() + desk.width()/2 - sw/2, - desk.y() + desk.height()/2 - sh/2, - sw, sh); + desk.y() + desk.height()/2 - sh/2, + sw, sh); } SVSplash::~SVSplash() @@ -92,9 +92,9 @@ painter->drawPixmap(rect(), *m_pixmap, m_pixmap->rect()); QString text = QString("v%1").arg(SV_VERSION); painter->drawText - (width() - painter->fontMetrics().width(text) - (width()/50), - (width()/70) + painter->fontMetrics().ascent(), - text); + (width() - painter->fontMetrics().width(text) - (width()/50), + (width()/70) + painter->fontMetrics().ascent(), + text); } diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/Surveyer.cpp --- a/main/Surveyer.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/Surveyer.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -24,7 +24,7 @@ #include #include -#include "version.h" +#include "../version.h" #include "transform/TransformFactory.h" #include "plugin/PluginIdentifier.h" diff -r 246bdf94ef7b -r 55d9bbf1fe45 main/main.cpp --- a/main/main.cpp Mon Sep 17 13:53:25 2018 +0100 +++ b/main/main.cpp Mon Sep 17 14:05:41 2018 +0100 @@ -24,9 +24,10 @@ #include "data/fileio/FileSource.h" #include "widgets/TipDialog.h" #include "widgets/InteractiveFileFinder.h" -#include "svapp/framework/TransformUserConfigurator.h" +#include "framework/TransformUserConfigurator.h" #include "transform/TransformFactory.h" -#include "svcore/plugin/PluginScan.h" +#include "plugin/PluginScan.h" +#include "plugin/PluginPathSetter.h" #include #include @@ -279,7 +280,6 @@ settings.beginGroup("Preferences"); // Default to using Piper server; can change in preferences if (!settings.contains("run-vamp-plugins-in-process")) { - cerr << "setting does not exist yet" << endl; settings.setValue("run-vamp-plugins-in-process", false); } settings.endGroup(); @@ -301,6 +301,8 @@ } settings.endGroup(); + PluginPathSetter::initialiseEnvironmentVariables(); + QIcon icon; int sizes[] = { 16, 22, 24, 32, 48, 64, 128 }; for (int i = 0; i < int(sizeof(sizes)/sizeof(sizes[0])); ++i) { @@ -309,9 +311,11 @@ QApplication::setWindowIcon(icon); QString language = QLocale::system().name(); + SVDEBUG << "System language is: " << language << endl; settings.beginGroup("Preferences"); - language = settings.value("locale", language).toString(); + QString prefLanguage = settings.value("locale", language).toString(); + if (prefLanguage != QString()) language = prefLanguage; settings.endGroup(); QTranslator qtTranslator; diff -r 246bdf94ef7b -r 55d9bbf1fe45 noconfig.pri --- a/noconfig.pri Mon Sep 17 13:53:25 2018 +0100 +++ b/noconfig.pri Mon Sep 17 14:05:41 2018 +0100 @@ -1,11 +1,13 @@ + +CONFIG += c++14 CONFIG += release - -#CONFIG -= release #CONFIG += debug +PREFIX_PATH = /usr/local + DEFINES += NDEBUG BUILD_RELEASE -DEFINES += NO_TIMING +DEFINES += NO_TIMING NO_HIT_COUNTS DEFINES += HAVE_PIPER HAVE_PLUGIN_CHECKER_HELPER @@ -28,6 +30,7 @@ # these. LIBS += \ + -lbase \ -lbz2 \ -lrubberband \ -lfftw3 \ @@ -54,11 +57,11 @@ # This config is currently used for 32-bit Windows builds. - INCLUDEPATH += sv-dependency-builds/win32-mingw/include + INCLUDEPATH += $$PWD/sv-dependency-builds/win32-mingw/include - LIBS += -Lrelease -Lsv-dependency-builds/win32-mingw/lib -L../sonic-visualiser/sv-dependency-builds/win32-mingw/lib + LIBS += -Lrelease -L$$PWD/sv-dependency-builds/win32-mingw/lib - DEFINES += NOMINMAX _USE_MATH_DEFINES USE_OWN_ALIGNED_MALLOC CAPNP_LITE + DEFINES += NOMINMAX _USE_MATH_DEFINES CAPNP_LITE QMAKE_CXXFLAGS_RELEASE += -ffast-math @@ -76,22 +79,23 @@ # we want to do 32-bit builds with MSVC as well, then we'll # need to add a way to distinguish the two. - INCLUDEPATH += sv-dependency-builds/win64-msvc/include + INCLUDEPATH += $$PWD/sv-dependency-builds/win64-msvc/include -## This seems to be intruding even when we're supposed to be release + # This seems to be intruding even when we're supposed to be release # CONFIG(debug) { # LIBS += -NODEFAULTLIB:MSVCRT -Ldebug \ -# -L../sonic-visualiser/sv-dependency-builds/win64-msvc/lib/debug \ -# -L../sonic-visualiser/sv-dependency-builds/win64-msvc/lib +# -L$$PWD/sv-dependency-builds/win64-msvc/lib/debug \ +# -L$$PWD/sv-dependency-builds/win64-msvc/lib # } CONFIG(release) { LIBS += -Lrelease \ - -L../sonic-visualiser/sv-dependency-builds/win64-msvc/lib + -L$$PWD/sv-dependency-builds/win64-msvc/lib } - DEFINES += NOMINMAX _USE_MATH_DEFINES USE_OWN_ALIGNED_MALLOC CAPNP_LITE + DEFINES += NOMINMAX _USE_MATH_DEFINES CAPNP_LITE - QMAKE_CXXFLAGS_RELEASE += -fp:fast + QMAKE_CXXFLAGS_RELEASE += -fp:fast -gl + QMAKE_LFLAGS_RELEASE += -ltcg # No Ogg/FLAC support in the sndfile build on this platform yet LIBS -= -lFLAC -logg -lvorbis -lvorbisenc -lvorbisfile @@ -111,12 +115,12 @@ # All Mac builds are 64-bit these days. - INCLUDEPATH += sv-dependency-builds/osx/include - LIBS += -Lsv-dependency-builds/osx/lib + INCLUDEPATH += $$PWD/sv-dependency-builds/osx/include + LIBS += -L$$PWD/sv-dependency-builds/osx/lib -L$$PWD - QMAKE_CXXFLAGS_RELEASE += -ffast-math + QMAKE_CXXFLAGS_RELEASE += -O3 -ffast-math - DEFINES += HAVE_COREAUDIO MALLOC_IS_ALIGNED HAVE_VDSP + DEFINES += HAVE_COREAUDIO HAVE_VDSP LIBS += \ -framework CoreAudio \ -framework CoreMidi \ diff -r 246bdf94ef7b -r 55d9bbf1fe45 platform-dataquay.pri --- a/platform-dataquay.pri Mon Sep 17 13:53:25 2018 +0100 +++ b/platform-dataquay.pri Mon Sep 17 14:05:41 2018 +0100 @@ -3,7 +3,11 @@ include(./config.pri) } -CONFIG += staticlib c++11 +!exists(config.pri) { + include(./noconfig.pri) +} + +CONFIG += staticlib DEFINES -= USE_REDLAND QMAKE_CXXFLAGS -= -I/usr/include/rasqal -I/usr/include/raptor2 diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,166 @@ +#!/bin/bash + +# Disable shellcheck warnings for useless-use-of-cat. UUOC is good +# practice, not bad: clearer, safer, less error-prone. +# shellcheck disable=SC2002 + +sml="$REPOINT_SML" + +set -eu + +# avoid gussying up output +export HGPLAIN=true + +mydir=$(dirname "$0") +program="$mydir/repoint.sml" + +hasher= +local_install= +if [ -w "$mydir" ]; then + if echo | sha256sum >/dev/null 2>&1 ; then + hasher=sha256sum + local_install=true + elif echo | shasum >/dev/null 2>&1 ; then + hasher=shasum + local_install=true + else + echo "WARNING: sha256sum or shasum program not found" 1>&2 + fi +fi + +if [ -n "$local_install" ]; then + hash=$(echo "$sml" | cat "$program" - | $hasher | cut -c1-16) + gen_sml=$mydir/.repoint-$hash.sml + gen_out=$mydir/.repoint-$hash.bin + trap 'rm -f $gen_sml' 0 +else + gen_sml=$(mktemp /tmp/repoint-XXXXXXXX.sml) + gen_out=$(mktemp /tmp/repoint-XXXXXXXX.bin) + trap 'rm -f $gen_sml $gen_out' 0 +fi + +if [ -x "$gen_out" ]; then + exec "$gen_out" "$@" +fi + +# We need one of Poly/ML, SML/NJ, MLton, or MLKit. Since we're running +# a single-file SML program as if it were a script, our order of +# preference is usually based on startup speed. An exception is the +# local_install case, where we retain a persistent binary + +if [ -z "$sml" ]; then + if [ -n "$local_install" ] && mlton 2>&1 | grep -q 'MLton'; then + sml="mlton" + elif sml -h 2>&1 | grep -q 'Standard ML of New Jersey'; then + sml="smlnj" + # We would prefer Poly/ML to SML/NJ, except that Poly v5.7 has a + # nasty bug that occasionally causes it to deadlock on startup. + # That is fixed in v5.7.1, so we could promote it up the order + # again at some point in future + elif echo | poly -v 2>/dev/null | grep -q 'Poly/ML'; then + sml="polyml" + elif mlton 2>&1 | grep -q 'MLton'; then + sml="mlton" + # MLKit is at the bottom because it leaves compiled files around + # in an MLB subdir in the current directory + elif mlkit 2>&1 | grep -q 'MLKit'; then + sml="mlkit" + else cat 1>&2 <&2 </dev/null 2>&1 ; then + if [ ! -x "$gen_out" ]; then + polyc -o "$gen_out" "$program" + fi + "$gen_out" "$@" + else + echo 'use "'"$program"'"; repoint ['"$arglist"'];' | + poly -q --error-exit + fi ;; + mlton) + if [ ! -x "$gen_out" ]; then + echo "[Precompiling Repoint binary...]" 1>&2 + echo "val _ = main ()" | cat "$program" - > "$gen_sml" + mlton -output "$gen_out" "$gen_sml" + fi + "$gen_out" "$@" ;; + mlkit) + if [ ! -x "$gen_out" ]; then + echo "[Precompiling Repoint binary...]" 1>&2 + echo "val _ = main ()" | cat "$program" - > "$gen_sml" + mlkit -output "$gen_out" "$gen_sml" + fi + "$gen_out" "$@" ;; + smlnj) + cat "$program" | ( + cat < (), flush = fn () => () }; + x + end; +val smlrun__prev = ref ""; +Control.Print.out := { + say = fn s => + (if String.isSubstring " Error" s + then (Control.Print.out := smlrun__cp; + (#say smlrun__cp) (!smlrun__prev); + (#say smlrun__cp) s) + else (smlrun__prev := s; ())), + flush = fn s => () +}; +EOF + cat - + cat < "$gen_sml" + CM_VERBOSE=false sml "$gen_sml" ;; + *) + echo "ERROR: Unknown SML implementation name: $sml" 1>&2; + exit 2 ;; +esac + diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint-lock.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint-lock.json Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,46 @@ +{ + "libraries": { + "vamp-plugin-sdk": { + "pin": "da86fb0bccb3" + }, + "svcore": { + "pin": "710e6250a401" + }, + "svgui": { + "pin": "13d9b422f7fe" + }, + "svapp": { + "pin": "9e15607531b2" + }, + "checker": { + "pin": "2e8a5f665a07" + }, + "piper": { + "pin": "f5a04ffe4d5a0ae01e77018a86a59b48a425e674" + }, + "piper-cpp": { + "pin": "44cb74e186a703e7e6ce403aa295913a87b88d62" + }, + "dataquay": { + "pin": "807b55408d9e" + }, + "bqvec": { + "pin": "3c9de9e7f6e8" + }, + "bqfft": { + "pin": "a766fe47501b" + }, + "bqresample": { + "pin": "a9a5555d9b6d" + }, + "bqaudioio": { + "pin": "138a7a8b546b" + }, + "sv-dependency-builds": { + "pin": "f1a9b270e043" + }, + "icons/scalable": { + "pin": "1c6516ba7fc1" + } + } +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint-project.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint-project.json Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,83 @@ +{ + "config": { + "extdir": "." + }, + "services": { + "soundsoftware": { + "vcs": ["hg", "git"], + "anonymous": "https://code.soundsoftware.ac.uk/{vcs}/{repository}", + "authenticated": "https://{account}@code.soundsoftware.ac.uk/{vcs}/{repository}" + } + }, + "libraries": { + "vamp-plugin-sdk": { + "vcs": "hg", + "service": "soundsoftware" + }, + "svcore": { + "vcs": "hg", + "service": "soundsoftware", + "branch": "zoom" + }, + "svgui": { + "vcs": "hg", + "service": "soundsoftware", + "branch": "zoom" + }, + "svapp": { + "vcs": "hg", + "service": "soundsoftware" + }, + "checker": { + "vcs": "hg", + "service": "soundsoftware", + "repository": "vamp-plugin-load-checker" + }, + "piper": { + "vcs": "git", + "service": "github", + "owner": "piper-audio" + }, + "piper-cpp": { + "vcs": "git", + "service": "github", + "owner": "piper-audio", + "repository": "piper-vamp-cpp" + }, + "dataquay": { + "vcs": "hg", + "service": "bitbucket", + "owner": "breakfastquay" + }, + "bqvec": { + "vcs": "hg", + "service": "bitbucket", + "owner": "breakfastquay" + }, + "bqfft": { + "vcs": "hg", + "service": "bitbucket", + "owner": "breakfastquay" + }, + "bqresample": { + "vcs": "hg", + "service": "bitbucket", + "owner": "breakfastquay" + }, + "bqaudioio": { + "vcs": "hg", + "service": "bitbucket", + "owner": "breakfastquay" + }, + "sv-dependency-builds": { + "vcs": "hg", + "service": "soundsoftware" + }, + "icons/scalable": { + "vcs": "hg", + "service": "soundsoftware", + "repository": "sv-iconset" + } + } +} + diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint.bat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint.bat Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,3 @@ +@echo off +PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '%~dpn0.ps1' %*"; + diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint.pri --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint.pri Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,7 @@ + +repoint.target = $$PWD/.repoint.point +repoint.depends = $$PWD/repoint-project.json $$PWD/repoint-lock.json +repoint.commands = $$PWD/repoint install --directory $$PWD + +QMAKE_EXTRA_TARGETS += repoint +PRE_TARGETDEPS += $$repoint.target diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint.ps1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint.ps1 Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,117 @@ +<# + +.SYNOPSIS +A simple manager for third-party source code dependencies. +Run "repoint help" for more documentation. + +#> + +Set-StrictMode -Version 2.0 +$ErrorActionPreference = "Stop" +$env:HGPLAIN = "true" + +$sml = $env:REPOINT_SML + +$mydir = Split-Path $MyInvocation.MyCommand.Path -Parent +$program = "$mydir/repoint.sml" + +# We need either Poly/ML or SML/NJ. No great preference as to which. + +# Typical locations +$env:PATH = "$env:PATH;C:\Program Files (x86)\SMLNJ\bin;C:\Program Files\Poly ML;C:\Program Files (x86)\Poly ML" + +if (!$sml) { + if (Get-Command "sml" -ErrorAction SilentlyContinue) { + $sml = "smlnj" + } elseif (Get-Command "polyml" -ErrorAction SilentlyContinue) { + $sml = "poly" + } else { + echo @" + +ERROR: No supported SML compiler or interpreter found + + The Repoint external source code manager needs a Standard ML (SML) + compiler or interpreter to run. + + Please ensure you have one of the following SML implementations + installed and present in your PATH, and try again. + + 1. Standard ML of New Jersey + - executable name: sml + + 2. Poly/ML + - executable name: polyml + +"@ + exit 1 + } +} + +if ($args -match "'""") { + $arglist = '["usage"]' +} else { + $arglist = '["' + ($args -join '","') + '"]' +} + +if ($sml -eq "poly") { + + $program = $program -replace "\\","\\\\" + echo "use ""$program""; repoint $arglist" | polyml -q --error-exit | Out-Host + + if (-not $?) { + exit $LastExitCode + } + +} elseif ($sml -eq "smlnj") { + + $lines = @(Get-Content $program) + $lines = $lines -notmatch "val _ = main ()" + + $intro = @" +val smlrun__cp = + let val x = !Control.Print.out in + Control.Print.out := { say = fn _ => (), flush = fn () => () }; + x + end; +val smlrun__prev = ref ""; +Control.Print.out := { + say = fn s => + (if String.isSubstring "Error" s orelse String.isSubstring "Fail" s + then (Control.Print.out := smlrun__cp; + (#say smlrun__cp) (!smlrun__prev); + (#say smlrun__cp) s) + else (smlrun__prev := s; ())), + flush = fn s => () +}; +"@ -split "[\r\n]+" + + $outro = @" +val _ = repoint $arglist; +val _ = OS.Process.exit (OS.Process.success); +"@ -split "[\r\n]+" + + $script = @() + $script += $intro + $script += $lines + $script += $outro + + $tmpfile = ([System.IO.Path]::GetTempFileName()) -replace "[.]tmp",".sml" + + $script | Out-File -Encoding "ASCII" $tmpfile + + $env:CM_VERBOSE="false" + + sml $tmpfile + + if (-not $?) { + del $tmpfile + exit $LastExitCode + } + + del $tmpfile + +} else { + + "Unknown SML implementation name: $sml" + exit 2 +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 repoint.sml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/repoint.sml Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,2707 @@ +(* + DO NOT EDIT THIS FILE. + This file is automatically generated from the individual + source files in the Repoint repository. +*) + +(* + Repoint + + A simple manager for third-party source code dependencies + + Copyright 2018 Chris Cannam, Particular Programs Ltd, + and Queen Mary, University of London + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of Chris Cannam, + Particular Programs Ltd, and Queen Mary, University of London + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*) + +val repoint_version = "1.1" + + +datatype vcs = + HG | + GIT | + SVN + +datatype source = + URL_SOURCE of string | + SERVICE_SOURCE of { + service : string, + owner : string option, + repo : string option + } + +type id_or_tag = string + +datatype pin = + UNPINNED | + PINNED of id_or_tag + +datatype libstate = + ABSENT | + CORRECT | + SUPERSEDED | + WRONG + +datatype localstate = + MODIFIED | + LOCK_MISMATCHED | + CLEAN + +datatype branch = + BRANCH of string | + DEFAULT_BRANCH + +(* If we can recover from an error, for example by reporting failure + for this one thing and going on to the next thing, then the error + should usually be returned through a result type rather than an + exception. *) + +datatype 'a result = + OK of 'a | + ERROR of string + +type libname = string + +type libspec = { + libname : libname, + vcs : vcs, + source : source, + branch : branch, + project_pin : pin, + lock_pin : pin +} + +type lock = { + libname : libname, + id_or_tag : id_or_tag +} + +type remote_spec = { + anon : string option, + auth : string option +} + +type provider = { + service : string, + supports : vcs list, + remote_spec : remote_spec +} + +type account = { + service : string, + login : string +} + +type context = { + rootpath : string, + extdir : string, + providers : provider list, + accounts : account list +} + +type userconfig = { + providers : provider list, + accounts : account list +} + +type project = { + context : context, + libs : libspec list +} + +structure RepointFilenames = struct + val project_file = "repoint-project.json" + val project_lock_file = "repoint-lock.json" + val project_completion_file = ".repoint.point" + val user_config_file = ".repoint.json" + val archive_dir = ".repoint-archive" +end + +signature VCS_CONTROL = sig + + (** Check whether the given VCS is installed and working *) + val is_working : context -> bool result + + (** Test whether the library is present locally at all *) + val exists : context -> libname -> bool result + + (** Return the id (hash) of the current revision for the library *) + val id_of : context -> libname -> id_or_tag result + + (** Test whether the library is at the given id *) + val is_at : context -> libname * id_or_tag -> bool result + + (** Test whether the library is on the given branch, i.e. is at + the branch tip or an ancestor of it *) + val is_on_branch : context -> libname * branch -> bool result + + (** Test whether the library is at the newest revision for the + given branch. False may indicate that the branch has advanced + or that the library is not on the branch at all. This function + may use the network to check for new revisions *) + val is_newest : context -> libname * source * branch -> bool result + + (** Test whether the library is at the newest revision available + locally for the given branch. False may indicate that the + branch has advanced or that the library is not on the branch + at all. This function must not use the network *) + val is_newest_locally : context -> libname * branch -> bool result + + (** Test whether the library has been modified in the local + working copy *) + val is_modified_locally : context -> libname -> bool result + + (** Check out, i.e. clone a fresh copy of, the repo for the given + library on the given branch *) + val checkout : context -> libname * source * branch -> unit result + + (** Update the library to the given branch tip. Assumes that a + local copy of the library already exists *) + val update : context -> libname * source * branch -> unit result + + (** Update the library to the given specific id or tag *) + val update_to : context -> libname * source * id_or_tag -> unit result + + (** Return a URL from which the library can be cloned, given that + the local copy already exists. For a DVCS this can be the + local copy, but for a centralised VCS it will have to be the + remote repository URL. Used for archiving *) + val copy_url_for : context -> libname -> string result +end + +signature LIB_CONTROL = sig + val review : context -> libspec -> (libstate * localstate) result + val status : context -> libspec -> (libstate * localstate) result + val update : context -> libspec -> unit result + val id_of : context -> libspec -> id_or_tag result + val is_working : context -> vcs -> bool result +end + +structure FileBits :> sig + val extpath : context -> string + val libpath : context -> libname -> string + val subpath : context -> libname -> string -> string + val command_output : context -> libname -> string list -> string result + val command : context -> libname -> string list -> unit result + val file_url : string -> string + val file_contents : string -> string + val mydir : unit -> string + val homedir : unit -> string + val mkpath : string -> unit result + val rmpath : string -> unit result + val nonempty_dir_exists : string -> bool + val project_spec_path : string -> string + val project_lock_path : string -> string + val project_completion_path : string -> string + val verbose : unit -> bool +end = struct + + fun verbose () = + case OS.Process.getEnv "REPOINT_VERBOSE" of + SOME "0" => false + | SOME _ => true + | NONE => false + + fun split_relative path desc = + case OS.Path.fromString path of + { isAbs = true, ... } => raise Fail (desc ^ " may not be absolute") + | { arcs, ... } => arcs + + fun extpath ({ rootpath, extdir, ... } : context) = + let val { isAbs, vol, arcs } = OS.Path.fromString rootpath + in OS.Path.toString { + isAbs = isAbs, + vol = vol, + arcs = arcs @ + split_relative extdir "extdir" + } + end + + fun subpath ({ rootpath, extdir, ... } : context) libname remainder = + (* NB libname is allowed to be a path fragment, e.g. foo/bar *) + let val { isAbs, vol, arcs } = OS.Path.fromString rootpath + in OS.Path.toString { + isAbs = isAbs, + vol = vol, + arcs = arcs @ + split_relative extdir "extdir" @ + split_relative libname "library path" @ + split_relative remainder "subpath" + } + end + + fun libpath context "" = + extpath context + | libpath context libname = + subpath context libname "" + + fun project_file_path rootpath filename = + let val { isAbs, vol, arcs } = OS.Path.fromString rootpath + in OS.Path.toString { + isAbs = isAbs, + vol = vol, + arcs = arcs @ [ filename ] + } + end + + fun project_spec_path rootpath = + project_file_path rootpath (RepointFilenames.project_file) + + fun project_lock_path rootpath = + project_file_path rootpath (RepointFilenames.project_lock_file) + + fun project_completion_path rootpath = + project_file_path rootpath (RepointFilenames.project_completion_file) + + fun trim str = + hd (String.fields (fn x => x = #"\n" orelse x = #"\r") str) + + fun file_url path = + let val forward_path = + String.translate (fn #"\\" => "/" | + c => Char.toString c) + (OS.Path.mkCanonical path) + in + (* Path is expected to be absolute already, but if it + starts with a drive letter, we'll need an extra slash *) + case explode forward_path of + #"/"::rest => "file:///" ^ implode rest + | _ => "file:///" ^ forward_path + end + + fun file_contents filename = + let val stream = TextIO.openIn filename + fun read_all str acc = + case TextIO.inputLine str of + SOME line => read_all str (trim line :: acc) + | NONE => rev acc + val contents = read_all stream [] + val _ = TextIO.closeIn stream + in + String.concatWith "\n" contents + end + + fun expand_commandline cmdlist = + (* We are quite strict about what we accept here, except + for the first element in cmdlist which is assumed to be a + known command location rather than arbitrary user input. *) + let open Char + fun quote arg = + if List.all + (fn c => isAlphaNum c orelse c = #"-" orelse c = #"_") + (explode arg) + then arg + else "\"" ^ arg ^ "\"" + fun check arg = + let val valid = explode " /#:;?,._-{}@=+" + in + app (fn c => + if isAlphaNum c orelse + List.exists (fn v => v = c) valid orelse + c > chr 127 + then () + else raise Fail ("Invalid character '" ^ + (Char.toString c) ^ + "' in command list")) + (explode arg); + arg + end + in + String.concatWith " " + (map quote + (hd cmdlist :: map check (tl cmdlist))) + end + + val tick_cycle = ref 0 + val tick_chars = Vector.fromList (map String.str (explode "|/-\\")) + + fun tick libname cmdlist = + let val n = Vector.length tick_chars + fun pad_to n str = + if n <= String.size str then str + else pad_to n (str ^ " ") + val name = if libname <> "" then libname + else if cmdlist = nil then "" + else hd (rev cmdlist) + in + print (" " ^ + Vector.sub(tick_chars, !tick_cycle) ^ " " ^ + pad_to 70 name ^ + "\r"); + tick_cycle := (if !tick_cycle = n - 1 then 0 else 1 + !tick_cycle) + end + + fun run_command context libname cmdlist redirect = + let open OS + val dir = libpath context libname + val cmd = expand_commandline cmdlist + val _ = if verbose () + then print ("\n=== " ^ dir ^ "\n<<< " ^ cmd ^ "\n") + else tick libname cmdlist + val _ = FileSys.chDir dir + val status = case redirect of + NONE => Process.system cmd + | SOME file => Process.system (cmd ^ ">" ^ file) + in + if Process.isSuccess status + then OK () + else ERROR ("Command failed: " ^ cmd ^ " (in dir " ^ dir ^ ")") + end + handle ex => ERROR ("Unable to run command: " ^ exnMessage ex) + + fun command context libname cmdlist = + run_command context libname cmdlist NONE + + fun command_output context libname cmdlist = + let open OS + val tmpFile = FileSys.tmpName () + val result = run_command context libname cmdlist (SOME tmpFile) + val contents = file_contents tmpFile + val _ = if verbose () + then print (">>> \"" ^ contents ^ "\"\n") + else () + in + FileSys.remove tmpFile handle _ => (); + case result of + OK () => OK contents + | ERROR e => ERROR e + end + + fun mydir () = + let open OS + val { dir, file } = Path.splitDirFile (CommandLine.name ()) + in + FileSys.realPath + (if Path.isAbsolute dir + then dir + else Path.concat (FileSys.getDir (), dir)) + end + + fun homedir () = + (* Failure is not routine, so we use an exception here *) + case (OS.Process.getEnv "HOME", + OS.Process.getEnv "HOMEPATH") of + (SOME home, _) => home + | (NONE, SOME home) => home + | (NONE, NONE) => + raise Fail "Failed to look up home directory from environment" + + fun mkpath' path = + if OS.FileSys.isDir path handle _ => false + then OK () + else case OS.Path.fromString path of + { arcs = nil, ... } => OK () + | { isAbs = false, ... } => ERROR "mkpath requires absolute path" + | { isAbs, vol, arcs } => + case mkpath' (OS.Path.toString { (* parent *) + isAbs = isAbs, + vol = vol, + arcs = rev (tl (rev arcs)) }) of + ERROR e => ERROR e + | OK () => ((OS.FileSys.mkDir path; OK ()) + handle OS.SysErr (e, _) => + ERROR ("Directory creation failed: " ^ e)) + + fun mkpath path = + mkpath' (OS.Path.mkCanonical path) + + fun dir_contents dir = + let open OS + fun files_from dirstream = + case FileSys.readDir dirstream of + NONE => [] + | SOME file => + (* readDir is supposed to filter these, + but let's be extra cautious: *) + if file = Path.parentArc orelse file = Path.currentArc + then files_from dirstream + else file :: files_from dirstream + val stream = FileSys.openDir dir + val files = map (fn f => Path.joinDirFile + { dir = dir, file = f }) + (files_from stream) + val _ = FileSys.closeDir stream + in + files + end + + fun rmpath' path = + let open OS + fun remove path = + if FileSys.isLink path (* dangling links bother isDir *) + then FileSys.remove path + else if FileSys.isDir path + then (app remove (dir_contents path); FileSys.rmDir path) + else FileSys.remove path + in + (remove path; OK ()) + handle SysErr (e, _) => ERROR ("Path removal failed: " ^ e) + end + + fun rmpath path = + rmpath' (OS.Path.mkCanonical path) + + fun nonempty_dir_exists path = + let open OS.FileSys + in + (not (isLink path) andalso + isDir path andalso + dir_contents path <> []) + handle _ => false + end + +end + +functor LibControlFn (V: VCS_CONTROL) :> LIB_CONTROL = struct + + (* Valid states for unpinned libraries: + + - CORRECT: We are on the right branch and are up-to-date with + it as far as we can tell. (If not using the network, this + should be reported to user as "Present" rather than "Correct" + as the remote repo may have advanced without us knowing.) + + - SUPERSEDED: We are on the right branch but we can see that + there is a newer revision either locally or on the remote (in + Git terms, we are at an ancestor of the desired branch tip). + + - WRONG: We are on the wrong branch (in Git terms, we are not + at the desired branch tip or any ancestor of it). + + - ABSENT: Repo doesn't exist here at all. + + Valid states for pinned libraries: + + - CORRECT: We are at the pinned revision. + + - WRONG: We are at any revision other than the pinned one. + + - ABSENT: Repo doesn't exist here at all. + *) + + fun check with_network context + ({ libname, source, branch, + project_pin, lock_pin, ... } : libspec) = + let fun check_unpinned () = + let val newest = + if with_network + then V.is_newest context (libname, source, branch) + else V.is_newest_locally context (libname, branch) + in + case newest of + ERROR e => ERROR e + | OK true => OK CORRECT + | OK false => + case V.is_on_branch context (libname, branch) of + ERROR e => ERROR e + | OK true => OK SUPERSEDED + | OK false => OK WRONG + end + fun check_pinned target = + case V.is_at context (libname, target) of + ERROR e => ERROR e + | OK true => OK CORRECT + | OK false => OK WRONG + fun check_remote () = + case project_pin of + UNPINNED => check_unpinned () + | PINNED target => check_pinned target + fun check_local () = + case V.is_modified_locally context libname of + ERROR e => ERROR e + | OK true => OK MODIFIED + | OK false => + case lock_pin of + UNPINNED => OK CLEAN + | PINNED target => + case V.is_at context (libname, target) of + ERROR e => ERROR e + | OK true => OK CLEAN + | OK false => OK LOCK_MISMATCHED + in + case V.exists context libname of + ERROR e => ERROR e + | OK false => OK (ABSENT, CLEAN) + | OK true => + case (check_remote (), check_local ()) of + (ERROR e, _) => ERROR e + | (_, ERROR e) => ERROR e + | (OK r, OK l) => OK (r, l) + end + + val review = check true + val status = check false + + fun update context + ({ libname, source, branch, + project_pin, lock_pin, ... } : libspec) = + let fun update_unpinned () = + case V.is_newest context (libname, source, branch) of + ERROR e => ERROR e + | OK true => OK () + | OK false => V.update context (libname, source, branch) + fun update_pinned target = + case V.is_at context (libname, target) of + ERROR e => ERROR e + | OK true => OK () + | OK false => V.update_to context (libname, source, target) + fun update' () = + case lock_pin of + PINNED target => update_pinned target + | UNPINNED => + case project_pin of + PINNED target => update_pinned target + | UNPINNED => update_unpinned () + in + case V.exists context libname of + ERROR e => ERROR e + | OK true => update' () + | OK false => + case V.checkout context (libname, source, branch) of + ERROR e => ERROR e + | OK () => update' () + end + + fun id_of context ({ libname, ... } : libspec) = + V.id_of context libname + + fun is_working context vcs = + V.is_working context + +end + +(* Simple Standard ML JSON parser + https://bitbucket.org/cannam/sml-simplejson + Copyright 2017 Chris Cannam. BSD licence. + Parts based on the JSON parser in the Ponyo library by Phil Eaton. +*) + +signature JSON = sig + + datatype json = OBJECT of (string * json) list + | ARRAY of json list + | NUMBER of real + | STRING of string + | BOOL of bool + | NULL + + datatype 'a result = OK of 'a + | ERROR of string + + val parse : string -> json result + val serialise : json -> string + val serialiseIndented : json -> string + +end + +structure Json :> JSON = struct + + datatype json = OBJECT of (string * json) list + | ARRAY of json list + | NUMBER of real + | STRING of string + | BOOL of bool + | NULL + + datatype 'a result = OK of 'a + | ERROR of string + + structure T = struct + datatype token = NUMBER of char list + | STRING of string + | BOOL of bool + | NULL + | CURLY_L + | CURLY_R + | SQUARE_L + | SQUARE_R + | COLON + | COMMA + + fun toString t = + case t of NUMBER digits => implode digits + | STRING s => s + | BOOL b => Bool.toString b + | NULL => "null" + | CURLY_L => "{" + | CURLY_R => "}" + | SQUARE_L => "[" + | SQUARE_R => "]" + | COLON => ":" + | COMMA => "," + end + + fun bmpToUtf8 cp = (* convert a codepoint in Unicode BMP to utf8 bytes *) + let open Word + infix 6 orb andb >> + in + map (Char.chr o toInt) + (if cp < 0wx80 then + [cp] + else if cp < 0wx800 then + [0wxc0 orb (cp >> 0w6), 0wx80 orb (cp andb 0wx3f)] + else if cp < 0wx10000 then + [0wxe0 orb (cp >> 0w12), + 0wx80 orb ((cp >> 0w6) andb 0wx3f), + 0wx80 orb (cp andb 0wx3f)] + else raise Fail ("Invalid BMP point " ^ (Word.toString cp))) + end + + fun error pos text = ERROR (text ^ " at character position " ^ + Int.toString (pos - 1)) + fun token_error pos = error pos ("Unexpected token") + + fun lexNull pos acc (#"u" :: #"l" :: #"l" :: xs) = + lex (pos + 3) (T.NULL :: acc) xs + | lexNull pos acc _ = token_error pos + + and lexTrue pos acc (#"r" :: #"u" :: #"e" :: xs) = + lex (pos + 3) (T.BOOL true :: acc) xs + | lexTrue pos acc _ = token_error pos + + and lexFalse pos acc (#"a" :: #"l" :: #"s" :: #"e" :: xs) = + lex (pos + 4) (T.BOOL false :: acc) xs + | lexFalse pos acc _ = token_error pos + + and lexChar tok pos acc xs = + lex pos (tok :: acc) xs + + and lexString pos acc cc = + let datatype escaped = ESCAPED | NORMAL + fun lexString' pos text ESCAPED [] = + error pos "End of input during escape sequence" + | lexString' pos text NORMAL [] = + error pos "End of input during string" + | lexString' pos text ESCAPED (x :: xs) = + let fun esc c = lexString' (pos + 1) (c :: text) NORMAL xs + in case x of + #"\"" => esc x + | #"\\" => esc x + | #"/" => esc x + | #"b" => esc #"\b" + | #"f" => esc #"\f" + | #"n" => esc #"\n" + | #"r" => esc #"\r" + | #"t" => esc #"\t" + | _ => error pos ("Invalid escape \\" ^ + Char.toString x) + end + | lexString' pos text NORMAL (#"\\" :: #"u" ::a::b::c::d:: xs) = + if List.all Char.isHexDigit [a,b,c,d] + then case Word.fromString ("0wx" ^ (implode [a,b,c,d])) of + SOME w => (let val utf = rev (bmpToUtf8 w) in + lexString' (pos + 6) (utf @ text) + NORMAL xs + end + handle Fail err => error pos err) + | NONE => error pos "Invalid Unicode BMP escape sequence" + else error pos "Invalid Unicode BMP escape sequence" + | lexString' pos text NORMAL (x :: xs) = + if Char.ord x < 0x20 + then error pos "Invalid unescaped control character" + else + case x of + #"\"" => OK (rev text, xs, pos + 1) + | #"\\" => lexString' (pos + 1) text ESCAPED xs + | _ => lexString' (pos + 1) (x :: text) NORMAL xs + in + case lexString' pos [] NORMAL cc of + OK (text, rest, newpos) => + lex newpos (T.STRING (implode text) :: acc) rest + | ERROR e => ERROR e + end + + and lexNumber firstChar pos acc cc = + let val valid = explode ".+-e" + fun lexNumber' pos digits [] = (rev digits, [], pos) + | lexNumber' pos digits (x :: xs) = + if x = #"E" then lexNumber' (pos + 1) (#"e" :: digits) xs + else if Char.isDigit x orelse List.exists (fn c => x = c) valid + then lexNumber' (pos + 1) (x :: digits) xs + else (rev digits, x :: xs, pos) + val (digits, rest, newpos) = + lexNumber' (pos - 1) [] (firstChar :: cc) + in + case digits of + [] => token_error pos + | _ => lex newpos (T.NUMBER digits :: acc) rest + end + + and lex pos acc [] = OK (rev acc) + | lex pos acc (x::xs) = + (case x of + #" " => lex + | #"\t" => lex + | #"\n" => lex + | #"\r" => lex + | #"{" => lexChar T.CURLY_L + | #"}" => lexChar T.CURLY_R + | #"[" => lexChar T.SQUARE_L + | #"]" => lexChar T.SQUARE_R + | #":" => lexChar T.COLON + | #"," => lexChar T.COMMA + | #"\"" => lexString + | #"t" => lexTrue + | #"f" => lexFalse + | #"n" => lexNull + | x => lexNumber x) (pos + 1) acc xs + + fun show [] = "end of input" + | show (tok :: _) = T.toString tok + + fun parseNumber digits = + (* Note lexNumber already case-insensitised the E for us *) + let open Char + + fun okExpDigits [] = false + | okExpDigits (c :: []) = isDigit c + | okExpDigits (c :: cs) = isDigit c andalso okExpDigits cs + + fun okExponent [] = false + | okExponent (#"+" :: cs) = okExpDigits cs + | okExponent (#"-" :: cs) = okExpDigits cs + | okExponent cc = okExpDigits cc + + fun okFracTrailing [] = true + | okFracTrailing (c :: cs) = + (isDigit c andalso okFracTrailing cs) orelse + (c = #"e" andalso okExponent cs) + + fun okFraction [] = false + | okFraction (c :: cs) = + isDigit c andalso okFracTrailing cs + + fun okPosTrailing [] = true + | okPosTrailing (#"." :: cs) = okFraction cs + | okPosTrailing (#"e" :: cs) = okExponent cs + | okPosTrailing (c :: cs) = + isDigit c andalso okPosTrailing cs + + fun okPositive [] = false + | okPositive (#"0" :: []) = true + | okPositive (#"0" :: #"." :: cs) = okFraction cs + | okPositive (#"0" :: #"e" :: cs) = okExponent cs + | okPositive (#"0" :: cs) = false + | okPositive (c :: cs) = isDigit c andalso okPosTrailing cs + + fun okNumber (#"-" :: cs) = okPositive cs + | okNumber cc = okPositive cc + in + if okNumber digits + then case Real.fromString (implode digits) of + NONE => ERROR "Number out of range" + | SOME r => OK r + else ERROR ("Invalid number \"" ^ (implode digits) ^ "\"") + end + + fun parseObject (T.CURLY_R :: xs) = OK (OBJECT [], xs) + | parseObject tokens = + let fun parsePair (T.STRING key :: T.COLON :: xs) = + (case parseTokens xs of + ERROR e => ERROR e + | OK (j, xs) => OK ((key, j), xs)) + | parsePair other = + ERROR ("Object key/value pair expected around \"" ^ + show other ^ "\"") + fun parseObject' acc [] = ERROR "End of input during object" + | parseObject' acc tokens = + case parsePair tokens of + ERROR e => ERROR e + | OK (pair, T.COMMA :: xs) => + parseObject' (pair :: acc) xs + | OK (pair, T.CURLY_R :: xs) => + OK (OBJECT (rev (pair :: acc)), xs) + | OK (_, _) => ERROR "Expected , or } after object element" + in + parseObject' [] tokens + end + + and parseArray (T.SQUARE_R :: xs) = OK (ARRAY [], xs) + | parseArray tokens = + let fun parseArray' acc [] = ERROR "End of input during array" + | parseArray' acc tokens = + case parseTokens tokens of + ERROR e => ERROR e + | OK (j, T.COMMA :: xs) => parseArray' (j :: acc) xs + | OK (j, T.SQUARE_R :: xs) => OK (ARRAY (rev (j :: acc)), xs) + | OK (_, _) => ERROR "Expected , or ] after array element" + in + parseArray' [] tokens + end + + and parseTokens [] = ERROR "Value expected" + | parseTokens (tok :: xs) = + (case tok of + T.NUMBER d => (case parseNumber d of + OK r => OK (NUMBER r, xs) + | ERROR e => ERROR e) + | T.STRING s => OK (STRING s, xs) + | T.BOOL b => OK (BOOL b, xs) + | T.NULL => OK (NULL, xs) + | T.CURLY_L => parseObject xs + | T.SQUARE_L => parseArray xs + | _ => ERROR ("Unexpected token " ^ T.toString tok ^ + " before " ^ show xs)) + + fun parse str = + case lex 1 [] (explode str) of + ERROR e => ERROR e + | OK tokens => case parseTokens tokens of + OK (value, []) => OK value + | OK (_, _) => ERROR "Extra data after input" + | ERROR e => ERROR e + + fun stringEscape s = + let fun esc x = [x, #"\\"] + fun escape' acc [] = rev acc + | escape' acc (x :: xs) = + escape' (case x of + #"\"" => esc x @ acc + | #"\\" => esc x @ acc + | #"\b" => esc #"b" @ acc + | #"\f" => esc #"f" @ acc + | #"\n" => esc #"n" @ acc + | #"\r" => esc #"r" @ acc + | #"\t" => esc #"t" @ acc + | _ => + let val c = Char.ord x + in + if c < 0x20 + then let val hex = Word.toString (Word.fromInt c) + in (rev o explode) (if c < 0x10 + then ("\\u000" ^ hex) + else ("\\u00" ^ hex)) + end @ acc + else + x :: acc + end) + xs + in + implode (escape' [] (explode s)) + end + + fun serialise json = + case json of + OBJECT pp => "{" ^ String.concatWith + "," (map (fn (key, value) => + serialise (STRING key) ^ ":" ^ + serialise value) pp) ^ + "}" + | ARRAY arr => "[" ^ String.concatWith "," (map serialise arr) ^ "]" + | NUMBER n => implode (map (fn #"~" => #"-" | c => c) + (explode (Real.toString n))) + | STRING s => "\"" ^ stringEscape s ^ "\"" + | BOOL b => Bool.toString b + | NULL => "null" + + fun serialiseIndented json = + let fun indent 0 = "" + | indent i = " " ^ indent (i - 1) + fun serialiseIndented' i json = + let val ser = serialiseIndented' (i + 1) + in + case json of + OBJECT [] => "{}" + | ARRAY [] => "[]" + | OBJECT pp => "{\n" ^ indent (i + 1) ^ + String.concatWith + (",\n" ^ indent (i + 1)) + (map (fn (key, value) => + ser (STRING key) ^ ": " ^ + ser value) pp) ^ + "\n" ^ indent i ^ "}" + | ARRAY arr => "[\n" ^ indent (i + 1) ^ + String.concatWith + (",\n" ^ indent (i + 1)) + (map ser arr) ^ + "\n" ^ indent i ^ "]" + | other => serialise other + end + in + serialiseIndented' 0 json ^ "\n" + end + +end + + +structure JsonBits :> sig + exception Config of string + val load_json_from : string -> Json.json (* filename -> json *) + val save_json_to : string -> Json.json -> unit + val lookup_optional : Json.json -> string list -> Json.json option + val lookup_optional_string : Json.json -> string list -> string option + val lookup_mandatory : Json.json -> string list -> Json.json + val lookup_mandatory_string : Json.json -> string list -> string +end = struct + + exception Config of string + + fun load_json_from filename = + case Json.parse (FileBits.file_contents filename) of + Json.OK json => json + | Json.ERROR e => raise Config ("Failed to parse file: " ^ e) + + fun save_json_to filename json = + (* using binary I/O to avoid ever writing CR/LF line endings *) + let val jstr = Json.serialiseIndented json + val stream = BinIO.openOut filename + in + BinIO.output (stream, Byte.stringToBytes jstr); + BinIO.closeOut stream + end + + fun lookup_optional json kk = + let fun lookup key = + case json of + Json.OBJECT kvs => + (case List.filter (fn (k, v) => k = key) kvs of + [] => NONE + | [(_,v)] => SOME v + | _ => raise Config ("Duplicate key: " ^ + (String.concatWith " -> " kk))) + | _ => raise Config "Object expected" + in + case kk of + [] => NONE + | key::[] => lookup key + | key::kk => case lookup key of + NONE => NONE + | SOME j => lookup_optional j kk + end + + fun lookup_optional_string json kk = + case lookup_optional json kk of + SOME (Json.STRING s) => SOME s + | SOME _ => raise Config ("Value (if present) must be string: " ^ + (String.concatWith " -> " kk)) + | NONE => NONE + + fun lookup_mandatory json kk = + case lookup_optional json kk of + SOME v => v + | NONE => raise Config ("Value is mandatory: " ^ + (String.concatWith " -> " kk)) + + fun lookup_mandatory_string json kk = + case lookup_optional json kk of + SOME (Json.STRING s) => s + | _ => raise Config ("Value must be string: " ^ + (String.concatWith " -> " kk)) +end + +structure Provider :> sig + val load_providers : Json.json -> provider list + val load_more_providers : provider list -> Json.json -> provider list + val remote_url : context -> vcs -> source -> libname -> string +end = struct + + val known_providers : provider list = + [ { + service = "bitbucket", + supports = [HG, GIT], + remote_spec = { + anon = SOME "https://bitbucket.org/{owner}/{repository}", + auth = SOME "ssh://{vcs}@bitbucket.org/{owner}/{repository}" + } + }, + { + service = "github", + supports = [GIT], + remote_spec = { + anon = SOME "https://github.com/{owner}/{repository}", + auth = SOME "ssh://{vcs}@github.com/{owner}/{repository}" + } + } + ] + + fun vcs_name vcs = + case vcs of HG => "hg" + | GIT => "git" + | SVN => "svn" + + fun vcs_from_name name = + case name of "hg" => HG + | "git" => GIT + | "svn" => SVN + | other => raise Fail ("Unknown vcs name \"" ^ name ^ "\"") + + fun load_more_providers previously_loaded json = + let open JsonBits + fun load pjson pname : provider = + { + service = pname, + supports = + case lookup_mandatory pjson ["vcs"] of + Json.ARRAY vv => + map (fn (Json.STRING v) => vcs_from_name v + | _ => raise Fail "Strings expected in vcs array") + vv + | _ => raise Fail "Array expected for vcs", + remote_spec = { + anon = lookup_optional_string pjson ["anonymous"], + auth = lookup_optional_string pjson ["authenticated"] + } + } + val loaded = + case lookup_optional json ["services"] of + NONE => [] + | SOME (Json.OBJECT pl) => map (fn (k, v) => load v k) pl + | _ => raise Fail "Object expected for services in config" + val newly_loaded = + List.filter (fn p => not (List.exists (fn pp => #service p = + #service pp) + previously_loaded)) + loaded + in + previously_loaded @ newly_loaded + end + + fun load_providers json = + load_more_providers known_providers json + + fun expand_spec spec { vcs, service, owner, repo } login = + (* ugly *) + let fun replace str = + case str of + "vcs" => vcs_name vcs + | "service" => service + | "owner" => + (case owner of + SOME ostr => ostr + | NONE => raise Fail ("Owner not specified for service " ^ + service)) + | "repository" => repo + | "account" => + (case login of + SOME acc => acc + | NONE => raise Fail ("Account not given for service " ^ + service)) + | other => raise Fail ("Unknown variable \"" ^ other ^ + "\" in spec for service " ^ service) + fun expand' acc sstr = + case Substring.splitl (fn c => c <> #"{") sstr of + (pfx, sfx) => + if Substring.isEmpty sfx + then rev (pfx :: acc) + else + case Substring.splitl (fn c => c <> #"}") sfx of + (tok, remainder) => + if Substring.isEmpty remainder + then rev (tok :: pfx :: acc) + else let val replacement = + replace + (* tok begins with "{": *) + (Substring.string + (Substring.triml 1 tok)) + in + expand' (Substring.full replacement :: + pfx :: acc) + (* remainder begins with "}": *) + (Substring.triml 1 remainder) + end + in + Substring.concat (expand' [] (Substring.full spec)) + end + + fun provider_url req login providers = + case providers of + [] => raise Fail ("Unknown service \"" ^ (#service req) ^ + "\" for vcs \"" ^ (vcs_name (#vcs req)) ^ "\"") + | ({ service, supports, remote_spec : remote_spec } :: rest) => + if service <> (#service req) orelse + not (List.exists (fn v => v = (#vcs req)) supports) + then provider_url req login rest + else + case (login, #auth remote_spec, #anon remote_spec) of + (SOME _, SOME auth, _) => expand_spec auth req login + | (SOME _, _, SOME anon) => expand_spec anon req NONE + | (NONE, _, SOME anon) => expand_spec anon req NONE + | _ => raise Fail ("No suitable anonymous or authenticated " ^ + "URL spec provided for service \"" ^ + service ^ "\"") + + fun login_for ({ accounts, ... } : context) service = + case List.find (fn a => service = #service a) accounts of + SOME { login, ... } => SOME login + | NONE => NONE + + fun reponame_for path = + case String.tokens (fn c => c = #"/") path of + [] => raise Fail "Non-empty library path required" + | toks => hd (rev toks) + + fun remote_url (context : context) vcs source libname = + case source of + URL_SOURCE u => u + | SERVICE_SOURCE { service, owner, repo } => + provider_url { vcs = vcs, + service = service, + owner = owner, + repo = case repo of + SOME r => r + | NONE => reponame_for libname } + (login_for context service) + (#providers context) +end + +structure HgControl :> VCS_CONTROL = struct + + (* Pulls always use an explicit URL, never just the default + remote, in order to ensure we update properly if the location + given in the project file changes. *) + + type vcsstate = { id: string, modified: bool, + branch: string, tags: string list } + + val hg_program = "hg" + + val hg_args = [ "--config", "ui.interactive=true", + "--config", "ui.merge=:merge" ] + + fun hg_command context libname args = + FileBits.command context libname (hg_program :: hg_args @ args) + + fun hg_command_output context libname args = + FileBits.command_output context libname (hg_program :: hg_args @ args) + + fun is_working context = + case hg_command_output context "" ["--version"] of + OK "" => OK false + | OK _ => OK true + | ERROR e => ERROR e + + fun exists context libname = + OK (OS.FileSys.isDir (FileBits.subpath context libname ".hg")) + handle _ => OK false + + fun remote_for context (libname, source) = + Provider.remote_url context HG source libname + + fun current_state context libname : vcsstate result = + let fun is_branch text = text <> "" andalso #"(" = hd (explode text) + and extract_branch b = + if is_branch b (* need to remove enclosing parens *) + then (implode o rev o tl o rev o tl o explode) b + else "default" + and is_modified id = id <> "" andalso #"+" = hd (rev (explode id)) + and extract_id id = + if is_modified id (* need to remove trailing "+" *) + then (implode o rev o tl o rev o explode) id + else id + and split_tags tags = String.tokens (fn c => c = #"/") tags + and state_for (id, branch, tags) = + OK { id = extract_id id, + modified = is_modified id, + branch = extract_branch branch, + tags = split_tags tags } + in + case hg_command_output context libname ["id"] of + ERROR e => ERROR e + | OK out => + case String.tokens (fn x => x = #" ") out of + [id, branch, tags] => state_for (id, branch, tags) + | [id, other] => if is_branch other + then state_for (id, other, "") + else state_for (id, "", other) + | [id] => state_for (id, "", "") + | _ => ERROR ("Unexpected output from hg id: " ^ out) + end + + fun branch_name branch = case branch of + DEFAULT_BRANCH => "default" + | BRANCH "" => "default" + | BRANCH b => b + + fun id_of context libname = + case current_state context libname of + ERROR e => ERROR e + | OK { id, ... } => OK id + + fun is_at context (libname, id_or_tag) = + case current_state context libname of + ERROR e => ERROR e + | OK { id, tags, ... } => + OK (String.isPrefix id_or_tag id orelse + String.isPrefix id id_or_tag orelse + List.exists (fn t => t = id_or_tag) tags) + + fun is_on_branch context (libname, b) = + case current_state context libname of + ERROR e => ERROR e + | OK { branch, ... } => OK (branch = branch_name b) + + fun is_newest_locally context (libname, branch) = + case hg_command_output context libname + ["log", "-l1", + "-b", branch_name branch, + "--template", "{node}"] of + ERROR e => OK false (* desired branch does not exist *) + | OK newest_in_repo => is_at context (libname, newest_in_repo) + + fun pull context (libname, source) = + let val url = remote_for context (libname, source) + in + hg_command context libname + (if FileBits.verbose () + then ["pull", url] + else ["pull", "-q", url]) + end + + fun is_newest context (libname, source, branch) = + case is_newest_locally context (libname, branch) of + ERROR e => ERROR e + | OK false => OK false + | OK true => + case pull context (libname, source) of + ERROR e => ERROR e + | _ => is_newest_locally context (libname, branch) + + fun is_modified_locally context libname = + case current_state context libname of + ERROR e => ERROR e + | OK { modified, ... } => OK modified + + fun checkout context (libname, source, branch) = + let val url = remote_for context (libname, source) + in + (* make the lib dir rather than just the ext dir, since + the lib dir might be nested and hg will happily check + out into an existing empty dir anyway *) + case FileBits.mkpath (FileBits.libpath context libname) of + ERROR e => ERROR e + | _ => hg_command context "" + ["clone", "-u", branch_name branch, + url, libname] + end + + fun update context (libname, source, branch) = + let val pull_result = pull context (libname, source) + in + case hg_command context libname ["update", branch_name branch] of + ERROR e => ERROR e + | _ => + case pull_result of + ERROR e => ERROR e + | _ => OK () + end + + fun update_to context (libname, _, "") = + ERROR "Non-empty id (tag or revision id) required for update_to" + | update_to context (libname, source, id) = + let val pull_result = pull context (libname, source) + in + case hg_command context libname ["update", "-r", id] of + OK _ => OK () + | ERROR e => + case pull_result of + ERROR e' => ERROR e' (* this was the ur-error *) + | _ => ERROR e + end + + fun copy_url_for context libname = + OK (FileBits.file_url (FileBits.libpath context libname)) + +end + +structure GitControl :> VCS_CONTROL = struct + + (* With Git repos we always operate in detached HEAD state. Even + the master branch is checked out using a remote reference + (repoint/master). The remote we use is always named repoint, and we + update it to the expected URL each time we fetch, in order to + ensure we update properly if the location given in the project + file changes. The origin remote is unused. *) + + val git_program = "git" + + fun git_command context libname args = + FileBits.command context libname (git_program :: args) + + fun git_command_output context libname args = + FileBits.command_output context libname (git_program :: args) + + fun is_working context = + case git_command_output context "" ["--version"] of + OK "" => OK false + | OK _ => OK true + | ERROR e => ERROR e + + fun exists context libname = + OK (OS.FileSys.isDir (FileBits.subpath context libname ".git")) + handle _ => OK false + + fun remote_for context (libname, source) = + Provider.remote_url context GIT source libname + + fun branch_name branch = case branch of + DEFAULT_BRANCH => "master" + | BRANCH "" => "master" + | BRANCH b => b + + val our_remote = "repoint" + + fun remote_branch_name branch = our_remote ^ "/" ^ branch_name branch + + fun checkout context (libname, source, branch) = + let val url = remote_for context (libname, source) + in + (* make the lib dir rather than just the ext dir, since + the lib dir might be nested and git will happily check + out into an existing empty dir anyway *) + case FileBits.mkpath (FileBits.libpath context libname) of + OK () => git_command context "" + ["clone", "--origin", our_remote, + "--branch", branch_name branch, + url, libname] + | ERROR e => ERROR e + end + + fun add_our_remote context (libname, source) = + (* When we do the checkout ourselves (above), we add the + remote at the same time. But if the repo was cloned by + someone else, we'll need to do it after the fact. Git + doesn't seem to have a means to add a remote or change its + url if it already exists; seems we have to do this: *) + let val url = remote_for context (libname, source) + in + case git_command context libname + ["remote", "set-url", our_remote, url] of + OK () => OK () + | ERROR e => git_command context libname + ["remote", "add", "-f", our_remote, url] + end + + (* NB git rev-parse HEAD shows revision id of current checkout; + git rev-list -1 shows revision id of revision with that tag *) + + fun id_of context libname = + git_command_output context libname ["rev-parse", "HEAD"] + + fun is_at context (libname, id_or_tag) = + case id_of context libname of + ERROR e => OK false (* HEAD nonexistent, expected in empty repo *) + | OK id => + if String.isPrefix id_or_tag id orelse + String.isPrefix id id_or_tag + then OK true + else is_at_tag context (libname, id, id_or_tag) + + and is_at_tag context (libname, id, tag) = + (* For annotated tags (with message) show-ref returns the tag + object ref rather than that of the revision being tagged; + we need the subsequent rev-list to chase that up. In fact + the rev-list on its own is enough to get us the id direct + from the tag name, but it fails with an error if the tag + doesn't exist, whereas we want to handle that quietly in + case the tag simply hasn't been pulled yet *) + case git_command_output context libname + ["show-ref", "refs/tags/" ^ tag, "--"] of + OK "" => OK false (* Not a tag *) + | ERROR _ => OK false + | OK s => + let val tag_ref = hd (String.tokens (fn c => c = #" ") s) + in + case git_command_output context libname + ["rev-list", "-1", tag_ref] of + OK tagged => OK (id = tagged) + | ERROR _ => OK false + end + + fun branch_tip context (libname, branch) = + (* We don't have access to the source info or the network + here, as this is used by status (e.g. via is_on_branch) as + well as review. It's possible the remote branch won't exist, + e.g. if the repo was checked out by something other than + Repoint, and if that's the case, we can't add it here; we'll + just have to fail, since checking against local branches + instead could produce the wrong result. *) + git_command_output context libname + ["rev-list", "-1", + remote_branch_name branch, "--"] + + fun is_newest_locally context (libname, branch) = + case branch_tip context (libname, branch) of + ERROR e => OK false + | OK rev => is_at context (libname, rev) + + fun is_on_branch context (libname, branch) = + case branch_tip context (libname, branch) of + ERROR e => OK false + | OK rev => + case is_at context (libname, rev) of + ERROR e => ERROR e + | OK true => OK true + | OK false => + case git_command context libname + ["merge-base", "--is-ancestor", + "HEAD", remote_branch_name branch] of + ERROR e => OK false (* cmd returns non-zero for no *) + | _ => OK true + + fun fetch context (libname, source) = + case add_our_remote context (libname, source) of + ERROR e => ERROR e + | _ => git_command context libname ["fetch", our_remote] + + fun is_newest context (libname, source, branch) = + case add_our_remote context (libname, source) of + ERROR e => ERROR e + | OK () => + case is_newest_locally context (libname, branch) of + ERROR e => ERROR e + | OK false => OK false + | OK true => + case fetch context (libname, source) of + ERROR e => ERROR e + | _ => is_newest_locally context (libname, branch) + + fun is_modified_locally context libname = + case git_command_output context libname ["status", "--porcelain"] of + ERROR e => ERROR e + | OK "" => OK false + | OK _ => OK true + + (* This function updates to the latest revision on a branch rather + than to a specific id or tag. We can't just checkout the given + branch, as that will succeed even if the branch isn't up to + date. We could checkout the branch and then fetch and merge, + but it's perhaps cleaner not to maintain a local branch at all, + but instead checkout the remote branch as a detached head. *) + + fun update context (libname, source, branch) = + case fetch context (libname, source) of + ERROR e => ERROR e + | _ => + case git_command context libname ["checkout", "--detach", + remote_branch_name branch] of + ERROR e => ERROR e + | _ => OK () + + (* This function is dealing with a specific id or tag, so if we + can successfully check it out (detached) then that's all we + need to do, regardless of whether fetch succeeded or not. We do + attempt the fetch first, though, purely in order to avoid ugly + error messages in the common case where we're being asked to + update to a new pin (from the lock file) that hasn't been + fetched yet. *) + + fun update_to context (libname, _, "") = + ERROR "Non-empty id (tag or revision id) required for update_to" + | update_to context (libname, source, id) = + let val fetch_result = fetch context (libname, source) + in + case git_command context libname ["checkout", "--detach", id] of + OK _ => OK () + | ERROR e => + case fetch_result of + ERROR e' => ERROR e' (* this was the ur-error *) + | _ => ERROR e + end + + fun copy_url_for context libname = + OK (FileBits.file_url (FileBits.libpath context libname)) + +end + +(* SubXml - A parser for a subset of XML + https://bitbucket.org/cannam/sml-subxml + Copyright 2018 Chris Cannam. BSD licence. +*) + +signature SUBXML = sig + + datatype node = ELEMENT of { name : string, children : node list } + | ATTRIBUTE of { name : string, value : string } + | TEXT of string + | CDATA of string + | COMMENT of string + + datatype document = DOCUMENT of { name : string, children : node list } + + datatype 'a result = OK of 'a + | ERROR of string + + val parse : string -> document result + val serialise : document -> string + +end + +structure SubXml :> SUBXML = struct + + datatype node = ELEMENT of { name : string, children : node list } + | ATTRIBUTE of { name : string, value : string } + | TEXT of string + | CDATA of string + | COMMENT of string + + datatype document = DOCUMENT of { name : string, children : node list } + + datatype 'a result = OK of 'a + | ERROR of string + + structure T = struct + datatype token = ANGLE_L + | ANGLE_R + | ANGLE_SLASH_L + | SLASH_ANGLE_R + | EQUAL + | NAME of string + | TEXT of string + | CDATA of string + | COMMENT of string + + fun name t = + case t of ANGLE_L => "<" + | ANGLE_R => ">" + | ANGLE_SLASH_L => " "/>" + | EQUAL => "=" + | NAME s => "name \"" ^ s ^ "\"" + | TEXT s => "text" + | CDATA _ => "CDATA section" + | COMMENT _ => "comment" + end + + structure Lex :> sig + val lex : string -> T.token list result + end = struct + + fun error pos text = + ERROR (text ^ " at character position " ^ Int.toString (pos-1)) + fun tokenError pos token = + error pos ("Unexpected token '" ^ Char.toString token ^ "'") + + val nameEnd = explode " \t\n\r\"'!=?" + + fun quoted quote pos acc cc = + let fun quoted' pos text [] = + error pos "Document ends during quoted string" + | quoted' pos text (x::xs) = + if x = quote + then OK (rev text, xs, pos+1) + else quoted' (pos+1) (x::text) xs + in + case quoted' pos [] cc of + ERROR e => ERROR e + | OK (text, rest, newpos) => + inside newpos (T.TEXT (implode text) :: acc) rest + end + + and name first pos acc cc = + let fun name' pos text [] = + error pos "Document ends during name" + | name' pos text (x::xs) = + if List.find (fn c => c = x) nameEnd <> NONE + then OK (rev text, (x::xs), pos) + else name' (pos+1) (x::text) xs + in + case name' (pos-1) [] (first::cc) of + ERROR e => ERROR e + | OK ([], [], pos) => error pos "Document ends before name" + | OK ([], (x::xs), pos) => tokenError pos x + | OK (text, rest, pos) => + inside pos (T.NAME (implode text) :: acc) rest + end + + and comment pos acc cc = + let fun comment' pos text cc = + case cc of + #"-" :: #"-" :: #">" :: xs => OK (rev text, xs, pos+3) + | x :: xs => comment' (pos+1) (x::text) xs + | [] => error pos "Document ends during comment" + in + case comment' pos [] cc of + ERROR e => ERROR e + | OK (text, rest, pos) => + outside pos (T.COMMENT (implode text) :: acc) rest + end + + and instruction pos acc cc = + case cc of + #"?" :: #">" :: xs => outside (pos+2) acc xs + | #">" :: _ => tokenError pos #">" + | x :: xs => instruction (pos+1) acc xs + | [] => error pos "Document ends during processing instruction" + + and cdata pos acc cc = + let fun cdata' pos text cc = + case cc of + #"]" :: #"]" :: #">" :: xs => OK (rev text, xs, pos+3) + | x :: xs => cdata' (pos+1) (x::text) xs + | [] => error pos "Document ends during CDATA section" + in + case cdata' pos [] cc of + ERROR e => ERROR e + | OK (text, rest, pos) => + outside pos (T.CDATA (implode text) :: acc) rest + end + + and doctype pos acc cc = + case cc of + #">" :: xs => outside (pos+1) acc xs + | x :: xs => doctype (pos+1) acc xs + | [] => error pos "Document ends during DOCTYPE" + + and declaration pos acc cc = + case cc of + #"-" :: #"-" :: xs => + comment (pos+2) acc xs + | #"[" :: #"C" :: #"D" :: #"A" :: #"T" :: #"A" :: #"[" :: xs => + cdata (pos+7) acc xs + | #"D" :: #"O" :: #"C" :: #"T" :: #"Y" :: #"P" :: #"E" :: xs => + doctype (pos+7) acc xs + | [] => error pos "Document ends during declaration" + | _ => error pos "Unsupported declaration type" + + and left pos acc cc = + case cc of + #"/" :: xs => inside (pos+1) (T.ANGLE_SLASH_L :: acc) xs + | #"!" :: xs => declaration (pos+1) acc xs + | #"?" :: xs => instruction (pos+1) acc xs + | xs => inside pos (T.ANGLE_L :: acc) xs + + and slash pos acc cc = + case cc of + #">" :: xs => outside (pos+1) (T.SLASH_ANGLE_R :: acc) xs + | x :: _ => tokenError pos x + | [] => error pos "Document ends before element closed" + + and close pos acc xs = outside pos (T.ANGLE_R :: acc) xs + + and equal pos acc xs = inside pos (T.EQUAL :: acc) xs + + and outside pos acc [] = OK acc + | outside pos acc cc = + let fun textOf text = T.TEXT (implode (rev text)) + fun outside' pos [] acc [] = OK acc + | outside' pos text acc [] = OK (textOf text :: acc) + | outside' pos text acc (x::xs) = + case x of + #"<" => if text = [] + then left (pos+1) acc xs + else left (pos+1) (textOf text :: acc) xs + | x => outside' (pos+1) (x::text) acc xs + in + outside' pos [] acc cc + end + + and inside pos acc [] = error pos "Document ends within tag" + | inside pos acc (#"<"::_) = tokenError pos #"<" + | inside pos acc (x::xs) = + (case x of + #" " => inside | #"\t" => inside + | #"\n" => inside | #"\r" => inside + | #"\"" => quoted x | #"'" => quoted x + | #"/" => slash | #">" => close | #"=" => equal + | x => name x) (pos+1) acc xs + + fun lex str = + case outside 1 [] (explode str) of + ERROR e => ERROR e + | OK tokens => OK (rev tokens) + end + + structure Parse :> sig + val parse : string -> document result + end = struct + + fun show [] = "end of input" + | show (tok :: _) = T.name tok + + fun error toks text = ERROR (text ^ " before " ^ show toks) + + fun attribute elt name toks = + case toks of + T.EQUAL :: T.TEXT value :: xs => + namedElement { + name = #name elt, + children = ATTRIBUTE { name = name, value = value } :: + #children elt + } xs + | T.EQUAL :: xs => error xs "Expected attribute value" + | toks => error toks "Expected attribute assignment" + + and content elt toks = + case toks of + T.ANGLE_SLASH_L :: T.NAME n :: T.ANGLE_R :: xs => + if n = #name elt + then OK (elt, xs) + else ERROR ("Closing tag " ^ + "does not match opening <" ^ #name elt ^ ">") + | T.TEXT text :: xs => + content { + name = #name elt, + children = TEXT text :: #children elt + } xs + | T.CDATA text :: xs => + content { + name = #name elt, + children = CDATA text :: #children elt + } xs + | T.COMMENT text :: xs => + content { + name = #name elt, + children = COMMENT text :: #children elt + } xs + | T.ANGLE_L :: xs => + (case element xs of + ERROR e => ERROR e + | OK (child, xs) => + content { + name = #name elt, + children = ELEMENT child :: #children elt + } xs) + | tok :: xs => + error xs ("Unexpected token " ^ T.name tok) + | [] => + ERROR ("Document ends within element \"" ^ #name elt ^ "\"") + + and namedElement elt toks = + case toks of + T.SLASH_ANGLE_R :: xs => OK (elt, xs) + | T.NAME name :: xs => attribute elt name xs + | T.ANGLE_R :: xs => content elt xs + | x :: xs => error xs ("Unexpected token " ^ T.name x) + | [] => ERROR "Document ends within opening tag" + + and element toks = + case toks of + T.NAME name :: xs => + (case namedElement { name = name, children = [] } xs of + ERROR e => ERROR e + | OK ({ name, children }, xs) => + OK ({ name = name, children = rev children }, xs)) + | toks => error toks "Expected element name" + + and document [] = ERROR "Empty document" + | document (tok :: xs) = + case tok of + T.TEXT _ => document xs + | T.COMMENT _ => document xs + | T.ANGLE_L => + (case element xs of + ERROR e => ERROR e + | OK (elt, []) => OK (DOCUMENT elt) + | OK (elt, (T.TEXT _ :: xs)) => OK (DOCUMENT elt) + | OK (elt, xs) => error xs "Extra data after document") + | _ => error xs ("Unexpected token " ^ T.name tok) + + fun parse str = + case Lex.lex str of + ERROR e => ERROR e + | OK tokens => document tokens + end + + structure Serialise :> sig + val serialise : document -> string + end = struct + + fun attributes nodes = + String.concatWith + " " + (map node (List.filter + (fn ATTRIBUTE _ => true | _ => false) + nodes)) + + and nonAttributes nodes = + String.concat + (map node (List.filter + (fn ATTRIBUTE _ => false | _ => true) + nodes)) + + and node n = + case n of + TEXT string => + string + | CDATA string => + "" + | COMMENT string => + "" + | ATTRIBUTE { name, value } => + name ^ "=" ^ "\"" ^ value ^ "\"" (*!!!*) + | ELEMENT { name, children } => + "<" ^ name ^ + (case (attributes children) of + "" => "" + | s => " " ^ s) ^ + (case (nonAttributes children) of + "" => "/>" + | s => ">" ^ s ^ "") + + fun serialise (DOCUMENT { name, children }) = + "\n" ^ + node (ELEMENT { name = name, children = children }) + end + + val parse = Parse.parse + val serialise = Serialise.serialise + +end + + +structure SvnControl :> VCS_CONTROL = struct + + val svn_program = "svn" + + fun svn_command context libname args = + FileBits.command context libname (svn_program :: args) + + fun svn_command_output context libname args = + FileBits.command_output context libname (svn_program :: args) + + fun svn_command_lines context libname args = + case svn_command_output context libname args of + ERROR e => ERROR e + | OK s => OK (String.tokens (fn c => c = #"\n" orelse c = #"\r") s) + + fun split_line_pair line = + let fun strip_leading_ws str = case explode str of + #" "::rest => implode rest + | _ => str + in + case String.tokens (fn c => c = #":") line of + [] => ("", "") + | first::rest => + (first, strip_leading_ws (String.concatWith ":" rest)) + end + + fun is_working context = + case svn_command_output context "" ["--version"] of + OK "" => OK false + | OK _ => OK true + | ERROR e => ERROR e + + structure X = SubXml + + fun svn_info context libname route = + (* SVN 1.9 has info --show-item which is just what we need, + but at this point we still have 1.8 on the CI boxes so we + might as well aim to support it. For that we really have to + use the XML output format, since the default info output is + localised. This is the only thing our mini-XML parser is + used for though, so it would be good to trim it at some + point *) + let fun find elt [] = OK elt + | find { children, ... } (first :: rest) = + case List.find (fn (X.ELEMENT { name, ... }) => name = first + | _ => false) + children of + NONE => ERROR ("No element \"" ^ first ^ "\" in SVN XML") + | SOME (X.ELEMENT e) => find e rest + | SOME _ => ERROR "Internal error" + in + case svn_command_output context libname ["info", "--xml"] of + ERROR e => ERROR e + | OK xml => + case X.parse xml of + X.ERROR e => ERROR e + | X.OK (X.DOCUMENT doc) => find doc route + end + + fun exists context libname = + OK (OS.FileSys.isDir (FileBits.subpath context libname ".svn")) + handle _ => OK false + + fun remote_for context (libname, source) = + Provider.remote_url context SVN source libname + + (* Remote the checkout came from, not necessarily the one we want *) + fun actual_remote_for context libname = + case svn_info context libname ["entry", "url"] of + ERROR e => ERROR e + | OK { children, ... } => + case List.find (fn (X.TEXT _) => true | _ => false) children of + NONE => ERROR "No content for URL in SVN info XML" + | SOME (X.TEXT url) => OK url + | SOME _ => ERROR "Internal error" + + fun id_of context libname = + case svn_info context libname ["entry"] of + ERROR e => ERROR e + | OK { children, ... } => + case List.find + (fn (X.ATTRIBUTE { name = "revision", ... }) => true + | _ => false) + children of + NONE => ERROR "No revision for entry in SVN info XML" + | SOME (X.ATTRIBUTE { value, ... }) => OK value + | SOME _ => ERROR "Internal error" + + fun is_at context (libname, id_or_tag) = + case id_of context libname of + ERROR e => ERROR e + | OK id => OK (id = id_or_tag) + + fun is_on_branch context (libname, b) = + OK (b = DEFAULT_BRANCH) + + fun check_remote context (libname, source) = + case (remote_for context (libname, source), + actual_remote_for context libname) of + (_, ERROR e) => ERROR e + | (url, OK actual) => + if actual = url + then OK () + else svn_command context libname ["relocate", url] + + fun is_newest context (libname, source, branch) = + case check_remote context (libname, source) of + ERROR e => ERROR e + | OK () => + case svn_command_lines context libname + ["status", "--show-updates"] of + ERROR e => ERROR e + | OK lines => + case rev lines of + [] => ERROR "No result returned for server status" + | last_line::_ => + case rev (String.tokens (fn c => c = #" ") last_line) of + [] => ERROR "No revision field found in server status" + | server_id::_ => is_at context (libname, server_id) + + fun is_newest_locally context (libname, branch) = + OK true (* no local history *) + + fun is_modified_locally context libname = + case svn_command_output context libname ["status"] of + ERROR e => ERROR e + | OK "" => OK false + | OK _ => OK true + + fun checkout context (libname, source, branch) = + let val url = remote_for context (libname, source) + val path = FileBits.libpath context libname + in + if FileBits.nonempty_dir_exists path + then (* Surprisingly, SVN itself has no problem with + this. But for consistency with other VCSes we + don't allow it *) + ERROR ("Refusing checkout to nonempty dir \"" ^ path ^ "\"") + else + (* make the lib dir rather than just the ext dir, since + the lib dir might be nested and svn will happily check + out into an existing empty dir anyway *) + case FileBits.mkpath (FileBits.libpath context libname) of + ERROR e => ERROR e + | _ => svn_command context "" ["checkout", url, libname] + end + + fun update context (libname, source, branch) = + case check_remote context (libname, source) of + ERROR e => ERROR e + | OK () => + case svn_command context libname + ["update", "--accept", "postpone"] of + ERROR e => ERROR e + | _ => OK () + + fun update_to context (libname, _, "") = + ERROR "Non-empty id (tag or revision id) required for update_to" + | update_to context (libname, source, id) = + case check_remote context (libname, source) of + ERROR e => ERROR e + | OK () => + case svn_command context libname + ["update", "-r", id, "--accept", "postpone"] of + ERROR e => ERROR e + | OK _ => OK () + + fun copy_url_for context libname = + actual_remote_for context libname + +end + +structure AnyLibControl :> LIB_CONTROL = struct + + structure H = LibControlFn(HgControl) + structure G = LibControlFn(GitControl) + structure S = LibControlFn(SvnControl) + + fun review context (spec as { vcs, ... } : libspec) = + (fn HG => H.review | GIT => G.review | SVN => S.review) vcs context spec + + fun status context (spec as { vcs, ... } : libspec) = + (fn HG => H.status | GIT => G.status | SVN => S.status) vcs context spec + + fun update context (spec as { vcs, ... } : libspec) = + (fn HG => H.update | GIT => G.update | SVN => S.update) vcs context spec + + fun id_of context (spec as { vcs, ... } : libspec) = + (fn HG => H.id_of | GIT => G.id_of | SVN => S.id_of) vcs context spec + + fun is_working context vcs = + (fn HG => H.is_working | GIT => G.is_working | SVN => S.is_working) + vcs context vcs + +end + + +type exclusions = string list + +structure Archive :> sig + + val archive : string * exclusions -> project -> OS.Process.status + +end = struct + + (* The idea of "archive" is to replace hg/git archive, which won't + include files, like the Repoint-introduced external libraries, + that are not under version control with the main repo. + + The process goes like this: + + - Make sure we have a target filename from the user, and take + its basename as our archive directory name + + - Make an "archive root" subdir of the project repo, named + typically .repoint-archive + + - Identify the VCS used for the project repo. Note that any + explicit references to VCS type in this structure are to + the VCS used for the project (something Repoint doesn't + otherwise care about), not for an individual library + + - Synthesise a Repoint project with the archive root as its + root path, "." as its extdir, with one library whose + name is the user-supplied basename and whose explicit + source URL is the original project root; update that + project -- thus cloning the original project to a subdir + of the archive root + + - Synthesise a Repoint project identical to the original one for + this project, but with the newly-cloned copy as its root + path; update that project -- thus checking out clean copies + of the external library dirs + + - Call out to an archive program to archive up the new copy, + running e.g. + tar cvzf project-release.tar.gz \ + --exclude=.hg --exclude=.git project-release + in the archive root dir + + - (We also omit the repoint-project.json file and any trace of + Repoint. It can't properly be run in a directory where the + external project folders already exist but their repo history + does not. End users shouldn't get to see Repoint) + + - Clean up by deleting the new copy + *) + + fun project_vcs_id_and_url dir = + let val context = { + rootpath = dir, + extdir = ".", + providers = [], + accounts = [] + } + val vcs_maybe = + case [HgControl.exists context ".", + GitControl.exists context ".", + SvnControl.exists context "."] of + [OK true, OK false, OK false] => OK HG + | [OK false, OK true, OK false] => OK GIT + | [OK false, OK false, OK true] => OK SVN + | _ => ERROR ("Unable to identify VCS for directory " ^ dir) + in + case vcs_maybe of + ERROR e => ERROR e + | OK vcs => + case (fn HG => HgControl.id_of + | GIT => GitControl.id_of + | SVN => SvnControl.id_of) + vcs context "." of + ERROR e => ERROR ("Unable to find id of project repo: " ^ e) + | OK id => + case (fn HG => HgControl.copy_url_for + | GIT => GitControl.copy_url_for + | SVN => SvnControl.copy_url_for) + vcs context "." of + ERROR e => ERROR ("Unable to find URL of project repo: " + ^ e) + | OK url => OK (vcs, id, url) + end + + fun make_archive_root (context : context) = + let val path = OS.Path.joinDirFile { + dir = #rootpath context, + file = RepointFilenames.archive_dir + } + in + case FileBits.mkpath path of + ERROR e => raise Fail ("Failed to create archive directory \"" + ^ path ^ "\": " ^ e) + | OK () => path + end + + fun archive_path archive_dir target_name = + OS.Path.joinDirFile { + dir = archive_dir, + file = target_name + } + + fun check_nonexistent path = + case SOME (OS.FileSys.fileSize path) handle OS.SysErr _ => NONE of + NONE => () + | _ => raise Fail ("Path " ^ path ^ " exists, not overwriting") + + fun make_archive_copy target_name (vcs, project_id, source_url) + ({ context, ... } : project) = + let val archive_root = make_archive_root context + val synthetic_context = { + rootpath = archive_root, + extdir = ".", + providers = [], + accounts = [] + } + val synthetic_library = { + libname = target_name, + vcs = vcs, + source = URL_SOURCE source_url, + branch = DEFAULT_BRANCH, (* overridden by pinned id below *) + project_pin = PINNED project_id, + lock_pin = PINNED project_id + } + val path = archive_path archive_root target_name + val _ = print ("Cloning original project to " ^ path + ^ " at revision " ^ project_id ^ "...\n"); + val _ = check_nonexistent path + in + case AnyLibControl.update synthetic_context synthetic_library of + ERROR e => ERROR ("Failed to clone original project to " + ^ path ^ ": " ^ e) + | OK _ => OK archive_root + end + + fun update_archive archive_root target_name + (project as { context, ... } : project) = + let val synthetic_context = { + rootpath = archive_path archive_root target_name, + extdir = #extdir context, + providers = #providers context, + accounts = #accounts context + } + in + foldl (fn (lib, acc) => + case acc of + ERROR e => ERROR e + | OK () => AnyLibControl.update synthetic_context lib) + (OK ()) + (#libs project) + end + + datatype packer = TAR + | TAR_GZ + | TAR_BZ2 + | TAR_XZ + (* could add other packers, e.g. zip, if we knew how to + handle the file omissions etc properly in pack_archive *) + + fun packer_and_basename path = + let val extensions = [ (".tar", TAR), + (".tar.gz", TAR_GZ), + (".tar.bz2", TAR_BZ2), + (".tar.xz", TAR_XZ)] + val filename = OS.Path.file path + in + foldl (fn ((ext, packer), acc) => + if String.isSuffix ext filename + then SOME (packer, + String.substring (filename, 0, + String.size filename - + String.size ext)) + else acc) + NONE + extensions + end + + fun pack_archive archive_root target_name target_path packer exclusions = + case FileBits.command { + rootpath = archive_root, + extdir = ".", + providers = [], + accounts = [] + } "" ([ + "tar", + case packer of + TAR => "cf" + | TAR_GZ => "czf" + | TAR_BZ2 => "cjf" + | TAR_XZ => "cJf", + target_path, + "--exclude=.hg", + "--exclude=.git", + "--exclude=.svn", + "--exclude=repoint", + "--exclude=repoint.sml", + "--exclude=repoint.ps1", + "--exclude=repoint.bat", + "--exclude=repoint-project.json", + "--exclude=repoint-lock.json" + ] @ (map (fn e => "--exclude=" ^ e) exclusions) @ + [ target_name ]) + of + ERROR e => ERROR e + | OK _ => FileBits.rmpath (archive_path archive_root target_name) + + fun archive (target_path, exclusions) (project : project) = + let val _ = check_nonexistent target_path + val (packer, name) = + case packer_and_basename target_path of + NONE => raise Fail ("Unsupported archive file extension in " + ^ target_path) + | SOME pn => pn + val details = + case project_vcs_id_and_url (#rootpath (#context project)) of + ERROR e => raise Fail e + | OK details => details + val archive_root = + case make_archive_copy name details project of + ERROR e => raise Fail e + | OK archive_root => archive_root + val outcome = + case update_archive archive_root name project of + ERROR e => ERROR e + | OK _ => + case pack_archive archive_root name + target_path packer exclusions of + ERROR e => ERROR e + | OK _ => OK () + in + case outcome of + ERROR e => raise Fail e + | OK () => OS.Process.success + end + +end + +val libobjname = "libraries" + +fun load_libspec spec_json lock_json libname : libspec = + let open JsonBits + val libobj = lookup_mandatory spec_json [libobjname, libname] + val vcs = lookup_mandatory_string libobj ["vcs"] + val retrieve = lookup_optional_string libobj + val service = retrieve ["service"] + val owner = retrieve ["owner"] + val repo = retrieve ["repository"] + val url = retrieve ["url"] + val branch = retrieve ["branch"] + val project_pin = case retrieve ["pin"] of + NONE => UNPINNED + | SOME p => PINNED p + val lock_pin = case lookup_optional lock_json [libobjname, libname] of + NONE => UNPINNED + | SOME ll => case lookup_optional_string ll ["pin"] of + SOME p => PINNED p + | NONE => UNPINNED + in + { + libname = libname, + vcs = case vcs of + "hg" => HG + | "git" => GIT + | "svn" => SVN + | other => raise Fail ("Unknown version-control system \"" ^ + other ^ "\""), + source = case (url, service, owner, repo) of + (SOME u, NONE, _, _) => URL_SOURCE u + | (NONE, SOME ss, owner, repo) => + SERVICE_SOURCE { service = ss, owner = owner, repo = repo } + | _ => raise Fail ("Must have exactly one of service " ^ + "or url string"), + project_pin = project_pin, + lock_pin = lock_pin, + branch = case branch of + NONE => DEFAULT_BRANCH + | SOME b => + case vcs of + "svn" => raise Fail ("Branches not supported for " ^ + "svn repositories; change " ^ + "URL instead") + | _ => BRANCH b + } + end + +fun load_userconfig () : userconfig = + let val home = FileBits.homedir () + val conf_json = + JsonBits.load_json_from + (OS.Path.joinDirFile { + dir = home, + file = RepointFilenames.user_config_file }) + handle IO.Io _ => Json.OBJECT [] + in + { + accounts = case JsonBits.lookup_optional conf_json ["accounts"] of + NONE => [] + | SOME (Json.OBJECT aa) => + map (fn (k, (Json.STRING v)) => + { service = k, login = v } + | _ => raise Fail + "String expected for account name") + aa + | _ => raise Fail "Array expected for accounts", + providers = Provider.load_providers conf_json + } + end + +datatype pintype = + NO_LOCKFILE | + USE_LOCKFILE + +fun load_project (userconfig : userconfig) rootpath pintype : project = + let val spec_file = FileBits.project_spec_path rootpath + val lock_file = FileBits.project_lock_path rootpath + val _ = if OS.FileSys.access (spec_file, [OS.FileSys.A_READ]) + handle OS.SysErr _ => false + then () + else raise Fail ("Failed to open project spec file " ^ + (RepointFilenames.project_file) ^ " in " ^ + rootpath ^ + ".\nPlease ensure the spec file is in the " ^ + "project root and run this from there.") + val spec_json = JsonBits.load_json_from spec_file + val lock_json = if pintype = USE_LOCKFILE + then JsonBits.load_json_from lock_file + handle IO.Io _ => Json.OBJECT [] + else Json.OBJECT [] + val extdir = JsonBits.lookup_mandatory_string spec_json + ["config", "extdir"] + val spec_libs = JsonBits.lookup_optional spec_json [libobjname] + val lock_libs = JsonBits.lookup_optional lock_json [libobjname] + val providers = Provider.load_more_providers + (#providers userconfig) spec_json + val libnames = case spec_libs of + NONE => [] + | SOME (Json.OBJECT ll) => map (fn (k, v) => k) ll + | _ => raise Fail "Object expected for libs" + in + { + context = { + rootpath = rootpath, + extdir = extdir, + providers = providers, + accounts = #accounts userconfig + }, + libs = map (load_libspec spec_json lock_json) libnames + } + end + +fun save_lock_file rootpath locks = + let val lock_file = FileBits.project_lock_path rootpath + open Json + val lock_json = + OBJECT [ + (libobjname, + OBJECT (map (fn { libname, id_or_tag } => + (libname, + OBJECT [ ("pin", STRING id_or_tag) ])) + locks)) + ] + in + JsonBits.save_json_to lock_file lock_json + end + +fun checkpoint_completion_file rootpath = + let val completion_file = FileBits.project_completion_path rootpath + val stream = TextIO.openOut completion_file + in + TextIO.closeOut stream + end + +fun pad_to n str = + if n <= String.size str then str + else pad_to n (str ^ " ") + +fun hline_to 0 = "" + | hline_to n = "-" ^ hline_to (n-1) + +val libname_width = 28 +val libstate_width = 11 +val localstate_width = 17 +val notes_width = 5 +val divider = " | " +val clear_line = "\r" ^ pad_to 80 ""; + +fun print_status_header () = + print (clear_line ^ "\n " ^ + pad_to libname_width "Library" ^ divider ^ + pad_to libstate_width "State" ^ divider ^ + pad_to localstate_width "Local" ^ divider ^ + "Notes" ^ "\n " ^ + hline_to libname_width ^ "-+-" ^ + hline_to libstate_width ^ "-+-" ^ + hline_to localstate_width ^ "-+-" ^ + hline_to notes_width ^ "\n") + +fun print_outcome_header () = + print (clear_line ^ "\n " ^ + pad_to libname_width "Library" ^ divider ^ + pad_to libstate_width "Outcome" ^ divider ^ + "Notes" ^ "\n " ^ + hline_to libname_width ^ "-+-" ^ + hline_to libstate_width ^ "-+-" ^ + hline_to notes_width ^ "\n") + +fun print_status with_network (lib : libspec, status) = + let val libstate_str = + case status of + OK (ABSENT, _) => "Absent" + | OK (CORRECT, _) => if with_network then "Correct" else "Present" + | OK (SUPERSEDED, _) => "Superseded" + | OK (WRONG, _) => "Wrong" + | ERROR _ => "Error" + val localstate_str = + case status of + OK (_, MODIFIED) => "Modified" + | OK (_, LOCK_MISMATCHED) => "Differs from Lock" + | OK (_, CLEAN) => "Clean" + | ERROR _ => "" + val error_str = + case status of + ERROR e => e + | _ => "" + in + print (" " ^ + pad_to libname_width (#libname lib) ^ divider ^ + pad_to libstate_width libstate_str ^ divider ^ + pad_to localstate_width localstate_str ^ divider ^ + error_str ^ "\n") + end + +fun print_update_outcome (lib : libspec, outcome) = + let val outcome_str = + case outcome of + OK id => "Ok" + | ERROR e => "Failed" + val error_str = + case outcome of + ERROR e => e + | _ => "" + in + print (" " ^ + pad_to libname_width (#libname lib) ^ divider ^ + pad_to libstate_width outcome_str ^ divider ^ + error_str ^ "\n") + end + +fun vcs_name HG = ("Mercurial", "hg") + | vcs_name GIT = ("Git", "git") + | vcs_name SVN = ("Subversion", "svn") + +fun print_problem_summary context lines = + let val failed_vcs = + foldl (fn (({ vcs, ... } : libspec, ERROR _), acc) => vcs::acc + | (_, acc) => acc) [] lines + fun report_nonworking vcs error = + print ((if error = "" then "" else error ^ "\n\n") ^ + "Error: The project uses the " ^ (#1 (vcs_name vcs)) ^ + " version control system, but its\n" ^ + "executable program (" ^ (#2 (vcs_name vcs)) ^ + ") does not appear to be installed in the program path\n\n") + fun check_working [] checked = () + | check_working (vcs::rest) checked = + if List.exists (fn v => vcs = v) checked + then check_working rest checked + else + case AnyLibControl.is_working context vcs of + OK true => check_working rest checked + | OK false => (report_nonworking vcs ""; + check_working rest (vcs::checked)) + | ERROR e => (report_nonworking vcs e; + check_working rest (vcs::checked)) + in + print "\nError: Some operations failed\n\n"; + check_working failed_vcs [] + end + +fun act_and_print action print_header print_line context (libs : libspec list) = + let val lines = map (fn lib => (lib, action lib)) libs + val imperfect = List.exists (fn (_, ERROR _) => true | _ => false) lines + val _ = print_header () + in + app print_line lines; + if imperfect then print_problem_summary context lines else (); + lines + end + +fun return_code_for outcomes = + foldl (fn ((_, result), acc) => + case result of + ERROR _ => OS.Process.failure + | _ => acc) + OS.Process.success + outcomes + +fun status_of_project ({ context, libs } : project) = + return_code_for (act_and_print (AnyLibControl.status context) + print_status_header (print_status false) + context libs) + +fun review_project ({ context, libs } : project) = + return_code_for (act_and_print (AnyLibControl.review context) + print_status_header (print_status true) + context libs) + +fun lock_project ({ context, libs } : project) = + let val _ = if FileBits.verbose () + then print ("Scanning IDs for lock file...\n") + else () + val outcomes = map (fn lib => (lib, AnyLibControl.id_of context lib)) + libs + val locks = + List.concat + (map (fn (lib : libspec, result) => + case result of + ERROR _ => [] + | OK id => [{ libname = #libname lib, + id_or_tag = id }]) + outcomes) + val return_code = return_code_for outcomes + val _ = print clear_line + in + if OS.Process.isSuccess return_code + then save_lock_file (#rootpath context) locks + else (); + return_code + end + +fun update_project (project as { context, libs }) = + let val outcomes = act_and_print + (AnyLibControl.update context) + print_outcome_header print_update_outcome + context libs + val _ = if List.exists (fn (_, OK _) => true | _ => false) outcomes + then lock_project project + else OS.Process.success + val return_code = return_code_for outcomes + in + if OS.Process.isSuccess return_code + then checkpoint_completion_file (#rootpath context) + else (); + return_code + end + +fun load_local_project pintype = + let val userconfig = load_userconfig () + val rootpath = OS.FileSys.getDir () + in + load_project userconfig rootpath pintype + end + +fun with_local_project pintype f = + let open OS.Process + val return_code = + f (load_local_project pintype) + handle Fail msg => + failure before print ("Error: " ^ msg) + | JsonBits.Config msg => + failure before print ("Error in configuration: " ^ msg) + | e => + failure before print ("Error: " ^ exnMessage e) + val _ = print "\n"; + in + return_code + end + +fun review () = with_local_project USE_LOCKFILE review_project +fun status () = with_local_project USE_LOCKFILE status_of_project +fun update () = with_local_project NO_LOCKFILE update_project +fun lock () = with_local_project NO_LOCKFILE lock_project +fun install () = with_local_project USE_LOCKFILE update_project + +fun version () = + (print ("v" ^ repoint_version ^ "\n"); + OS.Process.success) + +fun usage () = + (print "\nRepoint "; + version (); + print ("\n A simple manager for third-party source code dependencies.\n" + ^ " http://all-day-breakfast.com/repoint/\n\n" + ^ "Usage:\n\n" + ^ " repoint []\n\n" + ^ "where is one of:\n\n" + ^ " status print quick report on local status only, without using network\n" + ^ " review check configured libraries against their providers, and report\n" + ^ " install update configured libraries according to project specs and lock file\n" + ^ " update update configured libraries and lock file according to project specs\n" + ^ " lock rewrite lock file to match local library status\n" + ^ " archive pack up project and all libraries into an archive file:\n" + ^ " invoke as 'repoint archive targetfile.tar.gz --exclude unwanted.txt'\n" + ^ " version print the Repoint version number and exit\n\n" + ^ "and may include:\n\n" + ^ " --directory \n" + ^ " change to directory before doing anything; in particular,\n" + ^ " expect to find project spec file in that directory\n\n"); + OS.Process.failure) + +fun archive target args = + case args of + [] => + with_local_project USE_LOCKFILE (Archive.archive (target, [])) + | "--exclude"::xs => + with_local_project USE_LOCKFILE (Archive.archive (target, xs)) + | _ => usage () + +fun handleSystemArgs args = + let fun handleSystemArgs' leftover args = + case args of + "--directory"::dir::rest => + (OS.FileSys.chDir dir; + handleSystemArgs' leftover rest) + | arg::rest => + handleSystemArgs' (leftover @ [arg]) rest + | [] => leftover + in + OK (handleSystemArgs' [] args) + handle e => ERROR (exnMessage e) + end + +fun repoint args = + case handleSystemArgs args of + ERROR e => (print ("Error: " ^ e ^ "\n"); + OS.Process.exit OS.Process.failure) + | OK args => + let val return_code = + case args of + ["review"] => review () + | ["status"] => status () + | ["install"] => install () + | ["update"] => update () + | ["lock"] => lock () + | ["version"] => version () + | "archive"::target::args => archive target args + | arg::_ => (print ("Error: unknown argument \"" ^ arg ^ "\"\n"); + usage ()) + | _ => usage () + in + OS.Process.exit return_code + end + +fun main () = + repoint (CommandLine.arguments ()) diff -r 246bdf94ef7b -r 55d9bbf1fe45 server.pro --- a/server.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/server.pro Mon Sep 17 14:05:41 2018 +0100 @@ -1,8 +1,7 @@ TEMPLATE = app -CONFIG += stl c++11 exceptions console warn_on - +CONFIG += stl exceptions console warn_on CONFIG -= qt exists(config.pri) { @@ -31,7 +30,7 @@ OBJECTS_DIR = o MOC_DIR = o -INCLUDEPATH += piper-cpp vamp-plugin-sdk +INCLUDEPATH += piper-cpp piper-cpp/ext vamp-plugin-sdk include(vamp-plugin-sdk-files.pri) @@ -44,5 +43,5 @@ SOURCES += \ piper-cpp/vamp-capnp/piper-capnp.cpp \ - piper-cpp/json11/json11.cpp \ + piper-cpp/ext/json11/json11.cpp \ piper-cpp/vamp-server/simple-server.cpp diff -r 246bdf94ef7b -r 55d9bbf1fe45 sonic-visualiser.desktop --- a/sonic-visualiser.desktop Mon Sep 17 13:53:25 2018 +0100 +++ b/sonic-visualiser.desktop Mon Sep 17 14:05:41 2018 +0100 @@ -1,9 +1,11 @@ [Desktop Entry] Name=Sonic Visualiser +Comment=Viewing and analysing the contents of music audio files +Comment[fr]=Affichage et analyse des contenus des fichiers audio de musique Exec=sonic-visualiser %U Keywords=audio; sound; visualiser; sonic; Terminal=false Type=Application -Icon=sv-icon +Icon=sonic-visualiser Categories=Audio;AudioVideo; MimeType=application/x-sonicvisualiser;application/x-sonicvisualiser-layer;application/x-ogg;audio/mp3;audio/mpeg;audio/mpegurl;audio/x-flac;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-wav;audio/wav;application/ogg;audio/x-vorbis+ogg; diff -r 246bdf94ef7b -r 55d9bbf1fe45 sonic-visualiser.pro --- a/sonic-visualiser.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/sonic-visualiser.pro Mon Sep 17 14:05:41 2018 +0100 @@ -1,15 +1,18 @@ TEMPLATE = subdirs -!win* { - # We should build and run the tests on any platform, - # but doing it automatically doesn't work so well from - # within an IDE on Windows, so remove that from here - SUBDIRS += \ - sub_test_svcore_base \ +SUBDIRS += \ + sub_base + +# We build the tests on every platform, though at the time of +# writing they are only automatically run on non-Windows platforms +# (because of the difficulty of getting them running nicely in the +# IDE without causing great confusion if a test fails). +SUBDIRS += \ + sub_test_svcore_base \ + sub_test_svcore_system \ sub_test_svcore_data_fileio \ sub_test_svcore_data_model -} SUBDIRS += \ checker \ @@ -17,7 +20,10 @@ sub_convert \ sub_sv +sub_base.file = base.pro + sub_test_svcore_base.file = test-svcore-base.pro +sub_test_svcore_system.file = test-svcore-system.pro sub_test_svcore_data_fileio.file = test-svcore-data-fileio.pro sub_test_svcore_data_model.file = test-svcore-data-model.pro diff -r 246bdf94ef7b -r 55d9bbf1fe45 sonic-visualiser.qrc --- a/sonic-visualiser.qrc Mon Sep 17 13:53:25 2018 +0100 +++ b/sonic-visualiser.qrc Mon Sep 17 14:05:41 2018 +0100 @@ -3,134 +3,84 @@ icons/scalable/align.svg icons/scalable/colour3d.svg icons/scalable/cross.svg + icons/scalable/datadelete.svg icons/scalable/dataedit.svg + icons/scalable/down.svg icons/scalable/draw.svg - icons/scalable/erase.svg icons/scalable/editcopy.svg icons/scalable/editcut.svg icons/scalable/editdelete.svg icons/scalable/editpaste.svg + icons/scalable/erase.svg icons/scalable/exit.svg + icons/scalable/faders.svg icons/scalable/filenew.svg icons/scalable/fileopen.svg + icons/scalable/filesave.svg icons/scalable/filesaveas.svg - icons/scalable/filesave.svg icons/scalable/filesavesv.svg + icons/scalable/ffwd.svg icons/scalable/ffwd-end.svg - icons/scalable/ffwd.svg + icons/scalable/help.svg + icons/scalable/info.svg + icons/scalable/instants.svg + icons/scalable/measure.svg + icons/scalable/move.svg icons/scalable/navigate.svg - icons/scalable/move.svg + icons/scalable/normalise.svg + icons/scalable/normalise-columns.svg + icons/scalable/notes.svg + icons/scalable/pane.svg icons/scalable/pause.svg icons/scalable/playloop.svg icons/scalable/playpause.svg icons/scalable/playselection.svg - icons/scalable/solo.svg + icons/scalable/playfollow.svg icons/scalable/play.svg + icons/scalable/plus.svg icons/scalable/record.svg + icons/scalable/redo.svg + icons/scalable/regions.svg icons/scalable/rewind-start.svg icons/scalable/rewind.svg - icons/scalable/undo.svg - icons/scalable/redo.svg icons/scalable/select.svg - icons/scalable/measure.svg + icons/scalable/show-peaks.svg + icons/scalable/solo.svg icons/scalable/speaker.svg - icons/scalable/instants.svg - icons/scalable/notes.svg - icons/scalable/values.svg - icons/scalable/regions.svg icons/scalable/spectrogram.svg icons/scalable/spectrum.svg icons/scalable/text.svg icons/scalable/timeruler.svg + icons/scalable/undo.svg + icons/scalable/up.svg + icons/scalable/values.svg + icons/scalable/waveform.svg icons/scalable/zoom.svg icons/scalable/zoom-in.svg icons/scalable/zoom-out.svg icons/scalable/zoom-fit.svg + icons/scalable/zoom-reset.svg icons/scalable/sv-icon-light.svg icons/scalable/sv-icon.svg icons/scalable/sv-splash.svg icons/scalable/sv-splash.png icons/scalable/sv-splash@2x.png - icons/scalable/waveform.svg - icons/waveform.png - icons/spectrum.png - icons/spectrogram.png - icons/pane.png - icons/instants.png - icons/notes.png + icons/image.png - icons/values.png - icons/regions.png - icons/colour3d.png - icons/playpause.png - icons/playpause-on.png - icons/ffwd.png - icons/ffwd-end.png - icons/rewind.png - icons/rewind-start.png - icons/playselection.png - icons/playselection-on.png - icons/playloop.png - icons/playloop-on.png - icons/playfollow.png - icons/playfollow-on.png - icons/solo.png - icons/solo-on.png - icons/align.png - icons/align-on.png - icons/fader_background.png - icons/fader_knob.png - icons/fader_knob_red.png - icons/fader_leds.png - icons/faders.png - icons/select.png - icons/text.png - icons/draw.png icons/draw-curve.png - icons/erase.png icons/measure.png icons/measure1cursor.xbm icons/measure1mask.xbm icons/measure2cursor.xbm icons/measure2mask.xbm - icons/move.png - icons/navigate.png - icons/zoom-reset.png - icons/undo.png - icons/redo.png icons/new.png - icons/exit.png - icons/speaker.png icons/annotation.png - icons/info.png - icons/fileopen.png - icons/fileopensession.png - icons/fileopenaudio.png - icons/fileopen-22.png - icons/fileclose.png - icons/filenew.png - icons/filenew-22.png - icons/filesave.png - icons/filesave-22.png - icons/filesaveas.png - icons/filesaveas-22.png - icons/editdelete.png - icons/editcut.png - icons/editcopy.png - icons/editpaste.png - icons/datadelete.png - icons/dataedit.png icons/datainsert.png icons/mono.png icons/stereo.png icons/sharpen.png - icons/help.png icons/emptypage.png - icons/cross.png - icons/normalise.png - icons/normalise-columns.png icons/invert-vertical.png - icons/show-peaks.png icons/opaque.png icons/smooth.png icons/lines.png @@ -170,5 +120,10 @@ i18n/sonic-visualiser_en_US.qm i18n/sonic-visualiser_cs_CZ.qm i18n/tips_en.xml + README.md + README.OSC + CHANGELOG + COPYING + CITATION diff -r 246bdf94ef7b -r 55d9bbf1fe45 sv.pro --- a/sv.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/sv.pro Mon Sep 17 14:05:41 2018 +0100 @@ -17,6 +17,28 @@ linux*:TARGET = sonic-visualiser solaris*:TARGET = sonic-visualiser +!win32 { + PRE_TARGETDEPS += $$PWD/libbase.a + QMAKE_POST_LINK += cp checker/vamp-plugin-load-checker . +} + +linux* { + + sv_bins.path = $$PREFIX_PATH/bin/ + sv_bins.files = checker/vamp-plugin-load-checker piper-vamp-simple-server sonic-visualiser + sv_bins.CONFIG = no_check_exist + + sv_desktop.path = $$PREFIX_PATH/share/applications/ + sv_desktop.files = sonic-visualiser.desktop + sv_desktop.CONFIG = no_check_exist + + sv_icon.path = $$PREFIX_PATH/share/icons/hicolor/scalable/apps/ + sv_icon.files = icons/sonic-visualiser.svg + sv_icon.CONFIG = no_check_exist + + INSTALLS += sv_bins sv_desktop sv_icon +} + TRANSLATIONS += \ i18n/sonic-visualiser_ru.ts \ i18n/sonic-visualiser_en_GB.ts \ diff -r 246bdf94ef7b -r 55d9bbf1fe45 test-svcore-base.pro --- a/test-svcore-base.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/test-svcore-base.pro Mon Sep 17 14:05:41 2018 +0100 @@ -28,4 +28,6 @@ for (file, TEST_SOURCES) { SOURCES += $$sprintf("svcore/base/test/%1", $$file) } for (file, TEST_HEADERS) { HEADERS += $$sprintf("svcore/base/test/%1", $$file) } -QMAKE_POST_LINK = ./$${TARGET}$${TARGET_EXT} +!win32* { + QMAKE_POST_LINK = ./$${TARGET} +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 test-svcore-data-fileio.pro --- a/test-svcore-data-fileio.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/test-svcore-data-fileio.pro Mon Sep 17 14:05:41 2018 +0100 @@ -28,4 +28,6 @@ for (file, TEST_SOURCES) { SOURCES += $$sprintf("svcore/data/fileio/test/%1", $$file) } for (file, TEST_HEADERS) { HEADERS += $$sprintf("svcore/data/fileio/test/%1", $$file) } -QMAKE_POST_LINK = ./$${TARGET}$${TARGET_EXT} +!win32* { + QMAKE_POST_LINK = ./$${TARGET} +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 test-svcore-data-model.pro --- a/test-svcore-data-model.pro Mon Sep 17 13:53:25 2018 +0100 +++ b/test-svcore-data-model.pro Mon Sep 17 14:05:41 2018 +0100 @@ -28,4 +28,6 @@ for (file, TEST_SOURCES) { SOURCES += $$sprintf("svcore/data/model/test/%1", $$file) } for (file, TEST_HEADERS) { HEADERS += $$sprintf("svcore/data/model/test/%1", $$file) } -QMAKE_POST_LINK = ./$${TARGET}$${TARGET_EXT} +!win32* { + QMAKE_POST_LINK = ./$${TARGET} +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 test-svcore-system.pro --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test-svcore-system.pro Mon Sep 17 14:05:41 2018 +0100 @@ -0,0 +1,33 @@ + +TEMPLATE = app + +exists(config.pri) { + include(config.pri) +} + +!exists(config.pri) { + include(noconfig.pri) +} + +include(base.pri) + +CONFIG += console +QT += network xml testlib +QT -= gui + +win32-x-g++:QMAKE_LFLAGS += -Wl,-subsystem,console +macx*: CONFIG -= app_bundle + +TARGET = test-svcore-system + +OBJECTS_DIR = o +MOC_DIR = o + +include(svcore/system/test/files.pri) + +for (file, TEST_SOURCES) { SOURCES += $$sprintf("svcore/system/test/%1", $$file) } +for (file, TEST_HEADERS) { HEADERS += $$sprintf("svcore/system/test/%1", $$file) } + +!win32* { + QMAKE_POST_LINK = ./$${TARGET} +} diff -r 246bdf94ef7b -r 55d9bbf1fe45 version.h --- a/version.h Mon Sep 17 13:53:25 2018 +0100 +++ b/version.h Mon Sep 17 14:05:41 2018 +0100 @@ -1,1 +1,1 @@ -#define SV_VERSION "3.0" +#define SV_VERSION "3.2"