summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2024-07-27 13:39:32 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2024-07-27 13:39:32 +0200
commitfc29354d86e6a8b5601e92405b89a1da27406ce7 (patch)
treee31069154ad5bd9497764b6205dd4d3a411b40eb
parent329110e3230a6518f024c612842b04afdea1cd03 (diff)
WIP
-rw-r--r--INSTALL322
-rw-r--r--src/Makefile.am130
-rw-r--r--src/audiocache.cc28
-rw-r--r--src/audiocache.h55
-rw-r--r--src/audiodata.h28
-rw-r--r--src/audioextractor.cc24
-rw-r--r--src/audioextractor.h4
-rw-r--r--src/audiofile.h28
-rw-r--r--src/canvastool.cc2
-rw-r--r--src/canvastool.h2
-rw-r--r--src/canvastoollisten.cc3
-rw-r--r--src/canvastoolposition.cc161
-rw-r--r--src/canvastoolposition.h72
-rw-r--r--src/canvastoolranges.cc (renamed from src/canvastoolselections.cc)222
-rw-r--r--src/canvastoolranges.h (renamed from src/canvastoolselections.h)51
-rw-r--r--src/canvastoolthreshold.cc34
-rw-r--r--src/canvastoolthreshold.h13
-rw-r--r--src/detector.cc28
-rw-r--r--src/detector.h44
-rw-r--r--src/filelist.cc652
-rw-r--r--src/filelist.h58
-rw-r--r--src/instrumentwidget.cc275
-rw-r--r--src/instrumentwidget.h22
-rw-r--r--src/player.cc40
-rw-r--r--src/player.h14
-rw-r--r--src/project.cc56
-rw-r--r--src/project.h36
-rw-r--r--src/projectrenderer.cc6
-rw-r--r--src/projectserialiser.cc36
-rw-r--r--src/range.cc (renamed from src/selection.cc)34
-rw-r--r--src/range.h (renamed from src/selection.h)78
-rw-r--r--src/rangeeditor.cc (renamed from src/selectioneditor.cc)33
-rw-r--r--src/rangeeditor.h (renamed from src/selectioneditor.h)13
-rw-r--r--src/samplesorter.cc205
-rw-r--r--src/samplesorter.h24
-rw-r--r--src/ts/dgedit_da.ts152
-rw-r--r--src/ts/dgedit_fr.ts153
-rwxr-xr-xtools/MocList6
38 files changed, 2116 insertions, 1028 deletions
diff --git a/INSTALL b/INSTALL
index 007e939..e82fd21 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,8 +1,8 @@
Installation Instructions
*************************
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
+ Copyright (C) 1994-1996, 1999-2002, 2004-2017, 2020-2021 Free
+Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
@@ -12,97 +12,96 @@ without warranty of any kind.
Basic Installation
==================
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
+ Briefly, the shell command './configure && make && make install'
+should configure, build, and install this package. The following
+more-detailed instructions are generic; see the 'README' file for
instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
+'INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
- The `configure' shell script attempts to guess correct values for
+ The 'configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
+those values to create a 'Makefile' in each directory of the package.
+It may also create one or more '.h' files containing system-dependent
+definitions. Finally, it creates a shell script 'config.status' that
you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
+file 'config.log' containing compiler output (useful mainly for
+debugging 'configure').
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
+ It can also use an optional file (typically called 'config.cache' and
+enabled with '--cache-file=config.cache' or simply '-C') that saves the
+results of its tests to speed up reconfiguring. Caching is disabled by
+default to prevent problems with accidental use of stale cache files.
If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
+to figure out how 'configure' could check whether to do them, and mail
+diffs or instructions to the address given in the 'README' so they can
be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
+some point 'config.cache' contains results you don't want to keep, you
may remove or edit it.
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
+ The file 'configure.ac' (or 'configure.in') is used to create
+'configure' by a program called 'autoconf'. You need 'configure.ac' if
+you want to change it or regenerate 'configure' using a newer version of
+'autoconf'.
The simplest way to compile this package is:
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
+ 1. 'cd' to the directory containing the package's source code and type
+ './configure' to configure the package for your system.
- Running `configure' might take a while. While running, it prints
+ Running 'configure' might take a while. While running, it prints
some messages telling which features it is checking for.
- 2. Type `make' to compile the package.
+ 2. Type 'make' to compile the package.
- 3. Optionally, type `make check' to run any self-tests that come with
+ 3. Optionally, type 'make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
- 4. Type `make install' to install the programs and any data files and
+ 4. Type 'make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
+ user, and only the 'make install' phase executed with root
privileges.
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ 5. Optionally, type 'make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
+ regular user, particularly if the prior 'make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
+ source code directory by typing 'make clean'. To also remove the
+ files that 'configure' created (so you can compile the package for
+ a different kind of computer), type 'make distclean'. There is
+ also a 'make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
- 7. Often, you can also type `make uninstall' to remove the installed
+ 7. Often, you can also type 'make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
- 8. Some packages, particularly those that use Automake, provide `make
+ 8. Some packages, particularly those that use Automake, provide 'make
distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
+ targets like 'make install' and 'make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
+the 'configure' script does not know about. Run './configure --help'
for details on some of the pertinent environment variables.
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
+ You can give 'configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here is
+an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
@@ -113,21 +112,21 @@ Compiling For Multiple Architectures
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
+own directory. To do this, you can use GNU 'make'. 'cd' to the
directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
+the 'configure' script. 'configure' automatically checks for the source
+code in the directory that 'configure' is in and in '..'. This is known
+as a "VPATH" build.
- With a non-GNU `make', it is safer to compile the package for one
+ With a non-GNU 'make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
+installed the package for one architecture, use 'make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
+"universal" binaries--by specifying multiple '-arch' options to the
+compiler but only a single '-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
@@ -136,105 +135,104 @@ this:
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
+using the 'lipo' tool if you have problems.
Installation Names
==================
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
+ By default, 'make install' installs the package's commands under
+'/usr/local/bin', include files under '/usr/local/include', etc. You
+can specify an installation prefix other than '/usr/local' by giving
+'configure' the option '--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
+options like '--bindir=DIR' to specify different values for particular
+kinds of files. Run 'configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the default
+for these options is expressed in terms of '${prefix}', so that
+specifying just '--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
+correct locations to 'configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
+'make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
-affected directory. For example, `make install
+affected directory. For example, 'make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
+'${prefix}'. Any directories that were specified during 'configure',
+but not in terms of '${prefix}', must each be overridden at install time
+for the entire installation to be relocated. The approach of makefile
+variable overrides for each directory variable is required by the GNU
+Coding Standards, and ideally causes no recompilation. However, some
+platforms have known limitations with the semantics of shared libraries
+that end up requiring recompilation when using this method, particularly
+noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the 'DESTDIR' variable. For
+example, 'make install DESTDIR=/alternate/directory' will prepend
+'/alternate/directory' before all installation names. The approach of
+'DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
+when some directory options were not specified in terms of '${prefix}'
+at 'configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
+with an extra prefix or suffix on their names by giving 'configure' the
+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
+
+ Some packages pay attention to '--enable-FEATURE' options to
+'configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
+is something like 'gnu-as' or 'x' (for the X Window System). The
+'README' should mention any '--enable-' and '--with-' options that the
package recognizes.
- For packages that use the X Window System, `configure' can usually
+ For packages that use the X Window System, 'configure' can usually
find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
+you can use the 'configure' options '--x-includes=DIR' and
+'--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
+execution of 'make' will be. For these packages, running './configure
--enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
+overridden with 'make V=1'; while running './configure
--disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
+overridden with 'make V=0'.
Particular systems
==================
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
+is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
+ HP-UX 'make' updates targets which have the same timestamps as their
+prerequisites, which makes it generally unusable when shipped generated
+files such as 'configure' are involved. Use GNU 'make' instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
+parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
+workaround. If GNU CC is not installed, it is therefore recommended to
+try
./configure CC="cc"
@@ -242,26 +240,26 @@ and if that doesn't work, try
./configure CC="cc -nodtk"
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
+these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
+in your 'PATH', put it _after_ '/usr/bin'.
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
+ On Haiku, software installed for all users goes in '/boot/common',
+not '/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
- There may be some features `configure' cannot figure out
+ There may be some features 'configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
+_same_ architectures, 'configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
+'--build=TYPE' option. TYPE can either be a short name for the system
+type, such as 'sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
@@ -270,101 +268,101 @@ where SYSTEM can have one of these forms:
OS
KERNEL-OS
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
+ See the file 'config.sub' for the possible values of each field. If
+'config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
+use the option '--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
+eventually be run) with '--host=TYPE'.
Sharing Defaults
================
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
+ If you want to set default values for 'configure' scripts to share,
+you can create a site shell script called 'config.site' that gives
+default values for variables like 'CC', 'cache_file', and 'prefix'.
+'configure' looks for 'PREFIX/share/config.site' if it exists, then
+'PREFIX/etc/config.site' if it exists. Or, you can set the
+'CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all 'configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
+environment passed to 'configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
+them in the 'configure' command line, using 'VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
-causes the specified `gcc' to be used as the C compiler (unless it is
+causes the specified 'gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation. Until the limitation is lifted, you can use
-this workaround:
+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
+Autoconf limitation. Until the limitation is lifted, you can use this
+workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-`configure' Invocation
+'configure' Invocation
======================
- `configure' recognizes the following options to control how it
+ 'configure' recognizes the following options to control how it
operates.
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
+'--help'
+'-h'
+ Print a summary of all of the options to 'configure', and exit.
-`--help=short'
-`--help=recursive'
+'--help=short'
+'--help=recursive'
Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
+ 'configure', and exit. The 'short' variant lists options used only
+ in the top level, while the 'recursive' variant lists options also
+ present in any nested packages.
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
+'--version'
+'-V'
+ Print the version of Autoconf used to generate the 'configure'
script, and exit.
-`--cache-file=FILE'
+'--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
+ traditionally 'config.cache'. FILE defaults to '/dev/null' to
disable caching.
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
+'--config-cache'
+'-C'
+ Alias for '--cache-file=config.cache'.
-`--quiet'
-`--silent'
-`-q'
+'--quiet'
+'--silent'
+'-q'
Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
+ suppress all normal output, redirect it to '/dev/null' (any error
messages will still be shown).
-`--srcdir=DIR'
+'--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
+ 'configure' can determine that directory automatically.
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
+'--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names:: for
+ more details, including other options available for fine-tuning the
+ installation locations.
-`--no-create'
-`-n'
+'--no-create'
+'-n'
Run the configure checks, but stop before creating any output
files.
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
+'configure' also accepts some other, not widely useful, options. Run
+'configure --help' for more details.
diff --git a/src/Makefile.am b/src/Makefile.am
index a38b804..596767e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,74 +10,76 @@ dgedit_CXXFLAGS = -g $(SNDFILE_CXXFLAGS) $(QT_CFLAGS) $(AO_CFLAGS) \
AM_CXXFLAGS = $(QT_CFLAGS)
dgedit_TRANSLATIONS = \
- ts/dgedit_da.ts \
- ts/dgedit_fr.ts
+ $(top_srcdir)/src/ts/dgedit_da.ts \
+ $(top_srcdir)/src/ts/dgedit_fr.ts
dgedit_SOURCES = \
- dgedit.cc \
- aboutdialog.cc \
- audioextractor.cc \
- canvas.cc \
- canvastool.cc \
- canvastoollisten.cc \
- canvastoolselections.cc \
- canvastoolthreshold.cc \
- canvaswidget.cc \
- channeldialog.cc \
- channelswidget.cc \
- filelist.cc \
- imageeditor.cc \
- instrumentdialog.cc \
- instrumentwidget.cc \
- itemeditor.cc \
- localehandler.cc \
- mainwindow.cc \
- mipmap.cc \
- player.cc \
- project.cc \
- projectdialog.cc \
- projectrenderer.cc \
- projectserialiser.cc \
- renderdialog.cc \
- samplesorter.cc \
- selection.cc \
- selectioneditor.cc \
- settings.cc \
- volumefader.cc \
- zoomslider.cc
+ $(top_srcdir)/src/dgedit.cc \
+ $(top_srcdir)/src/aboutdialog.cc \
+ $(top_srcdir)/src/audioextractor.cc \
+ $(top_srcdir)/src/canvas.cc \
+ $(top_srcdir)/src/canvastool.cc \
+ $(top_srcdir)/src/canvastoollisten.cc \
+ $(top_srcdir)/src/canvastoolposition.cc \
+ $(top_srcdir)/src/canvastoolranges.cc \
+ $(top_srcdir)/src/canvastoolthreshold.cc \
+ $(top_srcdir)/src/canvaswidget.cc \
+ $(top_srcdir)/src/channeldialog.cc \
+ $(top_srcdir)/src/channelswidget.cc \
+ $(top_srcdir)/src/filelist.cc \
+ $(top_srcdir)/src/imageeditor.cc \
+ $(top_srcdir)/src/instrumentdialog.cc \
+ $(top_srcdir)/src/instrumentwidget.cc \
+ $(top_srcdir)/src/itemeditor.cc \
+ $(top_srcdir)/src/localehandler.cc \
+ $(top_srcdir)/src/mainwindow.cc \
+ $(top_srcdir)/src/mipmap.cc \
+ $(top_srcdir)/src/player.cc \
+ $(top_srcdir)/src/project.cc \
+ $(top_srcdir)/src/projectdialog.cc \
+ $(top_srcdir)/src/projectrenderer.cc \
+ $(top_srcdir)/src/projectserialiser.cc \
+ $(top_srcdir)/src/renderdialog.cc \
+ $(top_srcdir)/src/samplesorter.cc \
+ $(top_srcdir)/src/range.cc \
+ $(top_srcdir)/src/rangeeditor.cc \
+ $(top_srcdir)/src/settings.cc \
+ $(top_srcdir)/src/volumefader.cc \
+ $(top_srcdir)/src/zoomslider.cc
HDRS = \
- aboutdialog.h \
- audioextractor.h \
- canvas.h \
- canvastool.h \
- canvastoollisten.h \
- canvastoolselections.h \
- canvastoolthreshold.h \
- canvaswidget.h \
- channeldialog.h \
- channelswidget.h \
- filelist.h \
- imageeditor.h \
- instrumentdialog.h \
- instrumentwidget.h \
- itemeditor.h \
- localehandler.h \
- mainwindow.h \
- mipmap.h \
- player.h \
- project.h \
- projectdialog.h \
- projectrenderer.h \
- projectserialiser.h \
- renderdialog.h \
- samplesorter.h \
- selection.h \
- selectioneditor.h \
- sleep.h \
- settings.h \
- volumefader.h \
- zoomslider.h
+ $(top_srcdir)/src/aboutdialog.h \
+ $(top_srcdir)/src/audioextractor.h \
+ $(top_srcdir)/src/canvas.h \
+ $(top_srcdir)/src/canvastool.h \
+ $(top_srcdir)/src/canvastoollisten.h \
+ $(top_srcdir)/src/canvastoolposition.h \
+ $(top_srcdir)/src/canvastoolranges.h \
+ $(top_srcdir)/src/canvastoolthreshold.h \
+ $(top_srcdir)/src/canvaswidget.h \
+ $(top_srcdir)/src/channeldialog.h \
+ $(top_srcdir)/src/channelswidget.h \
+ $(top_srcdir)/src/filelist.h \
+ $(top_srcdir)/src/imageeditor.h \
+ $(top_srcdir)/src/instrumentdialog.h \
+ $(top_srcdir)/src/instrumentwidget.h \
+ $(top_srcdir)/src/itemeditor.h \
+ $(top_srcdir)/src/localehandler.h \
+ $(top_srcdir)/src/mainwindow.h \
+ $(top_srcdir)/src/mipmap.h \
+ $(top_srcdir)/src/player.h \
+ $(top_srcdir)/src/project.h \
+ $(top_srcdir)/src/projectdialog.h \
+ $(top_srcdir)/src/projectrenderer.h \
+ $(top_srcdir)/src/projectserialiser.h \
+ $(top_srcdir)/src/renderdialog.h \
+ $(top_srcdir)/src/samplesorter.h \
+ $(top_srcdir)/src/range.h \
+ $(top_srcdir)/src/rangeeditor.h \
+ $(top_srcdir)/src/sleep.h \
+ $(top_srcdir)/src/settings.h \
+ $(top_srcdir)/src/volumefader.h \
+ $(top_srcdir)/src/zoomslider.h
EXTRA_DIST = \
$(dgedit_TRANSLATIONS) \
diff --git a/src/audiocache.cc b/src/audiocache.cc
new file mode 100644
index 0000000..74b6498
--- /dev/null
+++ b/src/audiocache.cc
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiocache.cc
+ *
+ * Wed Mar 15 09:06:46 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "audiocache.h"
+
diff --git a/src/audiocache.h b/src/audiocache.h
new file mode 100644
index 0000000..fc5fd5b
--- /dev/null
+++ b/src/audiocache.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiocache.h
+ *
+ * Wed Mar 15 09:06:46 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+class AudioData
+{
+public:
+ AudioData(const AudioFile& audiofile);
+
+ //load();
+ //unload();
+
+ AudioData::ID id;
+ std::vector<float> data;
+};
+
+class AudioCache
+{
+public:
+ using ID = int;
+
+ static AudioCache& get()
+ {
+ static AudioCache cache;
+ return cache;
+ }
+
+ ID add(const AudioFile&);
+ AudioData& get(ID);
+ void remove(ID);
+};
diff --git a/src/audiodata.h b/src/audiodata.h
new file mode 100644
index 0000000..884717b
--- /dev/null
+++ b/src/audiodata.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiodata.h
+ *
+ * Wed Mar 15 08:58:33 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
diff --git a/src/audioextractor.cc b/src/audioextractor.cc
index 95fe6b2..681edaf 100644
--- a/src/audioextractor.cc
+++ b/src/audioextractor.cc
@@ -50,14 +50,14 @@ AudioExtractor::AudioExtractor(Instrument& instrument, QObject *parent)
{
}
-bool AudioExtractor::exportSelections()
+bool AudioExtractor::exportRanges()
{
- auto selections = instrument.getSelections();
+ auto ranges = instrument.getRanges();
auto exportpath = instrument.getProject().getExportPath();
auto prefix = instrument.getPrefix();
int samplerate = -1;
- emit setMaximumProgress(selections.ids().size() + 1/* for xml writing*/);
+ emit setMaximumProgress(ranges.ids().size() + 1/* for xml writing*/);
int progress = 0;
emit progressUpdate(progress++);
qApp->processEvents();
@@ -92,15 +92,16 @@ bool AudioExtractor::exportSelections()
}
idx = 1;
- QVector<sel_id_t> sels = selections.ids();
+ QVector<sel_id_t> sels = ranges.ids();
- // Sort selections by velocity
+/*
+ // Sort ranges by velocity
for(int v1 = 0; v1 < sels.size(); v1++)
{
for(int v2 = 0; v2 < sels.size(); v2++)
{
- Selection sel1 = selections.get(sels[v1]);
- Selection sel2 = selections.get(sels[v2]);
+ Range sel1 = ranges.get(sels[v1]);
+ Range sel2 = ranges.get(sels[v2]);
if(sel1.energy < sel2.energy)
{
@@ -110,7 +111,7 @@ bool AudioExtractor::exportSelections()
}
}
}
-
+*/
if(samplerate == -1)
{
// For some reason we never got a samplerate. Set it to 44k1Hz
@@ -121,7 +122,7 @@ bool AudioExtractor::exportSelections()
QVector<sel_id_t>::iterator si = sels.begin();
while(si != sels.end())
{
- Selection sel = selections.get(*si);
+ Range sel = ranges.get(*si);
size_t offset = sel.from;
size_t size = sel.to - sel.from;
size_t fadein = sel.fadein;
@@ -241,15 +242,16 @@ bool AudioExtractor::exportSelections()
{
index++;
- Selection i = selections.get(*si);
+ Range i = ranges.get(*si);
i.name = prefix + "-" + QString::number(index);
QDomElement sample = doc.createElement("sample");
sample.setAttribute("name", i.name);
sample.setAttribute("power", QString::number(i.energy));
+ sample.setAttribute("position", QString::number(i.position));
samples.appendChild(sample);
- selections.update(*si, i);
+ ranges.update(*si, i);
int channelnum = 1; // Filechannel numbers are 1-based.
diff --git a/src/audioextractor.h b/src/audioextractor.h
index 134c582..aa85d98 100644
--- a/src/audioextractor.h
+++ b/src/audioextractor.h
@@ -32,7 +32,7 @@
#include <QString>
#include <QVector>
-#include "selection.h"
+#include "range.h"
#include "samplesorter.h"
class Instrument;
@@ -45,7 +45,7 @@ public:
AudioExtractor(Instrument& instrument, QObject* parent);
public slots:
- bool exportSelections();
+ bool exportRanges();
signals:
void progressUpdate(int value);
diff --git a/src/audiofile.h b/src/audiofile.h
new file mode 100644
index 0000000..0513f64
--- /dev/null
+++ b/src/audiofile.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * audiofile.h
+ *
+ * Wed Mar 15 08:47:33 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
diff --git a/src/canvastool.cc b/src/canvastool.cc
index a00a5a2..0ec7f6d 100644
--- a/src/canvastool.cc
+++ b/src/canvastool.cc
@@ -66,7 +66,7 @@ void CanvasTool::activate()
setActive(true);
}
-void CanvasTool::disactivate()
+void CanvasTool::deactivate()
{
setActive(false);
}
diff --git a/src/canvastool.h b/src/canvastool.h
index c890422..dd4a8b3 100644
--- a/src/canvastool.h
+++ b/src/canvastool.h
@@ -54,7 +54,7 @@ signals:
public slots:
void setActive(bool active);
void activate();
- void disactivate();
+ void deactivate();
private:
bool _active;
diff --git a/src/canvastoollisten.cc b/src/canvastoollisten.cc
index b49e8bc..145d4f9 100644
--- a/src/canvastoollisten.cc
+++ b/src/canvastoollisten.cc
@@ -27,6 +27,8 @@
#include "canvastoollisten.h"
#include <QApplication>
+#include <iostream>
+
CanvasToolListen::CanvasToolListen(Canvas* c, Player& p)
: player(p)
@@ -42,6 +44,7 @@ bool CanvasToolListen::mousePressEvent(QMouseEvent* event)
return false;
}
player.setPosition(canvas->unmapX(event->x()));
+ std::cout << (size_t)canvas->unmapX(event->x()) << std::endl;
canvas->update();
connect(&player, SIGNAL(positionUpdate(size_t)), this, SLOT(update(size_t)));
return true;
diff --git a/src/canvastoolposition.cc b/src/canvastoolposition.cc
new file mode 100644
index 0000000..7784720
--- /dev/null
+++ b/src/canvastoolposition.cc
@@ -0,0 +1,161 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * canvastoolposition.cc
+ *
+ * Sat Mar 25 11:45:34 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "canvastoolposition.h"
+
+#include "project.h"
+#include "canvas.h"
+#include "range.h"
+
+#include <iostream>
+
+#define mapX(x) canvas.mapX(x)
+#define mapY(x) canvas.mapY(x)
+#define unmapX(x) canvas.unmapX(x)
+#define unmapY(x) canvas.unmapY(x)
+
+CanvasToolPosition::CanvasToolPosition(Instrument& instrument,
+ Canvas& canvas,
+ Ranges& ranges,
+ Ranges& ranges_preview)
+ : instrument(instrument)
+ , canvas(canvas)
+ , ranges(ranges)
+ , ranges_preview(ranges_preview)
+{
+ colSelBg = QColor(255, 0, 0, 60);
+ colSel = QColor(255, 0, 0, 160);
+ colActiveSelBg = QColor(255, 255, 0, 60);
+ colActiveSel = QColor(255, 255, 0, 160);
+ colPreviewSelBg = QColor(0, 0, 255, 60);
+ colPreviewSel = QColor(0, 0, 255, 160);
+}
+
+bool CanvasToolPosition::mouseMoveEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+bool CanvasToolPosition::mousePressEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+bool CanvasToolPosition::mouseReleaseEvent(QMouseEvent* event)
+{
+ return false;
+}
+
+namespace {
+void drawRange(const Range& range, Canvas& canvas, QPainter& painter)
+{
+ int x1 = mapX(range.pos1);
+ int x2 = mapX(range.pos2);
+
+ if(x1 > x2)
+ {
+ std::swap(x1, x2);
+ }
+
+ // x1 x2
+ // | |
+ // | |
+ // |<---->|
+ // | |
+ // | |
+ constexpr auto len = 8;
+ painter.drawLine(x1, mapY(-1.0), x1, mapY(1.0)); // left bar
+
+ painter.drawLine(x1, mapY( 0.0), x1 + len, mapY(0.0) + len); // left arrow
+ painter.drawLine(x1, mapY( 0.0), x1 + len, mapY(0.0) - len); // left arrow
+
+ painter.drawLine(x1, mapY( 0.0), x2, mapY(0.0)); // horizontal line
+
+ painter.drawLine(x2, mapY( 0.0), x2 - len, mapY(0.0) + len); // right arrow
+ painter.drawLine(x2, mapY( 0.0), x2 - len, mapY(0.0) - len); // right arrow
+
+ painter.drawLine(x2, mapY(-1.0), x2, mapY(1.0)); // right bar
+}
+}
+
+void CanvasToolPosition::paintEvent(QPaintEvent* event, QPainter& painter)
+{
+ int pos = unmapX(event->rect().x());
+ int width = unmapX(event->rect().width());
+
+ {
+ QVector<sel_id_t> ids = ranges.ids();
+ QVector<sel_id_t>::iterator i = ids.begin();
+ while(i != ids.end())
+ {
+ Range range = ranges.get(*i);
+
+ if(ranges.active() == *i)
+ {
+ painter.setBrush(colActiveSelBg);
+ painter.setPen(colActiveSel);
+ }
+ else
+ {
+ painter.setBrush(colSelBg);
+ painter.setPen(colSel);
+ }
+
+ drawRange(range, canvas, painter);
+ i++;
+ }
+ }
+
+ if(show_preview)
+ {
+ QVector<sel_id_t> ids = ranges_preview.ids();
+ QVector<sel_id_t>::iterator i = ids.begin();
+ while(i != ids.end())
+ {
+ Range range = ranges.get(*i);
+ painter.setBrush(colPreviewSelBg);
+ painter.setPen(colPreviewSel);
+ drawRange(range, canvas, painter);
+ i++;
+ }
+ }
+}
+
+void CanvasToolPosition::keyReleaseEvent(QKeyEvent* event)
+{
+}
+
+void CanvasToolPosition::rangesChanged()
+{
+ //auto ranges = instrument.getRanges();
+ canvas.update();
+}
+
+void CanvasToolPosition::setShowPreview(bool show_preview)
+{
+ this->show_preview = show_preview;
+ canvas.update();
+}
diff --git a/src/canvastoolposition.h b/src/canvastoolposition.h
new file mode 100644
index 0000000..0265a37
--- /dev/null
+++ b/src/canvastoolposition.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * canvastoolposition.h
+ *
+ * Sat Mar 25 11:45:34 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include "canvastool.h"
+
+#include <QColor>
+
+class Instrument;
+class Canvas;
+class Ranges;
+
+class CanvasToolPosition
+ : public CanvasTool
+{
+ Q_OBJECT
+public:
+ CanvasToolPosition(Instrument& instrument,
+ Canvas& canvas,
+ Ranges& ranges,
+ Ranges& ranges_preview);
+
+ QString name() override { return tr("Position"); }
+ bool mouseMoveEvent(QMouseEvent* event) override;
+ bool mousePressEvent(QMouseEvent* event) override;
+ bool mouseReleaseEvent(QMouseEvent* event) override;
+ void paintEvent(QPaintEvent* event, QPainter& painter) override;
+ void keyReleaseEvent(QKeyEvent* event) override;
+
+public slots:
+ void rangesChanged();
+ void setShowPreview(bool show_preview);
+
+private:
+ Instrument& instrument;
+ Canvas& canvas;
+ Ranges& ranges;
+ Ranges& ranges_preview;
+
+ QColor colSelBg;
+ QColor colSel;
+ QColor colActiveSelBg;
+ QColor colActiveSel;
+ QColor colPreviewSelBg;
+ QColor colPreviewSel;
+
+ bool show_preview{false};
+};
diff --git a/src/canvastoolselections.cc b/src/canvastoolranges.cc
index d3e90f1..9a76163 100644
--- a/src/canvastoolselections.cc
+++ b/src/canvastoolranges.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * canvastoolselections.cc
+ * canvastoolranges.cc
*
* Thu Jul 28 20:16:59 CEST 2011
* Copyright 2011 Bent Bisballe Nyeng
@@ -24,28 +24,32 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "canvastoolselections.h"
+#include "canvastoolranges.h"
+
+#include "project.h"
#include <math.h>
#include <stdio.h>
+#include <iostream>
#define mapX(x) canvas->mapX(x)
#define mapY(x) canvas->mapY(x)
#define unmapX(x) canvas->unmapX(x)
#define unmapY(x) canvas->unmapY(x)
-CanvasToolSelections::CanvasToolSelections(Canvas* c, Selections& s,
- Selections& p)
- : selections(s)
- , selections_preview(p)
+CanvasToolRanges::CanvasToolRanges(Instrument& instrument,
+ Canvas* c, Ranges& s,
+ Ranges& p)
+ : instrument(instrument)
+ , ranges(s)
+ , ranges_preview(p)
{
- threshold = 0.5; // Default from CanvasToolThreshold
hold = 100;
canvas = c;
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ range_is_moving_left = false;
+ range_is_moving_right = false;
colSelBg = QColor(255, 0, 0, 60);
colSel = QColor(255, 0, 0, 160);
@@ -55,39 +59,39 @@ CanvasToolSelections::CanvasToolSelections(Canvas* c, Selections& s,
colPreviewSel = QColor(0, 0, 255, 160);
}
-bool CanvasToolSelections::mouseMoveEvent(QMouseEvent* event)
+bool CanvasToolRanges::mouseMoveEvent(QMouseEvent* event)
{
- sel_id_t active_selection = selections.active();
- Selection act_sel = selections.get(active_selection);
+ sel_id_t active_range = ranges.active();
+ Range act_sel = ranges.get(active_range);
- if(selection_is_moving_left)
+ if(range_is_moving_left)
{
float val = unmapX(event->x());
if(val > act_sel.to) val = act_sel.to - 1;
act_sel.from = std::max(0.0f, val);
- selections.update(active_selection, act_sel);
+ ranges.update(active_range, act_sel);
canvas->update();
return true;
}
- if(selection_is_moving_right)
+ if(range_is_moving_right)
{
float val = unmapX(event->x());
if(val < act_sel.from) val = act_sel.from + 1;
act_sel.to = std::min(val, (float)canvas->size);
- selections.update(active_selection, act_sel);
+ ranges.update(active_range, act_sel);
canvas->update();
return true;
}
if(event->button() != Qt::LeftButton)
{
- // Check if a selection is being dragged.
- QVector<sel_id_t> ids = selections.ids();
+ // Check if a range is being dragged.
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(abs(event->x() - mapX(sel.from)) < 2
|| abs(event->x() - mapX(sel.to)) < 2)
{
@@ -101,42 +105,42 @@ bool CanvasToolSelections::mouseMoveEvent(QMouseEvent* event)
return false;
}
-bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
+bool CanvasToolRanges::mousePressEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- // Check if a selection is being dragged.
- QVector<sel_id_t> ids = selections.ids();
+ // Check if a range is being dragged.
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(abs(event->x() - mapX(sel.from)) < 2)
{
- selections.setActive(*i);
- selection_is_moving_left = true;
+ ranges.setActive(*i);
+ range_is_moving_left = true;
return true;
}
if(abs(event->x() - mapX(sel.to)) < 2)
{
- selections.setActive(*i);
- selection_is_moving_right = true;
+ ranges.setActive(*i);
+ range_is_moving_right = true;
return true;
}
i++;
}
- // Check if a selection is being selected.
+ // Check if a range is being selected.
i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(event->x() > mapX(sel.from) &&
event->x() < mapX(sel.to))
{
- selections.setActive(*i);
+ ranges.setActive(*i);
canvas->update();
return true;
}
@@ -144,12 +148,12 @@ bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
i++;
}
- // Make new selection
+ // Make new range
int from = unmapX(event->x());
- Selection new_selection(from, from);
- sel_id_t id = selections.add(new_selection);
- selections.setActive(id);
- selection_is_moving_right = true;
+ Range new_range{.from = from, .to = from};
+ sel_id_t id = ranges.add(new_range);
+ ranges.setActive(id);
+ range_is_moving_right = true;
canvas->update();
return true;
}
@@ -157,14 +161,14 @@ bool CanvasToolSelections::mousePressEvent(QMouseEvent* event)
return false;
}
-bool CanvasToolSelections::mouseReleaseEvent(QMouseEvent* event)
+bool CanvasToolRanges::mouseReleaseEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- if(selection_is_moving_left || selection_is_moving_right)
+ if(range_is_moving_left || range_is_moving_right)
{
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ range_is_moving_left = false;
+ range_is_moving_right = false;
canvas->setCursor(Qt::ArrowCursor);
canvas->update();
return true;
@@ -174,24 +178,24 @@ bool CanvasToolSelections::mouseReleaseEvent(QMouseEvent* event)
return false;
}
-void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
+void CanvasToolRanges::paintEvent(QPaintEvent* event, QPainter& painter)
{
int pos = unmapX(event->rect().x());
int width = unmapX(event->rect().width());
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
int from = sel.from;
int to = sel.to;
int fadein = sel.fadein;
int fadeout = sel.fadeout;
if(from > pos + width || to + width < pos)
{ i++; continue; }
- if(selections.active() ==* i)
+ if(ranges.active() == *i)
{
painter.setBrush(colActiveSelBg);
painter.setPen(colActiveSel);
@@ -213,11 +217,11 @@ void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
int from = sel.from;
int to = sel.to;
int fadein = sel.fadein;
@@ -238,56 +242,68 @@ void CanvasToolSelections::paintEvent(QPaintEvent* event, QPainter& painter)
}
}
-void CanvasToolSelections::keyReleaseEvent(QKeyEvent* event)
+void CanvasToolRanges::keyReleaseEvent(QKeyEvent* event)
{
- if(selections.active() != SEL_NONE && event->key() == Qt::Key_Delete)
+ if(ranges.active() != SEL_NONE && event->key() == Qt::Key_Delete)
{
- selections.remove(selections.active());
+ ranges.remove(ranges.active());
canvas->update();
}
}
-void CanvasToolSelections::thresholdChanged(double t)
-{
- threshold = t;
-}
-
-void CanvasToolSelections::holdChanged(int h)
+void CanvasToolRanges::holdChanged(int h)
{
hold = h;
}
-void CanvasToolSelections::noiseFloorChanged(int t)
+void CanvasToolRanges::noiseFloorChanged(int t)
{
double div = 666.0 / 0.00003;
noise_floor = (double)t/div;
}
-void CanvasToolSelections::fadeoutChanged(int t)
+void CanvasToolRanges::fadeoutChanged(int t)
{
fadeout = (double)t/1000.0;
}
-void CanvasToolSelections::autoCreateSelections()
+void CanvasToolRanges::autoCreateRanges()
{
- doAutoCreateSelections(false);
+ doAutoCreateRanges(false);
}
-void CanvasToolSelections::autoCreateSelectionsPreview()
+void CanvasToolRanges::autoCreateRangesPreview()
{
- doAutoCreateSelections(true);
+ doAutoCreateRanges(true);
}
-void CanvasToolSelections::doAutoCreateSelections(bool preview)
+void CanvasToolRanges::setPositionData(const float* positionData1,
+ size_t positionSize1,
+ const float* positionData2,
+ size_t positionSize2)
{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+ std::cout << positionSize1 << " " << positionSize2 << std::endl;
+ this->positionData1 = positionData1;
+ this->positionSize1 = positionSize1;
+
+ this->positionData2 = positionData2;
+ this->positionSize2 = positionSize2;
+}
+
+void CanvasToolRanges::doAutoCreateRanges(bool preview)
+{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+
+ // TODO: Get data from master file instead of canvas
float* data = canvas->data;
size_t size = canvas->size;
- if(preview) selections_preview.clear();
+ if(preview) ranges_preview.clear();
for(size_t i = 0; i < size; i++)
{
- if(fabs(data[i]) > fabs(threshold))
+ if(fabs(data[i]) > fabs(instrument.getThreshold()))
{
int from = i;
@@ -320,32 +336,94 @@ void CanvasToolSelections::doAutoCreateSelections(bool preview)
to++;
}
- Selection s(from, to, 2, ((to - from) / 3) * fadeout);
+ Range range{
+ .from = from,
+ .to = to,
+ .fadein = 2,
+ .fadeout = ((to - from) / 3) * fadeout
+ };
+
+ /////////////////////////////////////////////////////////////////////////
+ if(positionData1 && positionData2)
+ {
+ //TODO: set window in ms instead of samples
+ int pos_window_size{1000}; // +/- 500 from detected,
+ double threshold = 0.1; // 1/3 is about right
+
+ float norm{0};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ norm = std::max(std::abs(positionData1[idx]), norm);
+ }
+
+ int pos1{range.from - pos_window_size / 2};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ if(std::abs(positionData1[idx]) / norm > threshold)
+ {
+ pos1 = idx;
+ range.pos1 = pos1;
+ break;
+ }
+ }
+
+ norm = 0;
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ norm = std::max(std::abs(positionData1[idx]), norm);
+ }
+
+ int pos2{range.from + pos_window_size / 2};
+ for(int idx = range.from - pos_window_size / 2;
+ idx < range.from + pos_window_size / 2;
+ ++idx)
+ {
+ if(std::abs(positionData2[idx]) / norm > threshold)
+ {
+ pos2 = idx;
+ range.pos2 = pos2;
+ break;
+ }
+ }
+
+ constexpr double speed_of_sound{343100}; // mm/s
+ constexpr double samplerate{48000}; // 48kHz - TODO get from audio
+
+ range.position = std::abs(pos1 - pos2) * speed_of_sound / samplerate / 2.0;
+ }
+ /////////////////////////////////////////////////////////////////////////
+
if(preview)
{
- selections_preview.add(s);
+ ranges_preview.add(range);
}
else
{
- selections.add(s);
+ ranges.add(range);
}
- i = to+1;
+ i = to + 1;
}
}
canvas->update();
}
-void CanvasToolSelections::clearSelections()
+void CanvasToolRanges::clearRanges()
{
- selections.clear();
- selection_is_moving_left = false;
- selection_is_moving_right = false;
+ ranges.clear();
+ range_is_moving_left = false;
+ range_is_moving_right = false;
canvas->setCursor(Qt::ArrowCursor);
canvas->update();
}
-void CanvasToolSelections::setShowPreview(bool s)
+void CanvasToolRanges::setShowPreview(bool s)
{
show_preview = s;
canvas->update();
diff --git a/src/canvastoolselections.h b/src/canvastoolranges.h
index 21f00c6..164532a 100644
--- a/src/canvastoolselections.h
+++ b/src/canvastoolranges.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * canvastoolselections.h
+ * canvastoolranges.h
*
* Thu Jul 28 20:16:59 CEST 2011
* Copyright 2011 Bent Bisballe Nyeng
@@ -32,48 +32,56 @@
#include "canvas.h"
-#include "selection.h"
+#include "range.h"
-class CanvasToolSelections
+class Instrument;
+
+class CanvasToolRanges
: public CanvasTool
{
Q_OBJECT
public:
- CanvasToolSelections(Canvas* canvas, Selections& selections,
- Selections& selections_preview);
+ CanvasToolRanges(Instrument& instrument,
+ Canvas* canvas, Ranges& ranges,
+ Ranges& ranges_preview);
- QString name() { return tr("Selections"); }
+ QString name() { return tr("Ranges"); }
bool mouseMoveEvent(QMouseEvent* event);
bool mousePressEvent(QMouseEvent* event);
bool mouseReleaseEvent(QMouseEvent* event);
void paintEvent(QPaintEvent* event, QPainter& painter);
void keyReleaseEvent(QKeyEvent* event);
- //Selections selections();
+ //Ranges ranges();
+
+ void setPositionData(const float* positionData1,
+ size_t positionSize1,
+ const float* positionData2,
+ size_t positionSize2);
signals:
- //void selectionsChanged(Selections selections);
- //void activeSelectionChanged(sel_id_t id);
+ //void rangesChanged(Ranges ranges);
+ //void activeRangeChanged(sel_id_t id);
public slots:
- void autoCreateSelections();
- void autoCreateSelectionsPreview();
- void clearSelections();
- void thresholdChanged(double threshold);
+ void autoCreateRanges();
+ void autoCreateRangesPreview();
+ void clearRanges();
void noiseFloorChanged(int t);
void holdChanged(int h);
void fadeoutChanged(int f);
void setShowPreview(bool show_preview);
private:
- void doAutoCreateSelections(bool preview);
+ void doAutoCreateRanges(bool preview);
- bool selection_is_moving_left;
- bool selection_is_moving_right;
+ Instrument& instrument;
+
+ bool range_is_moving_left;
+ bool range_is_moving_right;
Canvas* canvas;
- double threshold;
double noise_floor;
double fadeout;
int hold;
@@ -85,8 +93,13 @@ private:
QColor colPreviewSelBg;
QColor colPreviewSel;
- Selections& selections;
- Selections& selections_preview;
+ Ranges& ranges;
+ Ranges& ranges_preview;
bool show_preview;
+
+ const float* positionData1{};
+ size_t positionSize1{};
+ const float* positionData2{};
+ size_t positionSize2{};
};
diff --git a/src/canvastoolthreshold.cc b/src/canvastoolthreshold.cc
index a905766..65a195b 100644
--- a/src/canvastoolthreshold.cc
+++ b/src/canvastoolthreshold.cc
@@ -27,24 +27,23 @@
#include "canvastoolthreshold.h"
#include <math.h>
+#include <iostream>
+#include "canvas.h"
#include "project.h"
-#define mapX(x) canvas->mapX(x)
-#define mapY(x) canvas->mapY(x)
-#define unmapX(x) canvas->unmapX(x)
-#define unmapY(x) canvas->unmapY(x)
+#define mapY(x) canvas.mapY(x)
+#define unmapY(x) canvas.unmapY(x)
-CanvasToolThreshold::CanvasToolThreshold(Canvas* c, Instrument& instrument)
- : instrument(instrument)
+CanvasToolThreshold::CanvasToolThreshold(Canvas& canvas, double default_value,
+ QColor color, QColor moving_color)
+ : canvas(canvas)
+ , colThreshold(color)
+ , colThresholdMoving(moving_color)
{
- canvas = c;
- threshold = instrument.getThreshold();
+ threshold = default_value;
threshold_is_moving = false;
-
- colThreshold = QColor(255, 127, 127);
- colThresholdMoving = QColor(180, 0, 0);
}
bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
@@ -60,7 +59,7 @@ bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
abs(event->y() - mapY(-threshold)) < 2 )
{
- canvas->setCursor(Qt::SplitVCursor);
+ canvas.setCursor(Qt::SplitVCursor);
return true;
}
}
@@ -73,10 +72,10 @@ bool CanvasToolThreshold::mouseMoveEvent(QMouseEvent* event)
val = 1.0;
}
threshold = fabs(val);
- canvas->update();
+ canvas.update();
emit thresholdChanging(threshold);
- instrument.setThreshold(threshold);
+ std::cout << threshold << "\n";
return true;
}
@@ -97,7 +96,7 @@ bool CanvasToolThreshold::mousePressEvent(QMouseEvent* event)
abs(event->y() - mapY(-threshold)) < 2)
{
threshold_is_moving = true;
- canvas->update();
+ canvas.update();
return true;
}
}
@@ -117,11 +116,10 @@ bool CanvasToolThreshold::mouseReleaseEvent(QMouseEvent* event)
if(threshold_is_moving)
{
threshold_is_moving = false;
- canvas->setCursor(Qt::ArrowCursor);
- canvas->update();
+ canvas.setCursor(Qt::ArrowCursor);
+ canvas.update();
emit thresholdChanged(threshold);
- instrument.setThreshold(threshold);
return true;
}
}
diff --git a/src/canvastoolthreshold.h b/src/canvastoolthreshold.h
index 936bf68..8847ecb 100644
--- a/src/canvastoolthreshold.h
+++ b/src/canvastoolthreshold.h
@@ -30,16 +30,15 @@
#include <QColor>
-#include "canvas.h"
-
-class Instrument;
+class Canvas;
class CanvasToolThreshold
: public CanvasTool
{
Q_OBJECT
public:
- CanvasToolThreshold(Canvas* canvas, Instrument& instrument);
+ CanvasToolThreshold(Canvas& canvas, double default_value,
+ QColor color, QColor moving_color);
QString name() { return tr("Threshold"); }
bool mouseMoveEvent(QMouseEvent* event);
@@ -52,13 +51,11 @@ signals:
void thresholdChanging(double threshold);
private:
- float threshold;
+ double threshold;
bool threshold_is_moving;
- Canvas* canvas;
+ Canvas& canvas;
QColor colThreshold;
QColor colThresholdMoving;
-
- Instrument& instrument;
};
diff --git a/src/detector.cc b/src/detector.cc
new file mode 100644
index 0000000..4a83659
--- /dev/null
+++ b/src/detector.cc
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * detector.cc
+ *
+ * Wed Mar 15 08:34:24 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "detector.h"
+
diff --git a/src/detector.h b/src/detector.h
new file mode 100644
index 0000000..8bd84d1
--- /dev/null
+++ b/src/detector.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * detector.h
+ *
+ * Wed Mar 15 08:34:24 CET 2023
+ * Copyright 2023 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#pragma once
+
+#include <QObject>
+
+class Detector
+ : public QObject
+{
+public slots:
+ // threshold changed (double)
+ // master file changed (float*, size)
+
+ // pos threshold changed, 1/2 (double)
+ // pos file changed, 1/2 (float*, size)
+
+signals:
+ // ranges changed
+ // pos changed, 1/2
+};
diff --git a/src/filelist.cc b/src/filelist.cc
index e1467e3..b746450 100644
--- a/src/filelist.cc
+++ b/src/filelist.cc
@@ -35,7 +35,6 @@
#include "itemeditor.h"
#include "project.h"
-#include <QAbstractItemModel>
#include <QTreeView>
#include <iostream>
@@ -43,7 +42,6 @@
#include <QComboBox>
#include <QLineEdit>
#include <QCheckBox>
-#include <QStyledItemDelegate>
#include <QPainter>
#include <QHeaderView>
#include <QStyleOptionButton>
@@ -51,378 +49,225 @@
#include <sndfile.h>
-class ChannelMapDeligate
- : public QStyledItemDelegate
+FileDataModel::FileDataModel(Instrument& instrument, FileList* fileList)
+ : instrument(instrument)
+ , fileList(fileList)
+{
+}
+
+QModelIndex FileDataModel::index(int row, int column, const QModelIndex &parent) const
{
-public:
- ChannelMapDeligate(Instrument& instrument)
- : instrument(instrument)
+ if(!hasIndex(row, column, parent))
{
+ return QModelIndex();
}
- QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
- const QModelIndex &index) const override
+ auto audiofile_ids = instrument.getAudioFileList();
+ if(!parent.isValid())
{
- // Main channel:
- if(index.column() == 2)
- {
- auto w = new QCheckBox(parent);
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w, &QCheckBox::stateChanged,
- [&audiofile](int state)
- {
- audiofile.setMainChannel(state == Qt::Checked);
- });
-
- return w;
- }
-
- // Name:
- if(index.column() == 3)
+ if(row < audiofile_ids.size())
{
- auto w = new QLineEdit(parent);
-
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w, &QLineEdit::textEdited,
- [&audiofile](const QString& name)
- {
- audiofile.setName(name);
- });
- return w;
+ return createIndex(row, column, &instrument);
}
-
- // Channel Map ID:
- if(index.column() == 4)
+ else
{
- auto w = new QComboBox(parent);
- w->addItem(tr("<None>"), -1);
- auto channel_ids = instrument.getProject().getChannelList();
- for(auto channel_id : channel_ids)
- {
- const auto& channel = instrument.getProject().getChannel(channel_id);
- w->addItem(channel.getChannelName(), channel.getId());
- }
-
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- connect(w,
- // This wierd line points the compiler to the correct overloaded
- // version of QComboBox::currentIndexChanged
- // ie. chooses the (int) version over the (const QString&) version
- QOverload<int>::of(&QComboBox::currentIndexChanged),
- [w, &audiofile](int idx)
- {
- audiofile.setChannelMapId(w->itemData(idx).toInt());
- });
- return w;
+ return QModelIndex(); // row is out of bounds.
}
-
- return QStyledItemDelegate::createEditor(parent, option, index);
}
- void setEditorData(QWidget *editor, const QModelIndex &index) const override
- {
- // Main channel:
- if(index.column() == 2)
- {
- auto w = static_cast<QCheckBox*>(editor);
- auto b = index.data(Qt::EditRole).toBool();
- w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
- }
-
- // Name:
- if(index.column() == 3)
- {
- auto w = static_cast<QLineEdit*>(editor);
- auto s = index.data(Qt::EditRole).toString();
- w->setText(s);
- }
+ return QModelIndex();
+}
- // Channel Map ID:
- if(index.column() == 4)
- {
- auto w = static_cast<QComboBox*>(editor);
- auto i = w->findData(index.data(Qt::EditRole).toInt());
- w->setCurrentIndex(i);
- }
+QModelIndex FileDataModel::parent(const QModelIndex &index) const
+{
+ return QModelIndex(); // no parent
}
- void setModelData(QWidget *editor, QAbstractItemModel *model,
- const QModelIndex &index) const override
+int FileDataModel::rowCount(const QModelIndex &parent) const
+{
+ if(parent.column() > 0) // only return row count on first column
{
- // Main channel:
- if(index.column() == 2)
- {
- model->setData(index,
- static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
- Qt::EditRole);
- }
-
- // Name:
- if(index.column() == 3)
- {
- model->setData(index, static_cast<QLineEdit*>(editor)->text(),
- Qt::EditRole);
- }
-
- // Channel Map ID:
- if(index.column() == 4)
- {
- model->setData(index, static_cast<QComboBox*>(editor)->currentData(),
- Qt::EditRole);
- }
+ return 0;
}
- void paint(QPainter* painter, const QStyleOptionViewItem& option,
- const QModelIndex& index) const override
+ if(!parent.isValid())
{
- if(index.column() == 2) // Main Channel
- {
- auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_id = audiofile_ids.begin() + index.row();
- const auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- bool checked = audiofile.getMainChannel();
- QStyleOptionButton butOpt;
- butOpt.state = QStyle::State_Enabled;
- butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
- butOpt.rect = option.rect;
- QApplication::style()->drawControl( QStyle::CE_CheckBox,
- &butOpt, painter );
- }
- else
- {
- QStyledItemDelegate::paint(painter, option, index);
- }
+ auto audiofile_ids = instrument.getAudioFileList();
+ return audiofile_ids.size(); // root level
}
-private:
- Instrument& instrument;
-};
+ return 0; // no children
+}
-class FileDataModel
- : public QAbstractItemModel
+int FileDataModel::columnCount(const QModelIndex &parent) const
{
-public:
- FileDataModel(Instrument& instrument)
- : instrument(instrument)
+ return 6;
+}
+
+QVariant FileDataModel::data(const QModelIndex &index, int role) const
+{
+ if(!index.isValid())
{
+ return QVariant();
}
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
- {
- if(!hasIndex(row, column, parent))
- {
- return QModelIndex();
- }
+ auto audiofile_ids = instrument.getAudioFileList();
- auto audiofile_ids = instrument.getAudioFileList();
- if(!parent.isValid())
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ if(role == Qt::DecorationRole )
+ {
+ if(index.column() == 0)
{
- if(row < audiofile_ids.size())
+ if(audiofile.getAbsoluteFile() == instrument.getMasterFile())
{
- return createIndex(row, column, &instrument);
+ return QPixmap(":/icons/master.png");
}
else
{
- return QModelIndex(); // row is out of bounds.
+ return QPixmap(":/icons/file.png");
}
}
-
- return QModelIndex();
- }
-
- QModelIndex parent(const QModelIndex &index) const override
- {
- return QModelIndex(); // no parent
- }
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- if(parent.column() > 0) // only return row count on first column
- {
- return 0;
- }
-
- if(!parent.isValid())
- {
- auto audiofile_ids = instrument.getAudioFileList();
- return audiofile_ids.size(); // root level
- }
-
- return 0; // no children
}
- int columnCount(const QModelIndex &parent = QModelIndex()) const override
+ if(role == Qt::DisplayRole)
{
- return 5;
- }
-
- QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if(!index.isValid())
- {
- return QVariant();
- }
-
- auto audiofile_ids = instrument.getAudioFileList();
-
- auto audiofile_id = audiofile_ids.begin() + index.row();
- const auto& audiofile = instrument.getAudioFile(*audiofile_id);
-
- if(role == Qt::DecorationRole )
- {
- if(index.column() == 0)
- {
- if(audiofile.getAbsoluteFile() == instrument.getMasterFile())
- {
- return QPixmap(":/icons/master.png");
- }
- else
- {
- return QPixmap(":/icons/file.png");
- }
- }
- }
-
- if(role == Qt::DisplayRole)
+ switch(index.column())
{
- switch(index.column())
- {
- case 0: return QVariant(); // Master
- case 1: return audiofile.getFile();
- case 2: return audiofile.getMainChannel() ? "x" : " ";
- case 3: return audiofile.getName();
- case 4:
- {
- auto channelMapId = audiofile.getChannelMapId();
- if(channelMapId == -1)
- {
- return tr("<None>");
- }
- return instrument.getProject().getChannel(channelMapId).getChannelName();
- }
- default: return QVariant();
- }
- }
- else if(role == Qt::EditRole)
+ case 0: return QVariant(); // Master
+ case 1: return audiofile.getFile();
+ case 2: return audiofile.getMainChannel() ? "x" : " ";
+ case 3: return audiofile.getName();
+ case 4:
{
- switch(index.column())
+ auto channelMapId = audiofile.getChannelMapId();
+ if(channelMapId == -1)
{
- case 0: return QVariant(); // Master
- case 1: return audiofile.getFile();
- case 2: return audiofile.getMainChannel();
- case 3: return audiofile.getName();
- case 4: return audiofile.getChannelMapId();
- default: return QVariant();
+ return tr("<None>");
}
+ return instrument.getProject().getChannel(channelMapId).getChannelName();
}
- else
-
- {
- return QVariant();
+ case 5: return audiofile.getPositionChannel() ? "x" : " ";
+ default: return QVariant();
}
}
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override
+ else if(role == Qt::EditRole)
{
- if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ switch(index.column())
{
- switch(section)
- {
- case 0: return tr("M");
- case 1: return tr("Filename");
- case 2: return tr("m");
- case 3: return tr("Name");
- case 4: return tr("Kit Channel");
- default: return QVariant();
- }
+ case 0: return QVariant(); // Master
+ case 1: return audiofile.getFile();
+ case 2: return audiofile.getMainChannel();
+ case 3: return audiofile.getName();
+ case 4: return audiofile.getChannelMapId();
+ case 5: return audiofile.getPositionChannel();
+ default: return QVariant();
}
+ }
+ else
+ {
return QVariant();
}
+}
- Qt::ItemFlags flags(const QModelIndex &index) const override
+QVariant FileDataModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
{
- if(!index.isValid())
+ switch(section)
{
- return 0;
- }
-
- switch(index.column())
- {
- case 0: // Master
- return QAbstractItemModel::flags(index);
- case 1: // File
- return QAbstractItemModel::flags(index);
- case 2: // Main channel
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
- case 3: // Name
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
- case 4: // Channel map id
- return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 0: return tr("M");
+ case 1: return tr("Filename");
+ case 2: return tr("m");
+ case 3: return tr("Name");
+ case 4: return tr("Kit Channel");
+ case 5: return tr("p");
+ default: return QVariant();
}
}
- bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole) override
+ return QVariant();
+}
+
+Qt::ItemFlags FileDataModel::flags(const QModelIndex &index) const
+{
+ if(!index.isValid())
{
- auto audiofile_ids = instrument.getAudioFileList();
+ return 0;
+ }
- if(index.row() > audiofile_ids.size() ||
- index.column() > (columnCount() - 1))
- {
- return false;
- }
+ switch(index.column())
+ {
+ case 0: // Master
+ return QAbstractItemModel::flags(index);
+ case 1: // File
+ return QAbstractItemModel::flags(index);
+ case 2: // Main channel
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 3: // Name
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 4: // Channel map id
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ case 5: // Pos channel
+ return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
+ }
- auto audiofile_id = audiofile_ids.begin() + index.row();
- auto& audiofile = instrument.getAudioFile(*audiofile_id);
+ return 0;
+}
- switch(index.column())
- {
- case 0: // Master
- break;
- case 1: // File
- break;
- case 2: // Main Channel
- audiofile.setMainChannel(value.toBool());
- break;
- case 3: // Name
- audiofile.setName(value.toString());
- break;
- case 4: // Channel map id
- audiofile.setChannelMapId(value.toInt());
- break;
- default: break;
- }
+bool FileDataModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ auto audiofile_ids = instrument.getAudioFileList();
- return true;
+ if(index.row() > audiofile_ids.size() ||
+ index.column() > (columnCount() - 1))
+ {
+ return false;
}
- void refresh()
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ switch(index.column())
{
- beginResetModel();
- endResetModel();
+ case 0: // Master
+ break;
+ case 1: // File
+ break;
+ case 2: // Main Channel
+ audiofile.setMainChannel(value.toBool());
+ break;
+ case 3: // Name
+ audiofile.setName(value.toString());
+ break;
+ case 4: // Channel map id
+ audiofile.setChannelMapId(value.toInt());
+ break;
+ case 5: // Pos Channel
+ audiofile.setPositionChannel(value.toBool());
+ fileList->positionFilesChanged();
+ break;
+ default: break;
}
-private:
- Instrument& instrument;
-};
+ return true;
+}
+
+void FileDataModel::refresh()
+{
+ beginResetModel();
+ endResetModel();
+}
+
FileList::FileList(Instrument& instrument)
: instrument(instrument)
{
- model = new FileDataModel(instrument);
+ model = new FileDataModel(instrument, this);
setModel(model);
- setItemDelegate(new ChannelMapDeligate(instrument));
+ setItemDelegate(new ChannelMapDeligate(instrument, this));
setEditTriggers(QAbstractItemView::AllEditTriggers); // show list on click
setContextMenuPolicy(Qt::CustomContextMenu); // enable context menu
@@ -584,3 +429,202 @@ void FileList::removeAllFiles()
emit masterFileChanged(""); // Clear canvas
emit allFilesRemoved();
}
+
+
+ChannelMapDeligate::ChannelMapDeligate(Instrument& instrument, FileList* fileList)
+ : instrument(instrument)
+ , fileList(fileList)
+{
+}
+
+QWidget* ChannelMapDeligate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ auto w = new QCheckBox(parent);
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QCheckBox::stateChanged,
+ [&audiofile](int state)
+ {
+ audiofile.setMainChannel(state == Qt::Checked);
+ });
+
+ return w;
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ auto w = new QLineEdit(parent);
+
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QLineEdit::textEdited,
+ [&audiofile](const QString& name)
+ {
+ audiofile.setName(name);
+ });
+ return w;
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ auto w = new QComboBox(parent);
+ w->addItem(tr("<None>"), -1);
+ auto channel_ids = instrument.getProject().getChannelList();
+ for(auto channel_id : channel_ids)
+ {
+ const auto& channel = instrument.getProject().getChannel(channel_id);
+ w->addItem(channel.getChannelName(), channel.getId());
+ }
+
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w,
+ // This wierd line points the compiler to the correct overloaded
+ // version of QComboBox::currentIndexChanged
+ // ie. chooses the (int) version over the (const QString&) version
+ QOverload<int>::of(&QComboBox::currentIndexChanged),
+ [w, &audiofile](int idx)
+ {
+ audiofile.setChannelMapId(w->itemData(idx).toInt());
+ });
+ return w;
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ auto w = new QCheckBox(parent);
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ connect(w, &QCheckBox::stateChanged,
+ [&](int state)
+ {
+ audiofile.setPositionChannel(state == Qt::Checked);
+ fileList->positionFilesChanged();
+ });
+
+ return w;
+ }
+
+ return QStyledItemDelegate::createEditor(parent, option, index);
+}
+
+void ChannelMapDeligate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ auto w = static_cast<QCheckBox*>(editor);
+ auto b = index.data(Qt::EditRole).toBool();
+ w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ auto w = static_cast<QLineEdit*>(editor);
+ auto s = index.data(Qt::EditRole).toString();
+ w->setText(s);
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ auto w = static_cast<QComboBox*>(editor);
+ auto i = w->findData(index.data(Qt::EditRole).toInt());
+ w->setCurrentIndex(i);
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ auto w = static_cast<QCheckBox*>(editor);
+ auto b = index.data(Qt::EditRole).toBool();
+ w->setCheckState(b ? Qt::Checked : Qt::Unchecked);
+ }
+}
+
+void ChannelMapDeligate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ // Main channel:
+ if(index.column() == 2)
+ {
+ model->setData(index,
+ static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
+ Qt::EditRole);
+ }
+
+ // Name:
+ if(index.column() == 3)
+ {
+ model->setData(index, static_cast<QLineEdit*>(editor)->text(),
+ Qt::EditRole);
+ }
+
+ // Channel Map ID:
+ if(index.column() == 4)
+ {
+ model->setData(index, static_cast<QComboBox*>(editor)->currentData(),
+ Qt::EditRole);
+ }
+
+ // Pos channel:
+ if(index.column() == 5)
+ {
+ model->setData(index,
+ static_cast<QCheckBox*>(editor)->checkState() == Qt::Checked,
+ Qt::EditRole);
+ }
+}
+
+void ChannelMapDeligate::paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const
+{
+ if(index.column() == 2) // Main Channel
+ {
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ bool checked = audiofile.getMainChannel();
+ QStyleOptionButton butOpt;
+ butOpt.state = QStyle::State_Enabled;
+ butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
+ butOpt.rect = option.rect;
+ QApplication::style()->drawControl( QStyle::CE_CheckBox,
+ &butOpt, painter );
+ }
+ else if(index.column() == 5) // Pos Channel
+ {
+ auto audiofile_ids = instrument.getAudioFileList();
+ auto audiofile_id = audiofile_ids.begin() + index.row();
+ const auto& audiofile = instrument.getAudioFile(*audiofile_id);
+
+ bool checked = audiofile.getPositionChannel();
+ QStyleOptionButton butOpt;
+ butOpt.state = QStyle::State_Enabled;
+ butOpt.state |= checked ? QStyle::State_On : QStyle::State_Off;
+ butOpt.rect = option.rect;
+ QApplication::style()->drawControl( QStyle::CE_CheckBox,
+ &butOpt, painter );
+ }
+ else
+ {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+}
diff --git a/src/filelist.h b/src/filelist.h
index 165af83..af0d40a 100644
--- a/src/filelist.h
+++ b/src/filelist.h
@@ -29,9 +29,41 @@
#include <QTreeView>
#include <QAction>
#include <QMenu>
+#include <QStyledItemDelegate>
+#include <QAbstractItemModel>
class Instrument;
-class FileDataModel;
+class FileList;
+
+class FileDataModel
+ : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ FileDataModel(Instrument& instrument, FileList* fileList);
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex &index) const override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const override;
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole) override;
+
+ void refresh();
+
+private:
+ Instrument& instrument;
+ FileList* fileList;
+};
class FileList
: public QTreeView
@@ -44,6 +76,7 @@ public:
signals:
void masterFileChanged(QString filename);
+ void positionFilesChanged();
// void fileAdded(QString file, QString name);
void fileRemoved(QString file, QString name);
void allFilesRemoved();
@@ -83,3 +116,26 @@ private:
Instrument& instrument;
FileDataModel* model;
};
+
+class ChannelMapDeligate
+ : public QStyledItemDelegate
+{
+ Q_OBJECT
+public:
+ ChannelMapDeligate(Instrument& instrument, FileList* fileList);
+
+ QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const override;
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const override;
+
+ void paint(QPainter* painter, const QStyleOptionViewItem& option,
+ const QModelIndex& index) const override;
+
+private:
+ Instrument& instrument;
+ FileList* fileList;
+};
diff --git a/src/instrumentwidget.cc b/src/instrumentwidget.cc
index 6a2e17e..42b549b 100644
--- a/src/instrumentwidget.cc
+++ b/src/instrumentwidget.cc
@@ -47,11 +47,13 @@
#include <QTime>
#include <QSpinBox>
+#include <sndfile.h>
+
#include "sleep.h"
#include "canvastool.h"
#include "canvastoolthreshold.h"
#include "volumefader.h"
-#include "selectioneditor.h"
+#include "rangeeditor.h"
#include "zoomslider.h"
#include "settings.h"
#include "project.h"
@@ -74,11 +76,11 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
{
setProperty("id", instrument.getId());
- {
- int start = 44100 * 60;
- Selection p(start, start + 44100 * 60, 0, 0); // one minute selection
- selections_preview.add(p);
- }
+ //{
+ // int start = 44100 * 60;
+ // Range p(start, start + 44100 * 60, 0, 0); // one minute range
+ // ranges_preview.add(p);
+ //}
QWidget* central = new QWidget();
QHBoxLayout* lh = new QHBoxLayout();
@@ -92,32 +94,66 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
QToolBar* toolbar = addToolBar(tr("Tools"));
listen = new CanvasToolListen(canvaswidget->canvas, player);
addTool(toolbar, canvaswidget->canvas, listen);
- threshold = new CanvasToolThreshold(canvaswidget->canvas, instrument);
+
+ threshold = new CanvasToolThreshold(*canvaswidget->canvas,
+ instrument.getThreshold(),
+ QColor(255, 127, 127),
+ QColor(180, 0, 0));
+
+ pos_threshold = new CanvasToolThreshold(*canvaswidget->canvas,
+ instrument.getPositionThreshold(),
+ QColor(127, 127, 255),
+ QColor(0, 0, 180));
+
canvaswidget->canvas->tools.push_back(threshold);
- tool_selections = new CanvasToolSelections(canvaswidget->canvas, selections,
- selections_preview);
- connect(threshold, SIGNAL(thresholdChanged(double)),
- tool_selections, SLOT(thresholdChanged(double)));
+ canvaswidget->canvas->tools.push_back(pos_threshold);
+
+ tool_ranges = new CanvasToolRanges(instrument,
+ canvaswidget->canvas, ranges,
+ ranges_preview);
+
+ tool_position = new CanvasToolPosition(instrument,
+ *canvaswidget->canvas, ranges,
+ ranges_preview);
+
+ connect(&instrument, SIGNAL(rangesChanged()),
+ tool_position, SLOT(rangesChanged()));
+
+ connect(&instrument, SIGNAL(thresholdChanged()),
+ tool_ranges, SLOT(autoCreateRangesPreview()));
+
+ connect(&instrument, SIGNAL(positionThresholdChanged()),
+ tool_ranges, SLOT(autoCreateRangesPreview()));
+
connect(threshold, SIGNAL(thresholdChanging(double)),
- tool_selections, SLOT(thresholdChanged(double)));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ &instrument, SLOT(setThreshold(double)));
+ connect(threshold, SIGNAL(thresholdChanged(double)),
+ &instrument, SLOT(setThreshold(double)));
+
+ connect(pos_threshold, SIGNAL(thresholdChanging(double)),
+ &instrument, SLOT(setPositionThreshold(double)));
+ connect(pos_threshold, SIGNAL(thresholdChanged(double)),
+ &instrument, SLOT(setPositionThreshold(double)));
+
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
canvaswidget->canvas, SLOT(update()));
- connect(&selections, SIGNAL(updated(sel_id_t)),
+ connect(&ranges, SIGNAL(updated(sel_id_t)),
canvaswidget->canvas, SLOT(update()));
- addTool(toolbar, canvaswidget->canvas, tool_selections);
-
- sorter = new SampleSorter(selections, selections_preview, instrument);
- connect(&selections, SIGNAL(added(sel_id_t)),
- sorter, SLOT(addSelection(sel_id_t)));
- connect(&selections_preview, SIGNAL(added(sel_id_t)),
- sorter, SLOT(addSelectionPreview(sel_id_t)));
- connect(&selections, SIGNAL(updated(sel_id_t)), sorter, SLOT(relayout()));
- connect(&selections_preview, SIGNAL(updated(sel_id_t)),
+ addTool(toolbar, canvaswidget->canvas, tool_ranges);
+ addTool(toolbar, canvaswidget->canvas, tool_position);
+
+ sorter = new SampleSorter(ranges, ranges_preview, instrument);
+ connect(&ranges, SIGNAL(added(sel_id_t)),
+ sorter, SLOT(addRange(sel_id_t)));
+ connect(&ranges_preview, SIGNAL(added(sel_id_t)),
+ sorter, SLOT(addRangePreview(sel_id_t)));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), sorter, SLOT(relayout()));
+ connect(&ranges_preview, SIGNAL(updated(sel_id_t)),
sorter, SLOT(relayout()));
- connect(&selections, SIGNAL(removed(sel_id_t)), sorter, SLOT(relayout()));
- connect(&selections_preview, SIGNAL(removed(sel_id_t)),
+ connect(&ranges, SIGNAL(removed(sel_id_t)), sorter, SLOT(relayout()));
+ connect(&ranges_preview, SIGNAL(removed(sel_id_t)),
sorter, SLOT(relayout()));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
sorter, SLOT(relayout()));
QPushButton* btn_playsamples = new QPushButton(tr("Play samples"));
@@ -142,11 +178,11 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
dockWidget->widget()->setLayout(new QVBoxLayout());
tabs = new QTabWidget(this);
- tabs->setMinimumWidth(350);
+ tabs->setMinimumWidth(416);
tabs->addTab(createFilesTab(), tr("Files"));
generateTabId = tabs->addTab(createGenerateTab(), tr("Generate"));
tabs->addTab(createEditTab(), tr("Edit"));
- //tabs->addTab(createExportTab(), tr("Export"));
+ tabs->addTab(createExportTab(), tr("Export"));
connect(tabs, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)));
tabChanged(tabs->currentIndex());
@@ -168,8 +204,9 @@ InstrumentWidget::InstrumentWidget(Settings& settings, Instrument& instrument)
canvaswidget->xscale->setValue(0);
canvaswidget->xoffset->setValue(0);
- // Update selections according to threshold
- tool_selections->thresholdChanged(instrument.getThreshold());
+ // Update ranges according to threshold
+// tool_ranges->thresholdChanged(instrument.getThreshold());
+ recalcPositions();
}
InstrumentWidget::~InstrumentWidget()
@@ -178,10 +215,12 @@ InstrumentWidget::~InstrumentWidget()
void InstrumentWidget::tabChanged(int tabid)
{
- tool_selections->setShowPreview(tabid == generateTabId);
+ tool_ranges->setShowPreview(tabid == generateTabId);
+ tool_position->setShowPreview(tabid == generateTabId);
sorter->setShowPreview(tabid == generateTabId);
- tool_selections->autoCreateSelectionsPreview();
+ tool_ranges->autoCreateRangesPreview();
threshold->setActive(tabid == generateTabId);
+ pos_threshold->setActive(tabid == generateTabId); // TODO && current waveform is pos
}
QWidget* InstrumentWidget::createFilesTab()
@@ -198,6 +237,8 @@ QWidget* InstrumentWidget::createFilesTab()
filelist = new FileList(instrument);
connect(filelist, SIGNAL(masterFileChanged(QString)),
this, SLOT(loadFile(QString)));
+ connect(filelist, SIGNAL(positionFilesChanged()),
+ this, SLOT(recalcPositions()));
connect(loadbtn, SIGNAL(clicked()), filelist, SLOT(addFiles()));
l->addWidget(filelist);
@@ -211,26 +252,26 @@ QWidget* InstrumentWidget::createFilesTab()
QWidget* InstrumentWidget::createEditTab()
{
- selections = instrument.getSelections();
- SelectionEditor* se = new SelectionEditor(selections, instrument);
+ ranges = instrument.getRanges();
+ RangeEditor* se = new RangeEditor(ranges, instrument);
- connect(&selections, SIGNAL(added(sel_id_t)), se, SLOT(added(sel_id_t)));
- connect(&selections, SIGNAL(updated(sel_id_t)), se, SLOT(updated(sel_id_t)));
- connect(&selections, SIGNAL(removed(sel_id_t)), se, SLOT(removed(sel_id_t)));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)),
+ connect(&ranges, SIGNAL(added(sel_id_t)), se, SLOT(added(sel_id_t)));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), se, SLOT(updated(sel_id_t)));
+ connect(&ranges, SIGNAL(removed(sel_id_t)), se, SLOT(removed(sel_id_t)));
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)),
se, SLOT(activeChanged(sel_id_t)));
- connect(&selections, SIGNAL(added(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(updated(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(removed(sel_id_t)), this, SLOT(selectionChanged()));
- connect(&selections, SIGNAL(activeChanged(sel_id_t)), this, SLOT(selectionChanged()));
+ connect(&ranges, SIGNAL(added(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(updated(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(removed(sel_id_t)), this, SLOT(rangeChanged()));
+ connect(&ranges, SIGNAL(activeChanged(sel_id_t)), this, SLOT(rangeChanged()));
return se;
}
-void InstrumentWidget::selectionChanged()
+void InstrumentWidget::rangeChanged()
{
- instrument.setSelections(selections);
+ instrument.setRanges(ranges);
}
static QSlider* createAttribute(QWidget* parent, QString name,
@@ -271,19 +312,14 @@ QWidget* InstrumentWidget::createGenerateTab()
QPushButton* autosel = new QPushButton();
autosel->setText(tr("Generate"));
connect(autosel, SIGNAL(clicked()),
- tool_selections, SLOT(clearSelections()));
+ tool_ranges, SLOT(clearRanges()));
connect(autosel, SIGNAL(clicked()),
- tool_selections, SLOT(autoCreateSelections()));
-
- connect(threshold, SIGNAL(thresholdChanged(double)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
- connect(threshold, SIGNAL(thresholdChanging(double)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRanges()));
QPushButton* clearsel = new QPushButton();
clearsel->setText(tr("Clear"));
connect(clearsel, SIGNAL(clicked()),
- tool_selections, SLOT(clearSelections()));
+ tool_ranges, SLOT(clearRanges()));
btns->addWidget(autosel);
btns->addWidget(clearsel);
@@ -294,7 +330,7 @@ QWidget* InstrumentWidget::createGenerateTab()
connect(slider_attacklength, SIGNAL(valueChanged(int)),
sorter, SLOT(setAttackLength(int)));
connect(slider_attacklength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_attacklength->setValue(instrument.getAttackLength());
connect(slider_attacklength, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
@@ -303,34 +339,34 @@ QWidget* InstrumentWidget::createGenerateTab()
connect(slider_spread, SIGNAL(valueChanged(int)),
sorter, SLOT(setSpreadFactor(int)));
connect(slider_spread, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_spread->setValue(instrument.getPowerSpread());
connect(slider_spread, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_hold = createAttribute(w, tr("Minimum size (samples):"), 0, 200000);
connect(slider_hold, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(holdChanged(int)));
+ tool_ranges, SLOT(holdChanged(int)));
connect(slider_hold, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_hold->setValue(instrument.getMinimumSize());
connect(slider_hold, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_falloff = createAttribute(w, tr("Falloff:"), 10, 5000);
connect(slider_falloff, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(noiseFloorChanged(int)));
+ tool_ranges, SLOT(noiseFloorChanged(int)));
connect(slider_falloff, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_falloff->setValue(instrument.getFalloff());
connect(slider_falloff, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
slider_fadelength = createAttribute(w, tr("Fadelength:"), 0, 2000);
connect(slider_fadelength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(fadeoutChanged(int)));
+ tool_ranges, SLOT(fadeoutChanged(int)));
connect(slider_fadelength, SIGNAL(valueChanged(int)),
- tool_selections, SLOT(autoCreateSelectionsPreview()));
+ tool_ranges, SLOT(autoCreateRangesPreview()));
slider_fadelength->setValue(instrument.getFadeLength());
connect(slider_fadelength, SIGNAL(valueChanged(int)),
this, SLOT(generateSlidersChanged()));
@@ -362,7 +398,7 @@ QWidget* InstrumentWidget::createExportTab()
connect(prefix, SIGNAL(textChanged(const QString &)),
this, SLOT(prefixChanged()));
l->addWidget(prefix);
-
+/*
l->addWidget(new QLabel(tr("Export path:")));
QHBoxLayout* lo_exportp = new QHBoxLayout();
lineed_exportp = new QLineEdit();
@@ -386,7 +422,7 @@ QWidget* InstrumentWidget::createExportTab()
connect(extractor, SIGNAL(setMaximumProgress(int)),
bar, SLOT(setMaximum(int)));
l->addWidget(bar);
-
+*/
l->addStretch();
return w;
@@ -404,10 +440,10 @@ void InstrumentWidget::exportPathChanged()
void InstrumentWidget::playSamples()
{
- Selections* sels = &selections;
+ Ranges* sels = &ranges;
if(tabs->currentIndex() == generateTabId)
{
- sels = &selections_preview;
+ sels = &ranges_preview;
}
QVector<sel_id_t> ids = sels->ids();
@@ -415,8 +451,8 @@ void InstrumentWidget::playSamples()
{
for(int v2 = 0; v2 < ids.size(); v2++)
{
- Selection sel1 = sels->get(ids[v1]);
- Selection sel2 = sels->get(ids[v2]);
+ Range sel1 = sels->get(ids[v1]);
+ Range sel2 = sels->get(ids[v2]);
if(sel1.energy < sel2.energy)
{
@@ -430,7 +466,7 @@ void InstrumentWidget::playSamples()
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = sels->get(*i);
+ Range sel = sels->get(*i);
unsigned int length = sb_playsamples->value() * 44100 / 1000;
@@ -448,7 +484,7 @@ void InstrumentWidget::playSamples()
connect(&player, SIGNAL(positionUpdate(size_t)),
listen, SLOT(update(size_t)));
- player.playSelection(sel, to - sel.from);
+ player.playRange(sel, to - sel.from);
QTime t;
t.start();
while(t.elapsed() < sb_playsamples->value())
@@ -466,7 +502,7 @@ void InstrumentWidget::playSamples()
void InstrumentWidget::doExport()
{
- extractor->exportSelections();
+ extractor->exportRanges();
}
void InstrumentWidget::loadFile(QString filename)
@@ -475,8 +511,8 @@ void InstrumentWidget::loadFile(QString filename)
statusBar()->showMessage(tr("Loading..."));
qApp->processEvents();
- sorter->setWavData(NULL, 0);
- player.setPcmData(NULL, 0, 0);
+ sorter->setWavData(nullptr, 0);
+ player.setPcmData(nullptr, 0, 0);
canvaswidget->canvas->load(filename);
@@ -489,6 +525,103 @@ void InstrumentWidget::loadFile(QString filename)
instrument.setMasterFile(filename);
}
+void InstrumentWidget::recalcPositions()
+{
+ size_t cnt{0};
+ QString file[2];
+ for(auto audioFileIdx : instrument.getAudioFileList())
+ {
+ auto& audioFile = instrument.getAudioFile(audioFileIdx);
+ if(audioFile.getPositionChannel())
+ {
+ file[cnt] = audioFile.getAbsoluteFile();
+ cnt++;
+ }
+
+ if(cnt == 2)
+ {
+ break;
+ }
+ }
+
+ if(cnt != 2)
+ {
+ return; // we need precisely two position files for this to work
+ }
+
+ //TODO: Load pos files and set data on sample sorter
+ {
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(file[0].toStdString().c_str(), SFM_READ, &sf_info);
+ if(!fh)
+ {
+ printf("Load error '%s'\n", file[0].toStdString().c_str());
+ // Just clear the canvas
+ return;
+ }
+
+ positionSize1 = sf_info.frames;
+ if(positionData1)
+ {
+ delete[] positionData1;
+ }
+ positionData1 = new float[positionSize1];
+
+ sf_read_float(fh, positionData1, positionSize1);
+
+ sf_close(fh);
+ }
+
+ {
+ SF_INFO sf_info;
+ SNDFILE *fh = sf_open(file[1].toStdString().c_str(), SFM_READ, &sf_info);
+ if(!fh)
+ {
+ printf("Load error '%s'\n", file[1].toStdString().c_str());
+ // Just clear the canvas
+ return;
+ }
+
+ positionSize2 = sf_info.frames;
+ if(positionData2)
+ {
+ delete[] positionData2;
+ }
+ positionData2 = new float[positionSize2];
+
+ sf_read_float(fh, positionData2, positionSize2);
+
+ sf_close(fh);
+ }
+
+#if 0
+ // Lowpass filter with runnig avarage
+ float p = 0.999;
+ {
+ float running{0};
+ for(int i = 0; i < positionSize1; ++i)
+ {
+ running = running * (1.0f - p) + positionData1[i] * p;
+ positionData1[i] = running;
+ }
+ }
+
+ {
+ float running{0};
+ for(int i = 0; i < positionSize2; ++i)
+ {
+ running = running * (1.0f - p) + positionData2[i] * p;
+ positionData2[i] = running;
+ }
+ }
+#endif
+
+ sorter->setPositionData(positionData1, positionSize1,
+ positionData2, positionSize2);
+ tool_ranges->setPositionData(positionData1, positionSize1,
+ positionData2, positionSize2);
+}
+
void InstrumentWidget::browse()
{
QString path =
diff --git a/src/instrumentwidget.h b/src/instrumentwidget.h
index 721b829..d3678d2 100644
--- a/src/instrumentwidget.h
+++ b/src/instrumentwidget.h
@@ -38,10 +38,11 @@
#include "audioextractor.h"
#include "samplesorter.h"
#include "filelist.h"
-#include "canvastoolselections.h"
+#include "canvastoolranges.h"
+#include "canvastoolposition.h"
#include "canvastoolthreshold.h"
#include "canvastoollisten.h"
-#include "selection.h"
+#include "range.h"
#include "player.h"
#include "zoomslider.h"
#include "canvaswidget.h"
@@ -70,11 +71,12 @@ public:
public slots:
void doExport();
void loadFile(QString filename);
+ void recalcPositions();
void playSamples();
void browse();
void tabChanged(int tabid);
void generateSlidersChanged();
- void selectionChanged();
+ void rangeChanged();
void prefixChanged();
void exportPathChanged();
@@ -87,8 +89,10 @@ private:
int generateTabId;
SampleSorter* sorter;
- CanvasToolSelections* tool_selections;
+ CanvasToolRanges* tool_ranges;
+ CanvasToolPosition* tool_position;
CanvasToolThreshold* threshold;
+ CanvasToolThreshold* pos_threshold;
CanvasToolListen* listen;
AudioExtractor* extractor;
FileList* filelist;
@@ -108,10 +112,16 @@ private:
QTabWidget* tabs;
// Session state information:
- Selections selections;
- Selections selections_preview;
+ Ranges ranges;
+ Ranges ranges_preview;
Player player;
Settings& settings;
Instrument& instrument;
+
+ // TODO: These should not be stored here...
+ float* positionData1{nullptr};
+ size_t positionSize1{0};
+ float* positionData2{nullptr};
+ size_t positionSize2{0};
};
diff --git a/src/player.cc b/src/player.cc
index d598d9f..a3eeaa2 100644
--- a/src/player.cc
+++ b/src/player.cc
@@ -38,7 +38,7 @@ Player::Player()
pcm_data = NULL;
pcm_size = 0;
end = 0;
- new_selection = false;
+ new_range = false;
connect(&report_timer, SIGNAL(timeout()), this, SLOT(reportTimeout()));
report_timer.start(50); // Update 25 times per second
@@ -55,7 +55,7 @@ Player::~Player()
#define _MIN(a, b) (a<b?a:b)
void Player::run()
{
- Selection sel;
+ Range sel;
static int init = 0;
if(init == 0)
@@ -79,14 +79,14 @@ void Player::run()
while(running)
{
{
- // Check for new Selection.
+ // Check for new Range.
QMutexLocker lock(&mutex);
- if(new_selection)
+ if(new_range)
{
- sel = selection;
+ sel = range;
pos = sel.from;
end = sel_end;
- new_selection = false;
+ new_range = false;
}
}
@@ -134,18 +134,18 @@ void Player::run()
}
}
-bool Player::playSelectionDone()
+bool Player::playRangeDone()
{
- return pos >= sel_end || pos >= selection.to;
+ return pos >= sel_end || pos >= range.to;
}
-void Player::playSelection(Selection s, int len)
+void Player::playRange(Range s, int len)
{
{
- // Enqueue new Selection for player consumation
+ // Enqueue new Range for player consumation
QMutexLocker lock(&mutex);
- selection = s;
+ range = s;
if(len > 0)
{
@@ -153,16 +153,16 @@ void Player::playSelection(Selection s, int len)
}
else
{
- sel_end = selection.to - selection.from;
+ sel_end = range.to - range.from;
}
- sel_end += selection.from;
+ sel_end += range.from;
- new_selection = true;
+ new_range = true;
}
- // Wait until player actually consumed the new Selection.
- while(new_selection)
+ // Wait until player actually consumed the new Range.
+ while(new_range)
{
msleep(1);
}
@@ -197,20 +197,20 @@ void Player::setPcmData(float* data, size_t size, double samplerate)
void Player::setPosition(size_t position)
{
- Selection s;
+ Range s;
s.from = position;
s.to = pcm_size;
s.fadein = 0;
s.fadeout = 0;
- playSelection(s);
+ playRange(s);
}
void Player::stop()
{
- Selection s;
+ Range s;
s.from = 0;
s.to = 0;
s.fadein = 0;
s.fadeout = 0;
- playSelection(s, pos);
+ playRange(s, pos);
}
diff --git a/src/player.h b/src/player.h
index 0f5b780..9bc03b7 100644
--- a/src/player.h
+++ b/src/player.h
@@ -32,7 +32,7 @@
#include <ao/ao.h>
-#include "selection.h"
+#include "range.h"
class Player
: public QThread
@@ -67,12 +67,12 @@ public slots:
//! Set player position as sample offset.
void setPosition(size_t position);
- //! Play range based on selection including fade-in/out.
+ //! Play range based on range including fade-in/out.
//! \param length Stop playing after length samples. -1 means play all.
- void playSelection(Selection selection, int length = -1);
+ void playRange(Range range, int length = -1);
- //! Return true if last selection is done playing.
- bool playSelectionDone();
+ //! Return true if last range is done playing.
+ bool playRangeDone();
//! Stop playing
void stop();
@@ -105,7 +105,7 @@ private:
bool running;
QMutex mutex;
- volatile bool new_selection;
+ volatile bool new_range;
size_t sel_end;
- Selection selection;
+ Range range;
};
diff --git a/src/project.cc b/src/project.cc
index 9cac537..bc96e07 100644
--- a/src/project.cc
+++ b/src/project.cc
@@ -127,8 +127,27 @@ void AudioFile::setMainChannel(bool main_channel)
}
}
+bool AudioFile::getPositionChannel() const
+{
+ return pos_channel;
+}
+
+void AudioFile::setPositionChannel(bool pos_channel)
+{
+ if(this->pos_channel == pos_channel)
+ {
+ return;
+ }
+
+ {
+ Project::RAIIBulkUpdate bulkUpdate(instrument.getProject());
+ this->pos_channel = pos_channel;
+ }
+}
+
Instrument::Instrument(Project& project, int id)
- : id(id)
+ : QObject(nullptr)
+ , id(id)
, project(project)
{
}
@@ -317,12 +336,12 @@ void Instrument::setFadeLength(std::size_t fade_length)
}
}
-float Instrument::getThreshold() const
+double Instrument::getThreshold() const
{
return threshold;
}
-void Instrument::setThreshold(float threshold)
+void Instrument::setThreshold(double threshold)
{
if(this->threshold == threshold)
{
@@ -333,19 +352,42 @@ void Instrument::setThreshold(float threshold)
Project::RAIIBulkUpdate bulkUpdate(project);
this->threshold = threshold;
}
+
+ emit thresholdChanged();
}
-Selections Instrument::getSelections() const
+double Instrument::getPositionThreshold() const
{
- return selections;
+ return position_threshold;
}
-void Instrument::setSelections(const Selections& selections)
+void Instrument::setPositionThreshold(double position_threshold)
{
+ std::cout << __PRETTY_FUNCTION__ << std::endl;
+ std::cout << position_threshold << std::endl;
+ if(this->position_threshold == position_threshold)
+ {
+ return;
+ }
+
{
Project::RAIIBulkUpdate bulkUpdate(project);
- this->selections = selections;
+ this->position_threshold = position_threshold;
}
+
+ emit positionThresholdChanged();
+}
+
+Ranges Instrument::getRanges() const
+{
+ return ranges;
+}
+
+void Instrument::setRanges(const Ranges& ranges)
+{
+ Project::RAIIBulkUpdate bulkUpdate(project);
+ this->ranges = ranges;
+ emit rangesChanged();
}
QString Instrument::getPrefix() const
diff --git a/src/project.h b/src/project.h
index 3e2b886..bbc7771 100644
--- a/src/project.h
+++ b/src/project.h
@@ -26,13 +26,14 @@
*/
#pragma once
-#include <list>
+#include "audioextractor.h"
+#include "range.h"
#include <QObject>
#include <QString>
-#include "audioextractor.h"
-#include "selection.h"
+#include <list>
+#include <array>
class Project;
class Instrument;
@@ -57,6 +58,9 @@ public:
bool getMainChannel() const;
void setMainChannel(bool main);
+ bool getPositionChannel() const;
+ void setPositionChannel(bool pos);
+
private:
friend class ProjectSerialiser;
@@ -64,15 +68,19 @@ private:
QString name;
int channel_map_id;
bool main_channel;
+ bool pos_channel{false};
int id;
Instrument& instrument;
};
class Instrument
+ : public QObject
{
+ Q_OBJECT
public:
Instrument(Project& project, int id);
+ virtual ~Instrument() = default;
int getId() const;
@@ -102,17 +110,26 @@ public:
std::size_t getFadeLength() const;
void setFadeLength(std::size_t fade_length);
- float getThreshold() const;
- void setThreshold(float threshold);
+ double getThreshold() const;
+ double getPositionThreshold() const;
- Selections getSelections() const;
- void setSelections(const Selections& selectios);
+ Ranges getRanges() const;
+ void setRanges(const Ranges& ranges);
QString getPrefix() const;
void setPrefix(const QString& prefix);
Project& getProject();
+public slots:
+ void setThreshold(double threshold);
+ void setPositionThreshold(double threshold);
+
+signals:
+ void thresholdChanged();
+ void positionThresholdChanged();
+ void rangesChanged();
+
private:
friend class ProjectSerialiser;
@@ -131,10 +148,11 @@ private:
std::size_t fade_length{666};
// Canvas
- float threshold{0.5f};
+ double threshold{0.1};
+ double position_threshold{0.1f};
// Edit tab
- Selections selections;
+ Ranges ranges;
// Export tab
QString prefix;
diff --git a/src/projectrenderer.cc b/src/projectrenderer.cc
index 62d646e..a8e805b 100644
--- a/src/projectrenderer.cc
+++ b/src/projectrenderer.cc
@@ -85,8 +85,8 @@ void ProjectRenderer::render()
instrument.getInstrumentName());
{
- auto selections = instrument.getSelections().ids();
- emit progressRenderStart(selections.count());
+ auto ranges = instrument.getRanges().ids();
+ emit progressRenderStart(ranges.count());
qApp->processEvents();
}
@@ -94,7 +94,7 @@ void ProjectRenderer::render()
connect(&extractor, SIGNAL(progressUpdate(int)),
this, SIGNAL(progressRenderTask(int)));
- if(!extractor.exportSelections())
+ if(!extractor.exportRanges())
{
emit progressFinished(1);
qApp->processEvents();
diff --git a/src/projectserialiser.cc b/src/projectserialiser.cc
index 6a204eb..8d9d824 100644
--- a/src/projectserialiser.cc
+++ b/src/projectserialiser.cc
@@ -188,15 +188,16 @@ QString ProjectSerialiser::serialise(const Project& project)
file.setAttribute("channel_map_id", audiofile.getChannelMapId());
file.setAttribute("master", i.master_file == audiofile.getAbsoluteFile());
file.setAttribute("main", audiofile.getMainChannel() ? "true" : "false");
+ file.setAttribute("pos", audiofile.getPositionChannel() ? "true" : "false");
file_list.appendChild(file);
}
auto regions = doc.createElement("regions");
- regions.setAttribute("nextid", i.selections.nextid);
- regions.setAttribute("act", i.selections.act);
+ regions.setAttribute("nextid", i.ranges.nextid);
+ regions.setAttribute("act", i.ranges.act);
instrument.appendChild(regions);
- for(auto r = i.selections.sels.begin(); r != i.selections.sels.end(); ++r)
+ for(auto r = i.ranges.sels.begin(); r != i.ranges.sels.end(); ++r)
{
auto region = doc.createElement("region");
region.setAttribute("id", (int)r.key());
@@ -205,6 +206,7 @@ QString ProjectSerialiser::serialise(const Project& project)
region.setAttribute("fadein", (int)r.value().fadein);
region.setAttribute("fadeout", (int)r.value().fadeout);
region.setAttribute("energy", r.value().energy);
+ region.setAttribute("position", r.value().position);
region.setAttribute("name", r.value().name);
regions.appendChild(region);
}
@@ -257,7 +259,7 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
for(auto& instrument : instruments)
{
auto id = instrument["id"].toInt();
- project.instruments.emplace_back(Instrument(project, id));
+ project.instruments.emplace_back(project, id);
auto& instr = project.instruments.back();
instr.instrument_name = instrument("instrument_name").text();
@@ -273,6 +275,7 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
audiofile.name = file["name"];
audiofile.channel_map_id = file["channel_map_id"].toInt();
audiofile.main_channel = file["main"] == "true";
+ audiofile.pos_channel = file["pos"] == "true";
if(file["master"] == "1")
{
@@ -292,20 +295,21 @@ bool ProjectSerialiser::deserialise(const QString& data, Project& project)
instr.prefix = instrument("prefix").text();
- auto selections = instrument("regions");
- instr.selections.nextid = selections["nextid"].toInt();
- instr.selections.act = selections["act"].toInt();
+ auto ranges = instrument("regions");
+ instr.ranges.nextid = ranges["nextid"].toInt();
+ instr.ranges.act = ranges["act"].toInt();
- for(auto& selection : selections.children())
+ for(auto& range : ranges.children())
{
- Selection s;
- s.from = selection["from"].toInt();
- s.to = selection["to"].toInt();
- s.fadein = selection["fadein"].toInt();
- s.fadeout = selection["fadeout"].toInt();
- s.energy = selection["energy"].toFloat();
- s.name = selection["name"];
- instr.selections.sels[selection["id"].toInt()] = s;
+ Range s;
+ s.from = range["from"].toInt();
+ s.to = range["to"].toInt();
+ s.fadein = range["fadein"].toInt();
+ s.fadeout = range["fadeout"].toInt();
+ s.energy = range["energy"].toFloat();
+ s.position = range["position"].toFloat();
+ s.name = range["name"];
+ instr.ranges.sels[range["id"].toInt()] = s;
}
}
diff --git a/src/selection.cc b/src/range.cc
index e18e485..980a8ae 100644
--- a/src/selection.cc
+++ b/src/range.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selection.cc
+ * range.cc
*
* Mon Apr 14 10:13:21 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -24,50 +24,50 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "selection.h"
+#include "range.h"
-Selections::Selections()
+Ranges::Ranges()
: QObject(NULL)
{
nextid = 0;
act = SEL_NONE;
}
-Selections::Selections(const Selections& other)
+Ranges::Ranges(const Ranges& other)
{
*this = other;
}
-void Selections::operator=(const Selections& other)
+void Ranges::operator=(const Ranges& other)
{
sels = other.sels;
nextid = other.nextid;
act = other.act;
}
-sel_id_t Selections::add(Selection selection)
+sel_id_t Ranges::add(Range range)
{
sel_id_t id = nextid++;
- sels[id] = selection;
+ sels[id] = range;
added(id);
return id;
}
-Selection Selections::get(sel_id_t id)
+Range& Ranges::get(sel_id_t id)
{
if(sels.find(id) == sels.end())
{
- Selection s(0,0,0,0);
+ static Range s{};
return s;
}
return sels[id];
}
-QVector<sel_id_t> Selections::ids()
+QVector<sel_id_t> Ranges::ids()
{
QVector<sel_id_t> v;
- QMap<sel_id_t, Selection>::iterator i = sels.begin();
+ QMap<sel_id_t, Range>::iterator i = sels.begin();
while(i != sels.end())
{
v.push_back(i.key());
@@ -77,16 +77,16 @@ QVector<sel_id_t> Selections::ids()
return v;
}
-void Selections::update(sel_id_t id, Selection selection)
+void Ranges::update(sel_id_t id, Range range)
{
if(sels.find(id) != sels.end())
{
- sels[id] = selection;
+ sels[id] = range;
emit updated(id);
}
}
-void Selections::remove(sel_id_t id)
+void Ranges::remove(sel_id_t id)
{
if(sels.find(id) != sels.end())
{
@@ -99,7 +99,7 @@ void Selections::remove(sel_id_t id)
}
}
-void Selections::clear()
+void Ranges::clear()
{
QVector<sel_id_t> _ids = ids();
QVector<sel_id_t>::iterator i = _ids.begin();
@@ -110,7 +110,7 @@ void Selections::clear()
}
}
-void Selections::setActive(sel_id_t id)
+void Ranges::setActive(sel_id_t id)
{
if(sels.find(id) != sels.end())
{
@@ -123,7 +123,7 @@ void Selections::setActive(sel_id_t id)
emit activeChanged(act);
}
-sel_id_t Selections::active()
+sel_id_t Ranges::active()
{
return act;
}
diff --git a/src/selection.h b/src/range.h
index 338b381..36782dc 100644
--- a/src/selection.h
+++ b/src/range.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selection.h
+ * range.h
*
* Sat Nov 21 13:20:46 CET 2009
* Copyright 2009 Bent Bisballe Nyeng
@@ -31,85 +31,81 @@
#include <QMap>
#include <QVector>
-class Selection
+struct Range
{
-public:
- Selection(int from = 0, int to = 0, int fadein = 0, int fadeout = 0)
- {
- this->from = from;
- this->to = to;
- this->fadein = fadein;
- this->fadeout = fadeout;
- }
- size_t from;
- size_t to;
- size_t fadein;
- size_t fadeout;
-
- double energy;
+ size_t from{};
+ size_t to{};
+ size_t fadein{};
+ size_t fadeout{};
+
+ size_t pos1{};
+ size_t pos2{};
+
+ double energy{};
+ double position{};
QString name;
};
-typedef int sel_id_t;
-#define SEL_NONE -1
+using sel_id_t = int;
+static constexpr sel_id_t SEL_NONE = -1;
-class Selections
+class Ranges
: public QObject
{
Q_OBJECT
public:
- Selections();
- Selections(const Selections&);
+ Ranges();
+ Ranges(const Ranges&);
- void operator=(const Selections& other);
+ void operator=(const Ranges& other);
- //! Add a new selection object. The new id is returned.
- //! Adding a new selections will emit an added signal with the new id.
- sel_id_t add(Selection selection);
+ //! Add a new range object. The new id is returned.
+ //! Adding a new ranges will emit an added signal with the new id.
+ sel_id_t add(Range range);
- //! Get a stack copy of a specific selection object, by id.
- //! NOTE: If id does not exist an empty selection (from = to = 0) is
+ //! Get a stack copy of a specific range object, by id.
+ //! NOTE: If id does not exist an empty range (from = to = 0) is
//! returned.
- Selection get(sel_id_t id);
+ Range& get(sel_id_t id);
//! Return vector (unsorted) of all ids in the object.
QVector<sel_id_t> ids();
- //! Set active selection (to be rendered yellow)
+ //! Set active range (to be rendered yellow)
void setActive(sel_id_t id);
- //! Get active selection id.
+ //! Get active range id.
sel_id_t active();
public slots:
- //! Update a selection by id.
- //! Updating a selection will emit a updated signal.
- void update(sel_id_t id, Selection selection);
+ //! Update a range by id.
+ //! Updating a range will emit a updated signal.
+ void update(sel_id_t id, Range range);
- //! Delete a selection by id.
- //! Deleting a selection will emit a deleted signal.
+ //! Delete a range by id.
+ //! Deleting a range will emit a deleted signal.
void remove(sel_id_t id);
- //! Delete all selections
+ //! Delete all ranges
void clear();
signals:
- //! This signal is emitted when a new selection has been added.
+ //! This signal is emitted when a new range has been added.
void added(sel_id_t id);
- //! This signal is emitted when an existing selection has been updated.
+ //! This signal is emitted when an existing range has been updated.
void updated(sel_id_t id);
- //! This signal is emitted when a selection has been removed.
+ //! This signal is emitted when a range has been removed.
void removed(sel_id_t id);
- //! The active selection changed.
+ //! The active range changed.
void activeChanged(sel_id_t id);
private:
friend class ProjectSerialiser;
- QMap<sel_id_t, Selection> sels;
+ QMap<sel_id_t, Range> sels;
sel_id_t nextid;
sel_id_t act;
};
diff --git a/src/selectioneditor.cc b/src/rangeeditor.cc
index 417059d..504500d 100644
--- a/src/selectioneditor.cc
+++ b/src/rangeeditor.cc
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selectioneditor.cc
+ * rangeeditor.cc
*
* Thu Apr 17 17:25:18 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -24,7 +24,7 @@
* along with DrumGizmo; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "selectioneditor.h"
+#include "rangeeditor.h"
#include "project.h"
@@ -40,7 +40,7 @@ static QLineEdit *createWidget(QString name, QWidget* parent)
QLineEdit* edt = new QLineEdit();
QObject::connect(edt, SIGNAL(editingFinished()),
- parent, SLOT(updateSelection()));
+ parent, SLOT(updateRange()));
l->addWidget(edt);
@@ -49,8 +49,8 @@ static QLineEdit *createWidget(QString name, QWidget* parent)
return edt;
}
-SelectionEditor::SelectionEditor(Selections &s, Instrument& instrument)
- : selections(s)
+RangeEditor::RangeEditor(Ranges &s, Instrument& instrument)
+ : ranges(s)
, instrument(instrument)
{
cur = SEL_NONE;
@@ -62,44 +62,47 @@ SelectionEditor::SelectionEditor(Selections &s, Instrument& instrument)
fadein = createWidget(tr("FadeIn:"), this);
fadeout = createWidget(tr("FadeOut:"), this);
energy = createWidget(tr("Energy:"), this);
+ position = createWidget(tr("Position:"), this);
name = createWidget(tr("Name:"), this);
((QHBoxLayout*)layout())->addStretch();
}
-void SelectionEditor::updateSelection()
+void RangeEditor::updateRange()
{
- Selection sel;
+ Range sel;
sel.from = from->text().toInt();
sel.to = to->text().toInt();
sel.fadein = fadein->text().toInt();
sel.fadeout = fadeout->text().toInt();
sel.energy = energy->text().toDouble();
+ sel.position = position->text().toDouble();
sel.name = name->text();
- selections.update(cur, sel);
+ ranges.update(cur, sel);
- instrument.setSelections(selections);
+ instrument.setRanges(ranges);
}
-void SelectionEditor::update()
+void RangeEditor::update()
{
- Selection sel = selections.get(cur);
+ Range sel = ranges.get(cur);
from->setText(QString::number(sel.from));
to->setText(QString::number(sel.to));
fadein->setText(QString::number(sel.fadein));
fadeout->setText(QString::number(sel.fadeout));
energy->setText(QString::number(sel.energy));
+ position->setText(QString::number(sel.position));
name->setText(sel.name);
}
-void SelectionEditor::added(sel_id_t id)
+void RangeEditor::added(sel_id_t id)
{
// Nothing to do here...
}
-void SelectionEditor::updated(sel_id_t id)
+void RangeEditor::updated(sel_id_t id)
{
if(cur == id)
{
@@ -107,7 +110,7 @@ void SelectionEditor::updated(sel_id_t id)
}
}
-void SelectionEditor::removed(sel_id_t id)
+void RangeEditor::removed(sel_id_t id)
{
if(cur == id)
{
@@ -116,7 +119,7 @@ void SelectionEditor::removed(sel_id_t id)
}
}
-void SelectionEditor::activeChanged(sel_id_t id)
+void RangeEditor::activeChanged(sel_id_t id)
{
cur = id;
update();
diff --git a/src/selectioneditor.h b/src/rangeeditor.h
index cdbf2de..d37e82c 100644
--- a/src/selectioneditor.h
+++ b/src/rangeeditor.h
@@ -1,6 +1,6 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
- * selectioneditor.h
+ * rangeeditor.h
*
* Thu Apr 17 17:25:17 CEST 2014
* Copyright 2014 Bent Bisballe Nyeng
@@ -29,16 +29,16 @@
#include <QWidget>
#include <QLineEdit>
-#include "selection.h"
+#include "range.h"
class Instrument;
-class SelectionEditor
+class RangeEditor
: public QWidget
{
Q_OBJECT
public:
- SelectionEditor(Selections& selections, Instrument& instrument);
+ RangeEditor(Ranges& ranges, Instrument& instrument);
public slots:
void added(sel_id_t id);
@@ -48,10 +48,10 @@ public slots:
private slots:
void update();
- void updateSelection();
+ void updateRange();
private:
- Selections& selections;
+ Ranges& ranges;
sel_id_t cur;
@@ -60,6 +60,7 @@ private:
QLineEdit* fadein;
QLineEdit* fadeout;
QLineEdit* energy;
+ QLineEdit* position;
QLineEdit* name;
Instrument& instrument;
diff --git a/src/samplesorter.cc b/src/samplesorter.cc
index 29c24e6..4e930e4 100644
--- a/src/samplesorter.cc
+++ b/src/samplesorter.cc
@@ -26,10 +26,13 @@
*/
#include "samplesorter.h"
+#include "project.h"
+
#include <QPainter>
#include <QPaintEvent>
#include <QKeyEvent>
+#include <iostream>
#include <stdio.h>
#include <math.h>
@@ -37,9 +40,9 @@
#define MAXFLOAT (3.40282347e+38F)
#endif
-SampleSorter::SampleSorter(Selections& s, Selections& p, Instrument& instrument)
- : selections(s)
- , selections_preview(p)
+SampleSorter::SampleSorter(Ranges& s, Ranges& p, Instrument& instrument)
+ : ranges(s)
+ , ranges_preview(p)
, instrument(instrument)
{
setMouseTracking(true);
@@ -66,6 +69,18 @@ void SampleSorter::setWavData(const float* data, size_t size)
relayout();
}
+void SampleSorter::setPositionData(const float* positionData1, size_t positionSize1,
+ const float* positionData2, size_t positionSize2)
+{
+ this->positionData1 = positionData1;
+ this->positionSize1 = positionSize1;
+
+ this->positionData2 = positionData2;
+ this->positionSize2 = positionSize2;
+
+ relayout();
+}
+
int SampleSorter::attackLength()
{
return attlen;
@@ -84,28 +99,152 @@ void SampleSorter::setAttackLength(int len)
relayout();
}
-void SampleSorter::addSelection(sel_id_t id)
+void SampleSorter::addRange(sel_id_t id)
{
- Selection s = selections.get(id);
+ auto range = ranges.get(id);
double energy = 0.0;
- for(size_t idx = s.from;
- (idx < (size_t)s.from + (size_t)attackLength()) &&
- (idx < (size_t)s.to) && (idx < size);
+ for(size_t idx = range.from;
+ (idx < (size_t)range.from + (size_t)attackLength()) &&
+ (idx < (size_t)range.to) && (idx < size);
idx++)
{
energy += data[idx] * data[idx];
}
- s.energy = pow(energy, spread);
- selections.update(id, s);
+ range.energy = pow(energy, spread);
+
+// constexpr int window_size{10}; // TODO: Specify in ms
+//
+// std::vector<float> corr;
+// corr.resize(window_size);
+//
+// double position = 0.0;
+//
+// std::cout << "\n\nRange from: " << range.from << "\n";
+//
+//
+// float max_val1{0};
+// for(int idx = range.from - window_size / 2; idx < range.from + window_size / 2; ++idx)
+// {
+// if(std::abs(positionData1[idx]) > max_val1)
+// {
+// max_val1 = std::abs(positionData1[idx]);
+// }
+// }
+// float norm1 = 1.0f / max_val1;
+//
+// float max_val2{0};
+// for(int idx = range.from - window_size / 2; idx < range.from + window_size / 2; ++idx)
+// {
+// if(std::abs(positionData2[idx]) > max_val2)
+// {
+// max_val2 = std::abs(positionData2[idx]);
+// }
+// }
+// float norm2 = 1.0f / max_val2;
+//
+//
+// //constexpr auto lpf_beta = 0.025f; // 0<ß<1
+// constexpr auto lpf_beta = 1.0f; // 0<ß<1
+//
+// auto filter1 =
+// [lpf_beta](auto in)
+// {
+// static auto v{0.0f};
+// v = v - (lpf_beta * (v - in));
+// return v;
+// };
+// auto filter2 =
+// [lpf_beta](auto in)
+// {
+// static auto v{0.0f};
+// v = v - (lpf_beta * (v - in));
+// return v;
+// };
+//
+//
+//#if 0 // Cross-correlation
+//
+// if(positionData1 && positionSize1 &&
+// positionData2 && positionSize2)
+// {
+// // From: http://eceweb1.rutgers.edu/~gajic/solmanual/slides/chapter9_CORR.pdf
+// for(int k = 0; k < window_size; ++k)
+// {
+// corr[k] = 0.0f;
+// for(int m = range.from - window_size / 2; m < range.from + window_size / 2; ++m)
+// {
+// corr[k] +=
+// (filter1(positionData1[m] * norm1)) *
+// (filter2(positionData2[m - k] * norm2));
+// }
+// }
+// }
+//
+// float max_corr{0.0f};
+// for(int idx = 0; idx < corr.size(); ++idx)
+// {
+// std::cout << idx << ": " << corr[idx] << "\n";
+// if(corr[idx] > max_corr)
+// {
+// max_corr = corr[idx];
+// position = idx;
+// }
+// }
+//
+// std::cout << "Maximum found: " << max_corr << " at idx " << position << "\n";
+//
+//#else // Rising edge detection
+//
+// float threshold = instrument.getPositionThreshold();//{0.003f};
+// int pos_window_size{100}; // +/- 50 from detected,
+// // ~40 samples between left/right impirically detected when at edge, same for main mic to each of
+// // the piezos
+// norm1 = norm2 = 1.0f;
+// int pos1{0};
+// for(int idx = range.from - pos_window_size / 2;
+// idx < range.from + pos_window_size / 2;
+// ++idx)
+// {
+// if(std::abs(filter1(positionData1[idx])) * norm1 > threshold)
+// {
+// pos1 = idx;
+// range.pos1 = pos1;
+// break;
+// }
+// }
+//
+// int pos2{0};
+// for(int idx = range.from - pos_window_size / 2;
+// idx < range.from + pos_window_size / 2;
+// ++idx)
+// {
+// if(std::abs(filter2(positionData2[idx])) * norm2 > threshold)
+// {
+// pos2 = idx;
+// range.pos2 = pos1;
+// break;
+// }
+// }
+//
+// position = std::abs(pos1 - pos2);
+//#endif
+//
+// std::cout << "[" << pos1 << " <-> " << pos2 << "]\n";
+//
+// constexpr double speed_of_sound{3431000}; // mm/s
+// constexpr double samplerate{48000}; // 48kHz - TODO get from audio
+// range.position = position * speed_of_sound / samplerate / 2.0;
+//
+ ranges.update(id, range);
relayout();
}
-void SampleSorter::addSelectionPreview(sel_id_t id)
+void SampleSorter::addRangePreview(sel_id_t id)
{
- Selection s = selections_preview.get(id);
+ Range s = ranges_preview.get(id);
double energy = 0.0;
for(size_t idx = s.from;
@@ -117,7 +256,7 @@ void SampleSorter::addSelectionPreview(sel_id_t id)
}
s.energy = pow(energy, spread);
- selections_preview.update(id, s);
+ ranges_preview.update(id, s);
relayout();
}
@@ -128,11 +267,11 @@ void SampleSorter::relayout()
max = 0.0;
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
if(sel.energy < min)
{
@@ -149,11 +288,11 @@ void SampleSorter::relayout()
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
if(sel.energy < min)
{
@@ -203,12 +342,12 @@ void SampleSorter::paintEvent(QPaintEvent* event)
{
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
- if(*i == selections.active())
+ Range sel = ranges.get(*i);
+ if(*i == ranges.active())
{
painter.setPen(colPtSel);
}
@@ -226,11 +365,11 @@ void SampleSorter::paintEvent(QPaintEvent* event)
if(show_preview)
{
- QVector<sel_id_t> ids = selections_preview.ids();
+ QVector<sel_id_t> ids = ranges_preview.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections_preview.get(*i);
+ Range sel = ranges_preview.get(*i);
painter.setPen(colPtPreview);
float x = (sel.energy / max);
x = sqrt(x);
@@ -243,16 +382,16 @@ void SampleSorter::paintEvent(QPaintEvent* event)
}
-sel_id_t SampleSorter::getSelectionByCoordinate(int px, int py)
+sel_id_t SampleSorter::getRangeByCoordinate(int px, int py)
{
// Hit radius is slithly larger than the circles themselves.
int hit_r = C_RADIUS + 1;
- QVector<sel_id_t> ids = selections.ids();
+ QVector<sel_id_t> ids = ranges.ids();
QVector<sel_id_t>::iterator i = ids.begin();
while(i != ids.end())
{
- Selection sel = selections.get(*i);
+ Range sel = ranges.get(*i);
float x = (sel.energy/max);
x = sqrt(x);
x *= (float)width() * 0.9;
@@ -273,14 +412,14 @@ void SampleSorter::mouseMoveEvent(QMouseEvent* event)
{
if(sel_moving != SEL_NONE)
{
- Selection sel = selections.get(sel_moving);
+ Range sel = ranges.get(sel_moving);
if(sel_moving != SEL_NONE)
{
double power = unmapX(event->x());
power *= power;
power *= max;
sel.energy = power;
- selections.update(sel_moving, sel);
+ ranges.update(sel_moving, sel);
}
update();
@@ -288,7 +427,7 @@ void SampleSorter::mouseMoveEvent(QMouseEvent* event)
}
else
{
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
if(psel != SEL_NONE)
{
setCursor(Qt::OpenHandCursor);
@@ -304,9 +443,9 @@ void SampleSorter::mousePressEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
sel_moving = psel;
- selections.setActive(psel);
+ ranges.setActive(psel);
if(psel != SEL_NONE)
{
setCursor(Qt::ClosedHandCursor);
@@ -319,7 +458,7 @@ void SampleSorter::mouseReleaseEvent(QMouseEvent* event)
if(event->button() == Qt::LeftButton)
{
sel_moving = SEL_NONE;
- sel_id_t psel = getSelectionByCoordinate(event->x(), event->y());
+ sel_id_t psel = getRangeByCoordinate(event->x(), event->y());
if(psel != SEL_NONE)
{
setCursor(Qt::OpenHandCursor);
@@ -333,8 +472,8 @@ void SampleSorter::mouseReleaseEvent(QMouseEvent* event)
void SampleSorter::keyReleaseEvent(QKeyEvent* event)
{
- if(selections.active() != SEL_NONE && event->key() == Qt::Key_Delete)
+ if(ranges.active() != SEL_NONE && event->key() == Qt::Key_Delete)
{
- selections.remove(selections.active());
+ ranges.remove(ranges.active());
}
}
diff --git a/src/samplesorter.h b/src/samplesorter.h
index 056161d..58a784a 100644
--- a/src/samplesorter.h
+++ b/src/samplesorter.h
@@ -28,7 +28,7 @@
#include <QWidget>
#include <QVector>
-#include "selection.h"
+#include "range.h"
class Instrument;
@@ -37,16 +37,18 @@ class SampleSorter
{
Q_OBJECT
public:
- SampleSorter(Selections& selections, Selections& selections_preview,
+ SampleSorter(Ranges& ranges, Ranges& ranges_preview,
Instrument& instrument);
public slots:
void setWavData(const float* data, size_t size);
+ void setPositionData(const float* positionData1, size_t positionSize1,
+ const float* positionData2, size_t positionSize2);
void setAttackLength(int len);
int attackLength();
- void addSelection(sel_id_t id);
- void addSelectionPreview(sel_id_t id);
+ void addRange(sel_id_t id);
+ void addRangePreview(sel_id_t id);
void relayout();
@@ -62,10 +64,10 @@ protected:
void keyReleaseEvent(QKeyEvent* event) override;
private:
- sel_id_t getSelectionByCoordinate(int x, int y);
+ sel_id_t getRangeByCoordinate(int x, int y);
- Selections& selections;
- Selections& selections_preview;
+ Ranges& ranges;
+ Ranges& ranges_preview;
bool show_preview;
@@ -77,7 +79,13 @@ private:
const float* data;
size_t size;
- Selection sel;
+ const float* positionData1{nullptr};
+ size_t positionSize1{0};
+
+ const float* positionData2{nullptr};
+ size_t positionSize2{0};
+
+ Range sel;
sel_id_t sel_moving;
diff --git a/src/ts/dgedit_da.ts b/src/ts/dgedit_da.ts
index bda3ba5..62ea715 100644
--- a/src/ts/dgedit_da.ts
+++ b/src/ts/dgedit_da.ts
@@ -23,17 +23,32 @@
</message>
</context>
<context>
+ <name>CanvasToolPosition</name>
+ <message>
+ <location filename="../canvastoolposition.h" line="47"/>
+ <source>Position</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CanvasToolRanges</name>
+ <message>
+ <location filename="../canvastoolranges.h" line="48"/>
+ <source>Ranges</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CanvasToolSelections</name>
<message>
- <location filename="../canvastoolselections.h" line="45"/>
<source>Selections</source>
- <translation>Markeringer</translation>
+ <translation type="vanished">Markeringer</translation>
</message>
</context>
<context>
<name>CanvasToolThreshold</name>
<message>
- <location filename="../canvastoolthreshold.h" line="44"/>
+ <location filename="../canvastoolthreshold.h" line="43"/>
<source>Threshold</source>
<translation>Grænseværdi</translation>
</message>
@@ -54,7 +69,7 @@
<context>
<name>ChannelMapDeligate</name>
<message>
- <location filename="../filelist.cc" line="104"/>
+ <location filename="../filelist.cc" line="481"/>
<source>&lt;None&gt;</source>
<translation>&lt;Ingen&gt;</translation>
</message>
@@ -62,50 +77,55 @@
<context>
<name>FileDataModel</name>
<message>
- <location filename="../filelist.cc" line="309"/>
+ <location filename="../filelist.cc" line="147"/>
<source>&lt;None&gt;</source>
<translation>&lt;Ingen&gt;</translation>
</message>
<message>
- <location filename="../filelist.cc" line="341"/>
+ <location filename="../filelist.cc" line="181"/>
<source>M</source>
<translation>M</translation>
</message>
<message>
- <location filename="../filelist.cc" line="342"/>
+ <location filename="../filelist.cc" line="182"/>
<source>Filename</source>
<translation>Filnavn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="343"/>
+ <location filename="../filelist.cc" line="183"/>
<source>m</source>
<translation>m</translation>
</message>
<message>
- <location filename="../filelist.cc" line="344"/>
+ <location filename="../filelist.cc" line="184"/>
<source>Name</source>
<translation>Navn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="345"/>
+ <location filename="../filelist.cc" line="185"/>
<source>Kit Channel</source>
<translation>Trommesæt kanal</translation>
</message>
+ <message>
+ <location filename="../filelist.cc" line="186"/>
+ <source>p</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>FileList</name>
<message>
- <location filename="../filelist.cc" line="462"/>
+ <location filename="../filelist.cc" line="307"/>
<source>Open file</source>
<translation>Åbn fil</translation>
</message>
<message>
- <location filename="../filelist.cc" line="463"/>
+ <location filename="../filelist.cc" line="308"/>
<source>Audio Files (*.wav)</source>
<translation>Lyd filer (*.wav)</translation>
</message>
<message>
- <location filename="../filelist.cc" line="530"/>
+ <location filename="../filelist.cc" line="375"/>
<source>Set as Master (dbl-click)</source>
<translation>Vælg hovedkanal (dbl klik)</translation>
</message>
@@ -114,12 +134,12 @@
<translation type="vanished">Redigér navn</translation>
</message>
<message>
- <location filename="../filelist.cc" line="533"/>
+ <location filename="../filelist.cc" line="378"/>
<source>Remove</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../filelist.cc" line="536"/>
+ <location filename="../filelist.cc" line="381"/>
<source>Remove all</source>
<translation>Fjern alle</translation>
</message>
@@ -140,108 +160,106 @@
<context>
<name>InstrumentWidget</name>
<message>
- <location filename="../instrumentwidget.cc" line="92"/>
+ <location filename="../instrumentwidget.cc" line="94"/>
<source>Tools</source>
<translation>Værktøjer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="123"/>
+ <location filename="../instrumentwidget.cc" line="159"/>
<source>Play samples</source>
<translation>Afspil lydbidder</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="137"/>
+ <location filename="../instrumentwidget.cc" line="173"/>
<source>Process</source>
<translation>Processér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="146"/>
+ <location filename="../instrumentwidget.cc" line="182"/>
<source>Files</source>
<translation>Filer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="147"/>
- <location filename="../instrumentwidget.cc" line="272"/>
+ <location filename="../instrumentwidget.cc" line="183"/>
+ <location filename="../instrumentwidget.cc" line="313"/>
<source>Generate</source>
<translation>Generér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="148"/>
+ <location filename="../instrumentwidget.cc" line="184"/>
<source>Edit</source>
<translation>Redigér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="193"/>
+ <location filename="../instrumentwidget.cc" line="232"/>
<source>Files: (double-click to set as master)</source>
<translation>Filer: (dobbeltklik for at vælge som hovedkanal)</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="195"/>
+ <location filename="../instrumentwidget.cc" line="234"/>
<source>Add files...</source>
<translation>Tilføj filer...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="284"/>
+ <location filename="../instrumentwidget.cc" line="320"/>
<source>Clear</source>
<translation>Ryd</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="293"/>
+ <location filename="../instrumentwidget.cc" line="329"/>
<source>Attack length:</source>
<translation>Attack længde:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="302"/>
+ <location filename="../instrumentwidget.cc" line="338"/>
<source>Power spread:</source>
<translation>Energi spredning:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="311"/>
+ <location filename="../instrumentwidget.cc" line="347"/>
<source>Minimum size (samples):</source>
<translation>Minimum størrelse (samples):</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="320"/>
+ <location filename="../instrumentwidget.cc" line="356"/>
<source>Falloff:</source>
<translation>Falloff:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="329"/>
+ <location filename="../instrumentwidget.cc" line="365"/>
<source>Fadelength:</source>
<translation>Fadelængde:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="359"/>
+ <location filename="../instrumentwidget.cc" line="395"/>
<source>Prefix:</source>
<translation>Præfix:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="366"/>
<source>Export path:</source>
- <translation>Eksporteringssti:</translation>
+ <translation type="vanished">Eksporteringssti:</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="373"/>
<source>...</source>
- <translation>...</translation>
+ <translation type="vanished">...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="380"/>
+ <location filename="../instrumentwidget.cc" line="185"/>
<source>Export</source>
<translation>Eksportér</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="475"/>
+ <location filename="../instrumentwidget.cc" line="511"/>
<source>Loading...</source>
<translation>Indlæser...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="486"/>
+ <location filename="../instrumentwidget.cc" line="522"/>
<source>Ready</source>
<translation>Klar</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="495"/>
+ <location filename="../instrumentwidget.cc" line="628"/>
<source>Select export path</source>
<translation>Vælg eksporteringssti</translation>
</message>
@@ -507,6 +525,44 @@
</message>
</context>
<context>
+ <name>RangeEditor</name>
+ <message>
+ <location filename="../rangeeditor.cc" line="60"/>
+ <source>From:</source>
+ <translation type="unfinished">Fra:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="61"/>
+ <source>To:</source>
+ <translation type="unfinished">Til:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="62"/>
+ <source>FadeIn:</source>
+ <translation type="unfinished">FadeIn:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="63"/>
+ <source>FadeOut:</source>
+ <translation type="unfinished">FadeOut:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="64"/>
+ <source>Energy:</source>
+ <translation type="unfinished">Energi:</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="65"/>
+ <source>Position:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="66"/>
+ <source>Name:</source>
+ <translation type="unfinished">Navn:</translation>
+ </message>
+</context>
+<context>
<name>RenderDialog</name>
<message>
<location filename="../renderdialog.cc" line="280"/>
@@ -537,34 +593,28 @@
<context>
<name>SelectionEditor</name>
<message>
- <location filename="../selectioneditor.cc" line="60"/>
<source>From:</source>
- <translation>Fra:</translation>
+ <translation type="vanished">Fra:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="61"/>
<source>To:</source>
- <translation>Til:</translation>
+ <translation type="vanished">Til:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="62"/>
<source>FadeIn:</source>
- <translation>FadeIn:</translation>
+ <translation type="vanished">FadeIn:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="63"/>
<source>FadeOut:</source>
- <translation>FadeOut:</translation>
+ <translation type="vanished">FadeOut:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="64"/>
<source>Energy:</source>
- <translation>Energi:</translation>
+ <translation type="vanished">Energi:</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="65"/>
<source>Name:</source>
- <translation>Navn:</translation>
+ <translation type="vanished">Navn:</translation>
</message>
</context>
<context>
diff --git a/src/ts/dgedit_fr.ts b/src/ts/dgedit_fr.ts
index deb07bd..17fd995 100644
--- a/src/ts/dgedit_fr.ts
+++ b/src/ts/dgedit_fr.ts
@@ -23,17 +23,32 @@
</message>
</context>
<context>
+ <name>CanvasToolPosition</name>
+ <message>
+ <location filename="../canvastoolposition.h" line="47"/>
+ <source>Position</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CanvasToolRanges</name>
+ <message>
+ <location filename="../canvastoolranges.h" line="48"/>
+ <source>Ranges</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CanvasToolSelections</name>
<message>
- <location filename="../canvastoolselections.h" line="45"/>
<source>Selections</source>
- <translation>Sélections</translation>
+ <translation type="vanished">Sélections</translation>
</message>
</context>
<context>
<name>CanvasToolThreshold</name>
<message>
- <location filename="../canvastoolthreshold.h" line="44"/>
+ <location filename="../canvastoolthreshold.h" line="43"/>
<source>Threshold</source>
<translation>Seuil de déclenchement</translation>
</message>
@@ -54,7 +69,7 @@
<context>
<name>ChannelMapDeligate</name>
<message>
- <location filename="../filelist.cc" line="104"/>
+ <location filename="../filelist.cc" line="481"/>
<source>&lt;None&gt;</source>
<translation>&lt;None&gt;</translation>
</message>
@@ -62,50 +77,55 @@
<context>
<name>FileDataModel</name>
<message>
- <location filename="../filelist.cc" line="309"/>
+ <location filename="../filelist.cc" line="147"/>
<source>&lt;None&gt;</source>
<translation>&lt;Aucun&gt;</translation>
</message>
<message>
- <location filename="../filelist.cc" line="341"/>
+ <location filename="../filelist.cc" line="181"/>
<source>M</source>
<translation>M</translation>
</message>
<message>
- <location filename="../filelist.cc" line="342"/>
+ <location filename="../filelist.cc" line="182"/>
<source>Filename</source>
<translation>Nom de fichier</translation>
</message>
<message>
- <location filename="../filelist.cc" line="343"/>
+ <location filename="../filelist.cc" line="183"/>
<source>m</source>
<translation>m</translation>
</message>
<message>
- <location filename="../filelist.cc" line="344"/>
+ <location filename="../filelist.cc" line="184"/>
<source>Name</source>
<translation>Nom</translation>
</message>
<message>
- <location filename="../filelist.cc" line="345"/>
+ <location filename="../filelist.cc" line="185"/>
<source>Kit Channel</source>
<translation>Canal de kit</translation>
</message>
+ <message>
+ <location filename="../filelist.cc" line="186"/>
+ <source>p</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>FileList</name>
<message>
- <location filename="../filelist.cc" line="462"/>
+ <location filename="../filelist.cc" line="307"/>
<source>Open file</source>
<translation>Ouvrir un fichier</translation>
</message>
<message>
- <location filename="../filelist.cc" line="463"/>
+ <location filename="../filelist.cc" line="308"/>
<source>Audio Files (*.wav)</source>
<translation>Fichiers audio (*.wav)</translation>
</message>
<message>
- <location filename="../filelist.cc" line="530"/>
+ <location filename="../filelist.cc" line="375"/>
<source>Set as Master (dbl-click)</source>
<translation>Paramétrer en tant que maître (dbl-clic)</translation>
</message>
@@ -114,12 +134,12 @@
<translation type="vanished">Éditer le nom</translation>
</message>
<message>
- <location filename="../filelist.cc" line="533"/>
+ <location filename="../filelist.cc" line="378"/>
<source>Remove</source>
<translation>Supprimer</translation>
</message>
<message>
- <location filename="../filelist.cc" line="536"/>
+ <location filename="../filelist.cc" line="381"/>
<source>Remove all</source>
<translation>Supprimer tout</translation>
</message>
@@ -140,108 +160,106 @@
<context>
<name>InstrumentWidget</name>
<message>
- <location filename="../instrumentwidget.cc" line="92"/>
+ <location filename="../instrumentwidget.cc" line="94"/>
<source>Tools</source>
<translation>Outils</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="123"/>
+ <location filename="../instrumentwidget.cc" line="159"/>
<source>Play samples</source>
<translation>Lire les échantillons</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="137"/>
+ <location filename="../instrumentwidget.cc" line="173"/>
<source>Process</source>
<translation>Traiter</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="146"/>
+ <location filename="../instrumentwidget.cc" line="182"/>
<source>Files</source>
<translation>Fichiers</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="147"/>
- <location filename="../instrumentwidget.cc" line="272"/>
+ <location filename="../instrumentwidget.cc" line="183"/>
+ <location filename="../instrumentwidget.cc" line="313"/>
<source>Generate</source>
<translation>Générer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="148"/>
+ <location filename="../instrumentwidget.cc" line="184"/>
<source>Edit</source>
<translation>Éditer</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="193"/>
+ <location filename="../instrumentwidget.cc" line="232"/>
<source>Files: (double-click to set as master)</source>
<translation>Fichiers : (double-clic pour paramétrer en tant que maître)</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="195"/>
+ <location filename="../instrumentwidget.cc" line="234"/>
<source>Add files...</source>
<translation>Ajouter des fichiers...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="284"/>
+ <location filename="../instrumentwidget.cc" line="320"/>
<source>Clear</source>
<translation>Vider</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="293"/>
+ <location filename="../instrumentwidget.cc" line="329"/>
<source>Attack length:</source>
<translation>Longueur d&apos;attaque :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="302"/>
+ <location filename="../instrumentwidget.cc" line="338"/>
<source>Power spread:</source>
<translation>Étalement de la puissance :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="311"/>
+ <location filename="../instrumentwidget.cc" line="347"/>
<source>Minimum size (samples):</source>
<translation>Taille minimum (échantillons) :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="320"/>
+ <location filename="../instrumentwidget.cc" line="356"/>
<source>Falloff:</source>
<translation>Temps de chute :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="329"/>
+ <location filename="../instrumentwidget.cc" line="365"/>
<source>Fadelength:</source>
<translation>Longueur de fondu :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="359"/>
+ <location filename="../instrumentwidget.cc" line="395"/>
<source>Prefix:</source>
<translation>Préfixe :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="366"/>
<source>Export path:</source>
- <translation>Chemin d&apos;exportation :</translation>
+ <translation type="vanished">Chemin d&apos;exportation :</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="373"/>
<source>...</source>
- <translation>...</translation>
+ <translation type="vanished">...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="380"/>
+ <location filename="../instrumentwidget.cc" line="185"/>
<source>Export</source>
<translation>Exporter</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="475"/>
+ <location filename="../instrumentwidget.cc" line="511"/>
<source>Loading...</source>
<translation>Chargement...</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="486"/>
+ <location filename="../instrumentwidget.cc" line="522"/>
<source>Ready</source>
<translation>Prêt</translation>
</message>
<message>
- <location filename="../instrumentwidget.cc" line="495"/>
+ <location filename="../instrumentwidget.cc" line="628"/>
<source>Select export path</source>
<translation>Sélectionner le chemin d&apos;exportation</translation>
</message>
@@ -507,6 +525,44 @@
</message>
</context>
<context>
+ <name>RangeEditor</name>
+ <message>
+ <location filename="../rangeeditor.cc" line="60"/>
+ <source>From:</source>
+ <translation type="unfinished">Depuis :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="61"/>
+ <source>To:</source>
+ <translation type="unfinished">Jusqu&apos;à :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="62"/>
+ <source>FadeIn:</source>
+ <translation type="unfinished">Fondu ouverture :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="63"/>
+ <source>FadeOut:</source>
+ <translation type="unfinished">Fondu fermeture :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="64"/>
+ <source>Energy:</source>
+ <translation type="unfinished">Énergie :</translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="65"/>
+ <source>Position:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location filename="../rangeeditor.cc" line="66"/>
+ <source>Name:</source>
+ <translation type="unfinished">Nom :</translation>
+ </message>
+</context>
+<context>
<name>RenderDialog</name>
<message>
<location filename="../renderdialog.cc" line="280"/>
@@ -537,34 +593,28 @@
<context>
<name>SelectionEditor</name>
<message>
- <location filename="../selectioneditor.cc" line="60"/>
<source>From:</source>
- <translation>Depuis :</translation>
+ <translation type="vanished">Depuis :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="61"/>
<source>To:</source>
- <translation>Jusqu&apos;à :</translation>
+ <translation type="vanished">Jusqu&apos;à :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="62"/>
<source>FadeIn:</source>
- <translation>Fondu ouverture :</translation>
+ <translation type="vanished">Fondu ouverture :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="63"/>
<source>FadeOut:</source>
- <translation>Fondu fermeture :</translation>
+ <translation type="vanished">Fondu fermeture :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="64"/>
<source>Energy:</source>
- <translation>Énergie :</translation>
+ <translation type="vanished">Énergie :</translation>
</message>
<message>
- <location filename="../selectioneditor.cc" line="65"/>
<source>Name:</source>
- <translation>Nom :</translation>
+ <translation type="vanished">Nom :</translation>
</message>
</context>
<context>
@@ -581,4 +631,3 @@
</message>
</context>
</TS>
-
diff --git a/tools/MocList b/tools/MocList
index 6aff3ee..cbbec60 100755
--- a/tools/MocList
+++ b/tools/MocList
@@ -1,9 +1,9 @@
# -*- mode: shell-script; sh-shell: bash; sh-indentation: 2 -*-
if [ "$2" = "cc" ]; then
- grep "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | sed -e 's/^//g;s/\.h/\.moc.cc/g'| xargs echo;
+ grep -m1 "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | sed -e 's/^//g;s/\.h/\.moc.cc/g'| xargs echo;
elif [ "$2" = "o" ]; then
- grep "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | sed -e 's/^//g;s/\.h/\.moc.o/g'| xargs echo;
+ grep -m1 "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | sed -e 's/^//g;s/\.h/\.moc.o/g'| xargs echo;
elif [ "$2" = "h" ]; then
- grep "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | cut -d'/' -f3 | xargs echo;
+ grep -m1 "Q_OBJECT" $1/*.h | LC_ALL=C sort | cut -d: -f1 | cut -d'/' -f3 | xargs echo;
fi