diff --git a/CMakeLists.txt b/CMakeLists.txt index 56955066e..bd130709b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -581,7 +581,7 @@ FOREACH(_ts_file ${lmms_LOCALES}) STRING(REPLACE "${CMAKE_SOURCE_DIR}/data/locale/" "" _ts_target "${_ts_file}") STRING(REPLACE ".ts" ".qm" _qm_file "${_ts_file}") STRING(REPLACE ".ts" ".qm" _qm_target "${_ts_target}") - ADD_CUSTOM_TARGET(${_ts_target} COMMAND ${QT_LUPDATE_EXECUTABLE} -locations none -no-obsolete ${lmms_SOURCES} `find ${CMAKE_SOURCE_DIR}/plugins/ -type f -name '*.cpp'` -ts ${_ts_file}) + ADD_CUSTOM_TARGET(${_ts_target} COMMAND ${QT_LUPDATE_EXECUTABLE} -locations none -no-obsolete ${lmms_SOURCES} ${lmms_UI} `find ${CMAKE_SOURCE_DIR}/plugins/ -type f -name '*.cpp'` -ts ${_ts_file}) ADD_CUSTOM_TARGET(${_qm_target} COMMAND ${QT_LRELEASE_EXECUTABLE} ${_ts_file} -qm ${_qm_file}) LIST(APPEND ts_targets "${_ts_target}") LIST(APPEND qm_targets "${_qm_target}") diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 000000000..0586f6041 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1514 @@ +# Doxyfile 1.6.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = LMMS + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src/core src/gui src/tracks include/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.cpp *.c *.h + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) +# there is already a search function so this one should typically +# be disabled. + +SEARCHENGINE = YES + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/data/locale/ca.ts b/data/locale/ca.ts index 1c3d75654..4bceecb00 100644 --- a/data/locale/ca.ts +++ b/data/locale/ca.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + Quant a + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Ajuda + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1186,6 +1255,150 @@ Per favor, assegura't que tens permís d'escriptura per al fitxer i el Rendering: %1% Representant: %1% + + Export project + + + + Output + Sortida + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Cancel·la + FxMixer @@ -2478,6 +2691,21 @@ Available decoders: %2 Fitxer: + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2877,6 +3105,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer Si funciona amb altre programari VST sota Linux, per favor contacta amb un desenvolupador de LMMS! + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/cs.ts b/data/locale/cs.ts index 7cea30e3e..f900de32d 100644 --- a/data/locale/cs.ts +++ b/data/locale/cs.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + O LMMS + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ PÅ™idat efekt + + EffectSelectDialog + + Add effect + PÅ™idat efekt + + + Plugin description + + + EffectView @@ -1186,6 +1255,150 @@ PÅ™esvÄ›dÄte se prosím, že máte právo zápisu do tohoto souboru a příslu Rendering: %1% Renderuji: %1% + + Export project + + + + Output + Výstup + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + ZruÅ¡it + FxMixer @@ -1947,7 +2160,7 @@ UjistÄ›te se prosím, že máte k souboru právo zápisu a zkuste to znovu. Master pitch - + Hlavní ladÄ›ní (pitch) master pitch @@ -2479,6 +2692,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2878,6 +3106,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer Jestliže tento plugin funguje v Linuxu v jiném VST softwaru, kontaktujte prosím LMMS vývojáře! + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/de.qm b/data/locale/de.qm index 06e0759cd..ac9a16ae8 100644 Binary files a/data/locale/de.qm and b/data/locale/de.qm differ diff --git a/data/locale/de.ts b/data/locale/de.ts index 6854ebfaa..78da0edab 100644 --- a/data/locale/de.ts +++ b/data/locale/de.ts @@ -1,199 +1,250 @@ + + AboutDialog + + About LMMS + Über LMMS + + + LMMS (Linux MultiMedia Studio) + LMMS (Linux MultiMedia Studio) + + + Version %1 (%2/%3, Qt %4, %5) + Version %1 (%2/%3, Qt %4, %5) + + + About + Über + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + Copyright (c) 2004-2009, die LMMS-Entwickler + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + Autoren + + + Translation + Übersetzung + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + Lizenz + + Arpeggiator Arpeggio - Arpeggio + Arpeggio Arpeggio type - Arpeggiotyp + Arpeggiotyp Arpeggio range - Arpeggio-Bereich + Arpeggio-Bereich Arpeggio time - Arpeggio-Zeit + Arpeggio-Zeit Arpeggio gate - Arpeggio-Gate + Arpeggio-Gate Arpeggio direction - Arpeggio-Richtung + Arpeggio-Richtung Arpeggio mode - Arpeggio-Modus + Arpeggio-Modus Up - Hoch + Hoch Down - Runter + Runter Up and down - Hoch und runter + Hoch und runter Random - Zufällig + Zufällig Free - Frei + Frei Sort - Sortiert + Sortiert Sync - Synchron + Synchron ArpeggiatorView ARPEGGIO - ARPEGGIO + ARPEGGIO An arpeggio is a method playing (especially plucked) instruments, which makes the music much livelier. The strings of such instruments (e.g. harps) are plucked like chords. The only difference is that this is done in a sequential order, so the notes are not played at the same time. Typical arpeggios are major or minor triads, but there are a lot of other possible chords, you can select. - Ein Arpeggio ist eine Art, (vorallem gezupfte) Instrumente zu spielen, die die Musik viel lebendiger macht. Die Seiten von solchen Instrumenten (z.B. Harfen) werden wie Akkorde gezupft, der einzige Unterschied besteht darin, dass dies nacheinander geschieht. Die Noten werden also nicht zur gleichen Zeit gespielt. Typische Arpeggios sind Dur- oder Moll-Dreiklänge, aber es gibt noch viele andere Akkorde, die Sie auswählen können. + Ein Arpeggio ist eine Art, (vorallem gezupfte) Instrumente zu spielen, die die Musik viel lebendiger macht. Die Seiten von solchen Instrumenten (z.B. Harfen) werden wie Akkorde gezupft, der einzige Unterschied besteht darin, dass dies nacheinander geschieht. Die Noten werden also nicht zur gleichen Zeit gespielt. Typische Arpeggios sind Dur- oder Moll-Dreiklänge, aber es gibt noch viele andere Akkorde, die Sie auswählen können. RANGE - BEREICH + BEREICH Arpeggio range: - Arpeggio-Bereich: + Arpeggio-Bereich: octave(s) - Oktave(n) + Oktave(n) Use this knob for setting the arpeggio range in octaves. The selected arpeggio will be played within specified number of octaves. - Benutzen Sie diesen Knopf, um den Arpeggio-Bereich in Oktaven zu setzen. Das gewähle Arpeggio wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. + Benutzen Sie diesen Knopf, um den Arpeggio-Bereich in Oktaven zu setzen. Das gewähle Arpeggio wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. TIME - ZEIT + ZEIT Arpeggio time: - Arpeggio-Zeit: + Arpeggio-Zeit: ms - ms + ms Use this knob for setting the arpeggio time in milliseconds. The arpeggio time specifies how long each arpeggio-tone should be played. - Benutzen Sie diesen Knopf, um die Arpeggio-Zeit in Millisekunden zu setzen. Die Arpeggio-Zeit gibt an, wie lange jeder einzelne Arpeggio-Ton gespielt werden soll. + Benutzen Sie diesen Knopf, um die Arpeggio-Zeit in Millisekunden zu setzen. Die Arpeggio-Zeit gibt an, wie lange jeder einzelne Arpeggio-Ton gespielt werden soll. GATE - GATE + GATE Arpeggio gate: - Arpeggio-Gate: + Arpeggio-Gate: % - % + % Use this knob for setting the arpeggio gate. The arpeggio gate specifies the percent of a whole arpeggio-tone that should be played. With this you can make cool staccato arpeggios. - Benutzen Sie diesen Knopf, um das Arpeggio-Gate zu setzen. Das Arpeggio-Gate gibt an, wie viel Prozent eines ganzen Arpeggio-Tons gespielt werden sollen. Damit können Sie coole Staccato-Arpeggios erzeugen. + Benutzen Sie diesen Knopf, um das Arpeggio-Gate zu setzen. Das Arpeggio-Gate gibt an, wie viel Prozent eines ganzen Arpeggio-Tons gespielt werden sollen. Damit können Sie coole Staccato-Arpeggios erzeugen. Direction: - Richtung: + Richtung: Mode: - Modus: + Modus: AudioAlsa::setupWidget DEVICE - GERÄT + GERÄT CHANNELS - KANÄLE + KANÄLE AudioFileProcessorView Open other sample - Anderes Sample öffnen + Anderes Sample öffnen Click here, if you want to open another audio-file. A dialog will appear where you can select your file. Settings like looping-mode, start and end-points, amplify-value, and so on are not reset. So, it may not sound like the original sample. - Klicken Sie hier, um eine andere Audio-Datei zu öffnen. Danach erscheint ein Dialog, in dem Sie Ihre Datei wählen können. Einstellungen wie Wiederhol-Modus, Start- und Endpunkt sowie Verstärkung werden nicht zurückgesetzt, weshalb die Datei möglicherweise nicht wie das Original klingt. + Klicken Sie hier, um eine andere Audio-Datei zu öffnen. Danach erscheint ein Dialog, in dem Sie Ihre Datei wählen können. Einstellungen wie Wiederhol-Modus, Start- und Endpunkt sowie Verstärkung werden nicht zurückgesetzt, weshalb die Datei möglicherweise nicht wie das Original klingt. Reverse sample - Sample umkehren + Sample umkehren If you enable this button, the whole sample is reversed. This is useful for cool effects, e.g. a reversed crash. - Wenn Sie diesen Button aktivieren, wird das gesamte Sample umgekehrt. Das kann nützlich für coole Effekte sein, wie z.B. eine umgekehrte Crash. + Wenn Sie diesen Button aktivieren, wird das gesamte Sample umgekehrt. Das kann nützlich für coole Effekte sein, wie z.B. eine umgekehrte Crash. Loop sample at start- and end-point - Sample an Start- und Endpunkt wiederholen + Sample an Start- und Endpunkt wiederholen Here you can set, whether looping-mode is enabled. If enabled, AudioFileProcessor loops between start and end-points of a sample until the whole note is played. This is useful for things like string and choir samples. - Hier können Sie festlegen, ob der Looping-Modus aktiviert sein soll. Wenn aktiviert, wiederholt AudioFileProcessor das Sample zwischen Start- und Endpunkt solange, bis die gesamte Note gespielt ist. Das ist vorallem für String- und Chor-Samples nützlich. + Hier können Sie festlegen, ob der Looping-Modus aktiviert sein soll. Wenn aktiviert, wiederholt AudioFileProcessor das Sample zwischen Start- und Endpunkt solange, bis die gesamte Note gespielt ist. Das ist vorallem für String- und Chor-Samples nützlich. Amplify: - Verstärkung: + Verstärkung: With this knob you can set the amplify ratio. When you set a value of 100% your sample isn't changed. Otherwise it will be amplified up or down (your actual sample-file isn't touched!) - Mit diesem Knopf können Sie die Verstärkungsrate festlegen. Wenn Sie einen Wert von 100% setzen, wird das Sample nicht geändert. Ansonsten wird es hoch oder runter verstärkt (Ihre Audio-Datei wird dabei nicht verändert!) + Mit diesem Knopf können Sie die Verstärkungsrate festlegen. Wenn Sie einen Wert von 100% setzen, wird das Sample nicht geändert. Ansonsten wird es hoch oder runter verstärkt (Ihre Audio-Datei wird dabei nicht verändert!) Startpoint: - Startpunkt: + Startpunkt: With this knob you can set the point where AudioFileProcessor should begin playing your sample. If you enable looping-mode, this is the point to which AudioFileProcessor returns if a note is longer than the sample between the start and end-points. - Mit diesem Knopf können Sie festlegen, wo AudioFileProcessor anfangen soll, Ihr Sample zu spielen. Wenn Sie den Looping-Modus aktivieren, ist das der Punkt, wohin AudioFileProcessor zurückkehrt, wenn eine Note länger als das Sample zwischen Start- und Endpunkt ist. + Mit diesem Knopf können Sie festlegen, wo AudioFileProcessor anfangen soll, Ihr Sample zu spielen. Wenn Sie den Looping-Modus aktivieren, ist das der Punkt, wohin AudioFileProcessor zurückkehrt, wenn eine Note länger als das Sample zwischen Start- und Endpunkt ist. Endpoint: - Endpunkt: + Endpunkt: With this knob you can set the point where AudioFileProcessor should stop playing your sample. If you enable looping-mode, this is the point where AudioFileProcessor returns if a note is longer than the sample between the start and end-points. - Mit diesem Knopf können Sie festlegen, wo AudioFileProcessor aufhören soll, Ihr Sample zu spielen. Wenn Sie den Looping-Modus aktivieren, ist das der Punkt, an dem AudioFileProcessor zum Startpunkt zurückkehrt, wenn eine Note länger als das Sample zwischen Start- und Endpunkt ist. + Mit diesem Knopf können Sie festlegen, wo AudioFileProcessor aufhören soll, Ihr Sample zu spielen. Wenn Sie den Looping-Modus aktivieren, ist das der Punkt, an dem AudioFileProcessor zum Startpunkt zurückkehrt, wenn eine Note länger als das Sample zwischen Start- und Endpunkt ist. AudioJack JACK client restarted - + JACK-Client neugestartet LMMS was kicked by JACK for some reason. Therefore the JACK backend of LMMS has been restarted. You will have to make manual connections again. @@ -212,94 +263,94 @@ AudioJack::setupWidget CLIENT-NAME - CLIENT-NAME + CLIENT-NAME CHANNELS - KANÄLE + KANÄLE AudioOss::setupWidget DEVICE - GERÄT + GERÄT CHANNELS - KANÄLE + KANÄLE AudioPortAudio::setupWidget BACKEND - BACKEND + BACKEND DEVICE - GERÄT + GERÄT CHANNELS - KANÄLE + KANÄLE AudioPulseAudio::setupWidget DEVICE - GERÄT + GERÄT CHANNELS - KANÄLE + KANÄLE AudioSdl::setupWidget DEVICE - GERÄT + GERÄT AutomatableModel &Reset (%1%2) - &Zurücksetzen (%1%2) + &Zurücksetzen (%1%2) &Copy value (%1%2) - Wert &kopieren (%1%2) + Wert &kopieren (%1%2) &Paste value (%1%2) - Wert &einfügen (%1%2) + Wert &einfügen (%1%2) Edit song-global automation - Song-globale Automation editieren + Song-globale Automation editieren Connected to %1 - Verbunden mit %1 + Verbunden mit %1 Connected to controller - Verbunden mit Controller + Verbunden mit Controller Edit connection... - Verbindung bearbeiten... + Verbindung bearbeiten... Remove connection - Verbindung entfernen + Verbindung entfernen Connect to controller... - Mit Controller verbinden... + Mit Controller verbinden... de-arm @@ -314,582 +365,600 @@ ChordCreator octave - Oktave + Oktave Major - Dur + Dur Majb5 - Durb5 + Durb5 minor - moll + moll minb5 - mollb5 + mollb5 sus2 - sus2 + sus2 sus4 - sus4 + sus4 aug - aug + aug augsus4 - augsus4 + augsus4 tri - tri + tri 6 - 6 + 6 6sus4 - 6sus4 + 6sus4 6add9 - madd9 + madd9 m6 - m6 + m6 m6add9 - m6add9 + m6add9 7 - 7 + 7 7sus4 - 7sus4 + 7sus4 7#5 - 7#5 + 7#5 7b5 - 7b5 + 7b5 7#9 - 7#9 + 7#9 7b9 - 7b9 + 7b9 7#5#9 - 7#5#9 + 7#5#9 7#5b9 - 7#5b9 + 7#5b9 7b5b9 - 7b5b9 + 7b5b9 7add11 - 7add11 + 7add11 7add13 - 7add13 + 7add13 7#11 - 7#11 + 7#11 Maj7 - Maj7 + Maj7 Maj7b5 - Maj7b5 + Maj7b5 Maj7#5 - Maj7#5 + Maj7#5 Maj7#11 - Maj7#11 + Maj7#11 Maj7add13 - Maj7add13 + Maj7add13 m7 - m7 + m7 m7b5 - m7b5 + m7b5 m7b9 - m7b9 + m7b9 m7add11 - m7add11 + m7add11 m7add13 - m7add13 + m7add13 m-Maj7 - m-Maj7 + m-Maj7 m-Maj7add11 - m-Maj7add11 + m-Maj7add11 m-Maj7add13 - m-Maj7add13 + m-Maj7add13 9 - 9 + 9 9sus4 - 9sus4 + 9sus4 add9 - add9 + add9 9#5 - 9#5 + 9#5 9b5 - 9b5 + 9b5 9#11 - 9#11 + 9#11 9b13 - 9b13 + 9b13 Maj9 - Maj9 + Maj9 Maj9sus4 - Maj9sus4 + Maj9sus4 Maj9#5 - Maj9#5 + Maj9#5 Maj9#11 - Maj9#11 + Maj9#11 m9 - m9 + m9 madd9 - madd9 + madd9 m9b5 - m9b5 + m9b5 m9-Maj7 - m9-Maj7 + m9-Maj7 11 - 11 + 11 11b9 - 11b9 + 11b9 Maj11 - Maj11 + Maj11 m11 - m11 + m11 m-Maj11 - m-Maj11 + m-Maj11 13 - 13 + 13 13#9 - 13#9 + 13#9 13b9 - 13b9 + 13b9 13b5b9 - 13b5b9 + 13b5b9 Maj13 - Maj13 + Maj13 m13 - m13 + m13 m-Maj13 - m-Maj13 + m-Maj13 Harmonic minor - Harmonisches Moll + Harmonisches Moll Melodic minor - Melodisches Moll + Melodisches Moll Whole tone - Ganze Töne + Ganze Töne Diminished - Vermindert + Vermindert Major pentatonic - Pentatonisches Dur + Pentatonisches Dur Minor pentatonic - Pentatonisches Moll + Pentatonisches Moll Jap in sen - + Major bebop - Dur Bebop + Dur Bebop Dominant bebop - Dominanter Bebop + Dominanter Bebop Blues - Blues + Blues Arabic - Arabisch + Arabisch Enigmatic - Enigmatisch + Enigmatisch Neopolitan - Neopolitanisch + Neopolitanisch Neopolitan minor - Neopolitanisches Moll + Neopolitanisches Moll Hungarian minor - Zigeunermoll + Zigeunermoll Dorian - Dorisch + Dorisch Phrygolydian - Phrygisch + Phrygisch Lydian - Lydisch + Lydisch Mixolydian - Mixolydisch + Mixolydisch Aeolian - Äolisch + Äolisch Locrian - Locrisch + Locrisch Chords - Akkorde + Akkorde Chord type - Akkordtyp + Akkordtyp Chord range - Akkord-Bereich + Akkord-Bereich ChordCreatorView CHORDS - AKKORDE + AKKORDE RANGE - BEREICH + BEREICH Chord range: - Akkord-Bereich: + Akkord-Bereich: octave(s) - Oktave(n) + Oktave(n) Use this knob for setting the chord range in octaves. The selected chord will be played within specified number of octaves. - Benutzen Sie diesen Knopf, um den Akkord-Bereich in Oktaven zu setzen. Der gewähle Akkord wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. + Benutzen Sie diesen Knopf, um den Akkord-Bereich in Oktaven zu setzen. Der gewähle Akkord wird innerhalb der angegebenen Anzahl von Oktaven abgespielt. Controller Controller %1 - Controller %1 + Controller %1 ControllerConnectionDialog Connection Settings - Verbindungseinstellungen + Verbindungseinstellungen MIDI CONTROLLER - MIDI CONTROLLER + MIDI CONTROLLER Input channel - Eingangskanal + Eingangskanal CHANNEL - KANAL + KANAL Input controller - Eingangscontroller + Eingangscontroller CONTROLLER - CONTROLLER + CONTROLLER Auto Detect - Automatische Erkennung + Automatische Erkennung MIDI-devices to receive MIDI-events from - MIDI-Geräte, von denen MIDI-Events empfangen werden sollen + MIDI-Geräte, von denen MIDI-Events empfangen werden sollen USER CONTROLLER - BENUTZERDEFINIETER CONTROLLER + BENUTZERDEFINIETER CONTROLLER MAPPING FUNCTION - ABBILDUNGS-FUNKTION + ABBILDUNGS-FUNKTION OK - OK + OK Cancel - Abbrechen + Abbrechen LMMS - LMMS + LMMS Cycle Detected. - Schleife erkannt. + Schleife erkannt. ControllerRackView Controller Rack - Controller-Einheit + Controller-Einheit Add - Hinzufügen + Hinzufügen ControllerView Controls - Regler + Regler Controllers are able to automate the value of a knob, slider, and other controls. - Mit Controller können Sie den Wert eines Knopfes, Schiebereglers und anderer Steuerelemente automatisieren. + Mit Controller können Sie den Wert eines Knopfes, Schiebereglers und anderer Steuerelemente automatisieren. Rename controller - Controller umbenennen + Controller umbenennen Enter the new name for this controller - Geben Sie einen neuen Namen für diesen Controller ein + Geben Sie einen neuen Namen für diesen Controller ein &Remove this plugin - Plugin entfe&rnen + Plugin entfe&rnen &Help - &Hilfe + &Hilfe + + + + DirectorySelectDialog + + Select directory + Verzeichnis auswählen Effect Effect enabled - Effekt eingeschaltet + Effekt eingeschaltet Wet/Dry mix - Wet/Dry-Mix + Wet/Dry-Mix Gate - Gate + Gate Decay - Abfallzeit + Abfallzeit EffectChain Effects enabled - Effekte aktiviert + Effekte aktiviert EffectRackView EFFECTS CHAIN - EFFEKT-KETTE + EFFEKT-KETTE Add effect - Effekt hinzufügen + Effekt hinzufügen + + + + EffectSelectDialog + + Add effect + Effekt hinzufügen + + + Plugin description + Pluginbeschreibung EffectView Toggles the effect on or off. - Schaltet den Effekt an oder aus. + Schaltet den Effekt an oder aus. On/Off - An/aus + An/aus W/D - W/D + W/D Wet Level: - Wet-Level: + Wet-Level: The Wet/Dry knob sets the ratio between the input signal and the effect signal that forms the output. - Der Wet/Dry-Knopf legt das Verhältnis zwischen Eingangssignal und vom Effekt bearbeiteten Signal im Ausgang fest. + Der Wet/Dry-Knopf legt das Verhältnis zwischen Eingangssignal und vom Effekt bearbeiteten Signal im Ausgang fest. DECAY - DECAY + DECAY Time: - Zeit: + Zeit: The Decay knob controls how many buffers of silence must pass before the plugin stops processing. Smaller values will reduce the CPU overhead but run the risk of clipping the tail on delay and reverb effects. - Der Abfallzeit-Knopf legt fest, wie viele Puffer mit Stille durchgelaufen sein müssen, bis der Effekt mit der Verarbeitung stoppt. Kleinere Werte reduzieren die CPU-Last, können jedoch unter Umständen das Ende von Delay-Effekten o.ä. abschneiden. + Der Abfallzeit-Knopf legt fest, wie viele Puffer mit Stille durchgelaufen sein müssen, bis der Effekt mit der Verarbeitung stoppt. Kleinere Werte reduzieren die CPU-Last, können jedoch unter Umständen das Ende von Delay-Effekten o.ä. abschneiden. GATE - GATE + GATE Gate: - Gate: + Gate: The Gate knob controls the signal level that is considered to be 'silence' while deciding when to stop processing signals. - Der Gate-Knopf legt die Stärke des Signals fest, welches als Stille angesehen wird, um zu entscheiden, wann das Plugin mit der Verarbeitung aufhören kann. + Der Gate-Knopf legt die Stärke des Signals fest, welches als Stille angesehen wird, um zu entscheiden, wann das Plugin mit der Verarbeitung aufhören kann. Controls - Regler + Regler Effect plugins function as a chained series of effects where the signal will be processed from top to bottom. @@ -909,253 +978,253 @@ Right clicking will bring up a context menu where you can change the order in wh Move &up - Nach &oben verschieben + Nach &oben verschieben Move &down - Nach &unten verschieben + Nach &unten verschieben &Remove this plugin - Plugin entfe&rnen + Plugin entfe&rnen &Help - &Hilfe + &Hilfe EnvelopeAndLfoParameters Predelay - Verzögerung (predelay) + Verzögerung (predelay) Attack - Anschwellzeit (attack) + Anschwellzeit (attack) Hold - Haltezeit (hold) + Haltezeit (hold) Decay - Abfallzeit + Abfallzeit Sustain - Haltepegel (sustain) + Haltepegel (sustain) Release - Ausklingzeit (release) + Ausklingzeit (release) Modulation - Modulation + Modulation LFO Predelay - LFO-Verzögerung + LFO-Verzögerung LFO Attack - LFO-Anschwellzeit (LFO-attack) + LFO-Anschwellzeit (LFO-attack) LFO speed - LFO-Geschwindigkeit + LFO-Geschwindigkeit LFO Modulation - LFO Modulation + LFO Modulation LFO Wave Shape - LFO-Wellenform + LFO-Wellenform Freq x 100 - Freq x 100 + Freq x 100 Modulate Env-Amount - Hüllkurve modulieren + Hüllkurve modulieren EnvelopeAndLfoView DEL - DEL + DEL Predelay: - Verzögerung (predelay): + Verzögerung (predelay): Use this knob for setting predelay of the current envelope. The bigger this value the longer the time before start of actual envelope. - Benutzen Sie diesen Knopf, um die Verzögerung (predelay) für die aktuelle Hüllkurven einzustellen. Je größer dieser Wert, desto länger dauert es, bis die eigentliche Hüllkurve beginnt. + Benutzen Sie diesen Knopf, um die Verzögerung (predelay) für die aktuelle Hüllkurven einzustellen. Je größer dieser Wert, desto länger dauert es, bis die eigentliche Hüllkurve beginnt. ATT - ATT + ATT Attack: - Anschwellzeit (attack): + Anschwellzeit (attack): Use this knob for setting attack-time of the current envelope. The bigger this value the longer the envelope needs to increase to attack-level. Choose a small value for instruments like pianos and a big value for strings. - Benutzen Sie diesen Knopf, um die Anschwellzeit (attack) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto länger braucht die Hüllkurve, um bis zum Anschwellpegel (attack-level) zu steigen. Wählen Sie einen kleinen Wert für Instrumente wie Klavier und einen großen Wert für Streichinstrumente. + Benutzen Sie diesen Knopf, um die Anschwellzeit (attack) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto länger braucht die Hüllkurve, um bis zum Anschwellpegel (attack-level) zu steigen. Wählen Sie einen kleinen Wert für Instrumente wie Klavier und einen großen Wert für Streichinstrumente. HOLD - HOLD + HOLD Hold: - Haltezeit (hold): + Haltezeit (hold): Use this knob for setting hold-time of the current envelope. The bigger this value the longer the envelope holds attack-level before it begins to decrease to sustain-level. - Benutzen Sie diesen Knopf, um die Haltezeit (hold) der aktuellen Hüllkurve zu setzen. Je größer der Wert, desto länger hält die Hüllkurve den Anschwellpegel, bevor sie zum Haltepegel (sustain-level) abfällt. + Benutzen Sie diesen Knopf, um die Haltezeit (hold) der aktuellen Hüllkurve zu setzen. Je größer der Wert, desto länger hält die Hüllkurve den Anschwellpegel, bevor sie zum Haltepegel (sustain-level) abfällt. DEC - DEC + DEC Decay: - Abfallzeit (decay): + Abfallzeit (decay): Use this knob for setting decay-time of the current envelope. The bigger this value the longer the envelope needs to decrease from attack-level to sustain-level. Choose a small value for instruments like pianos. - Benutzen Sie diesen Knopf, um die Abfallzeit (decay) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto länger braucht die Hüllkurve, um vom Anschwellpegel (attack-level) zum Dauerpegel (sustain-level) abzufallen. Wählen Sie einen kleinen Wert für Instrumente wie Klavier. + Benutzen Sie diesen Knopf, um die Abfallzeit (decay) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto länger braucht die Hüllkurve, um vom Anschwellpegel (attack-level) zum Dauerpegel (sustain-level) abzufallen. Wählen Sie einen kleinen Wert für Instrumente wie Klavier. SUST - SUST + SUST Sustain: - Dauerpegel (sustain): + Dauerpegel (sustain): Use this knob for setting sustain-level of the current envelope. The bigger this value the higher the level on which the envelope stays before going down to zero. - Benutzen Sie diesen Knopf, um den Dauerpegel (sustain-level) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto höher der Pegel, den die Hüllkurve hält, bevor sie auf Null abfällt. + Benutzen Sie diesen Knopf, um den Dauerpegel (sustain-level) für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto höher der Pegel, den die Hüllkurve hält, bevor sie auf Null abfällt. REL - REL + REL Release: - Ausklingzeit (release): + Ausklingzeit (release): Use this knob for setting release-time of the current envelope. The bigger this value the longer the envelope needs to decrease from sustain-level to zero. Choose a big value for soft instruments like strings. - Benutzen Sie diesen Knopf, um die Ausklingzeit der aktuellen Hüllkurve einzustellen. Je größer der Wert, desto länger braucht die Hüllkurve um vom Dauerpegel (sustain-level) auf Null abzufallen. Wählen Sie einen großen Wert für weiche Instrumente, wie z.B. Streicher. + Benutzen Sie diesen Knopf, um die Ausklingzeit der aktuellen Hüllkurve einzustellen. Je größer der Wert, desto länger braucht die Hüllkurve um vom Dauerpegel (sustain-level) auf Null abzufallen. Wählen Sie einen großen Wert für weiche Instrumente, wie z.B. Streicher. AMT - AMT + AMT Modulation amount: - Modulationsintensität: + Modulationsintensität: Use this knob for setting modulation amount of the current envelope. The bigger this value the more the according size (e.g. volume or cutoff-frequency) will be influenced by this envelope. - Benutzen Sie diesen Knopf, um die Modulationsintensität für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cutoff-Frequenz) von der Hüllkurve beeinflusst. + Benutzen Sie diesen Knopf, um die Modulationsintensität für die aktuelle Hüllkurve einzustellen. Je größer dieser Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cutoff-Frequenz) von der Hüllkurve beeinflusst. LFO predelay: - LFO-Verzögerung: + LFO-Verzögerung: Use this knob for setting predelay-time of the current LFO. The bigger this value the the time until the LFO starts to oscillate. - Benutzen Sie diesen Knopf, um die Verzögerungszeit für den aktuellen LFO einzustellen. Je größer dieser Wert, desto länger die Zeit, bis der LFO anfängt zu schwingen. + Benutzen Sie diesen Knopf, um die Verzögerungszeit für den aktuellen LFO einzustellen. Je größer dieser Wert, desto länger die Zeit, bis der LFO anfängt zu schwingen. LFO- attack: - LFO-Anschwellzeit (LFO-attack): + LFO-Anschwellzeit (LFO-attack): Use this knob for setting attack-time of the current LFO. The bigger this value the longer the LFO needs to increase its amplitude to maximum. - Benutzen Sie diesen Knopf, um die Anschwellzeit für den aktuellen LFO einzustellen. Je größer dieser Wert, desto länger dauert es, bis die Amplitude des LFOs bis zum Maximum angestiegen ist. + Benutzen Sie diesen Knopf, um die Anschwellzeit für den aktuellen LFO einzustellen. Je größer dieser Wert, desto länger dauert es, bis die Amplitude des LFOs bis zum Maximum angestiegen ist. SPD - SPD + SPD LFO speed: - LFO-Geschwindigkeit: + LFO-Geschwindigkeit: Use this knob for setting speed of the current LFO. The bigger this value the faster the LFO oscillates and the faster will be your effect. - Benutzen Sie diesen Knopf, um die Geschwindigkeit für den aktuellen LFO einzustellen. Je größer der Wert, desto schneller schwingt der LFO und desto schneller ist der entsprechende Effekt. + Benutzen Sie diesen Knopf, um die Geschwindigkeit für den aktuellen LFO einzustellen. Je größer der Wert, desto schneller schwingt der LFO und desto schneller ist der entsprechende Effekt. Use this knob for setting modulation amount of the current LFO. The bigger this value the more the selected size (e.g. volume or cutoff-frequency) will be influenced by this LFO. - Benutzen Sie diesen Knopf, um die Modulationsintensität des aktuellen LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. + Benutzen Sie diesen Knopf, um die Modulationsintensität des aktuellen LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. Click here for a sine-wave. - Klick für eine Sinuswelle. + Klick für eine Sinuswelle. Click here for a triangle-wave. - Klick für eine Dreieckswelle. + Klick für eine Dreieckswelle. Click here for a saw-wave for current. - Klick für eine Sägezahnwelle. + Klick für eine Sägezahnwelle. Click here for a square-wave. - Klick für eine Rechteckswelle. + Klick für eine Rechteckswelle. Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. - Hier klicken für eine benutzerdefinierte Wellenform. Danach eine entsprechende Sampledatei auf den LFO-Graphen ziehen. + Hier klicken für eine benutzerdefinierte Wellenform. Danach eine entsprechende Sampledatei auf den LFO-Graphen ziehen. FREQ x 100 - FREQ x 100 + FREQ x 100 Click here if the frequency of this LFO should be multiplied by 100. - Hier klicken, wenn die Frequenz des LFOs mit 100 multipliziert werden soll. + Hier klicken, wenn die Frequenz des LFOs mit 100 multipliziert werden soll. multiply LFO-frequency by 100 - LFO-Frequenz mit 100 multiplizieren + LFO-Frequenz mit 100 multiplizieren MODULATE ENV-AMOUNT - HÜLLK. MODULIEREN + HÜLLK. MODULIEREN Click here to make the envelope-amount controlled by this LFO. - Klicken Sie hier, um die Hüllkurvenintensität durch diesen LFO kontrollieren zu lassen. + Klicken Sie hier, um die Hüllkurvenintensität durch diesen LFO kontrollieren zu lassen. control envelope-amount by this LFO - Hüllkurvenintensität durch diesen LFO kontrollieren + Hüllkurvenintensität durch diesen LFO kontrollieren ms/LFO: - ms/LFO: + ms/LFO: Hint - Tipp + Tipp Drag a sample from somewhere and drop it in this window. - Ziehen Sie ein Sample von irgendwo und lassen es in diesem Fenster fallen. + Ziehen Sie ein Sample von irgendwo und lassen es in diesem Fenster fallen. @@ -1163,54 +1232,198 @@ Right clicking will bring up a context menu where you can change the order in wh Could not open file %1 for writing. Please make sure you have write-permission to the file and the directory containing the file and try again! - Die Datei %1 konnte nicht zum Schreiben geöffnet werden. + Die Datei %1 konnte nicht zum Schreiben geöffnet werden. Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei und das Verzeichnis, das diese Datei enthält, besitzen und versuchen es erneut! Could not open file - Konnte Datei nicht öffnen + Konnte Datei nicht öffnen Export project to %1 - Projekt nach %1 exportieren + Projekt nach %1 exportieren Error - Fehler + Fehler Error while determining file-encoder device. Please try to choose a different output format. - Fehler beim Bestimmen des Datei-Enkoder-Geräts. Bitte wählen Sie ein anderes Ausgabeformat. + Fehler beim Bestimmen des Datei-Enkoder-Geräts. Bitte wählen Sie ein anderes Ausgabeformat. Rendering: %1% - Rendere: %1% + Rendere: %1% + + + Export project + Projekt exportieren + + + Output + Ausgabe + + + File format: + Dateiformat: + + + Samplerate: + + + + 44100 Hz + 44100 Hz + + + 48000 Hz + 48000 Hz + + + 88200 Hz + 88200 Hz + + + 96000 Hz + 96000 Hz + + + 192000 Hz + 192000 Hz + + + Bitrate: + Bitrate: + + + 64 KBit/s + 64 KBit/s + + + 128 KBit/s + 128 KBit/s + + + 160 KBit/s + 160 KBit/s + + + 192 KBit/s + 192 KBit/s + + + 256 KBit/s + 256 KBit/s + + + 320 KBit/s + 320 KBit/s + + + Depth: + + + + 16 Bit Integer + 16 Bit Integer + + + 24 Bit Integer + + + + 32 Bit Float + 32 Bit Gleitkommazahlen + + + Please note that not all of the parameters above apply for all file formats. + Bitte beachten Sie, dass nicht alle diese Parameter für alle Dateiformate zutreffen. + + + Quality settings + Qualitätseinstellungen + + + Interpolation: + Interpolation: + + + Zero Order Hold + + + + Sinc Fastest + Sinc schnell + + + Sinc Medium (recommended) + Sinc Medium (empfohlen) + + + Sinc Best (very slow!) + Sinc am besten (sehr langsam!) + + + Oversampling (use with care!): + Oversampling (mit Vorsicht benutzen!): + + + 1x (None) + 1x (keine) + + + 2x + 2x + + + 4x + 4x + + + 8x + 8x + + + Sample-exact controllers + Sample-genaue Controller + + + Alias-free oscillators + Alias-freie Oszillatoren + + + Start + Start + + + Cancel + Abbrechen FxMixer Master - Master + Master FX %1 - FX %1 + FX %1 FxMixerView Rename FX channel - FX-Kanal umbenennen + FX-Kanal umbenennen Enter the new name for this FX channel - Bitte einen neuen Namen für den FX-Kanal eingeben + Bitte einen neuen Namen für den FX-Kanal eingeben FX-Mixer - FX-Mixer + FX-Mixer FX Fader %1 @@ -1218,447 +1431,447 @@ Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei und das Verzeic Mute - Stumm + Stumm Mute this FX channel - Diesen FX-Kanal stummschalten + Diesen FX-Kanal stummschalten InstrumentMidiIOView ENABLE MIDI INPUT - MIDI-EINGANG AKTIVIEREN + MIDI-EINGANG AKTIVIEREN CHANNEL - KANAL + KANAL VELOCITY - LAUTSTÄRKE + LAUTSTÄRKE ENABLE MIDI OUTPUT - MIDI-AUSGANG AKTIVIEREN + MIDI-AUSGANG AKTIVIEREN PROGRAM - PROGRAMM + PROGRAMM MIDI devices to receive MIDI events from - + MIDI Geräte, von denen MIDI-Events empfangen werden sollen MIDI devices to send MIDI events to - + MIDI-Geräte, an die MIDI-Events gesendet werden sollen InstrumentSoundShaping VOLUME - LAUTSTÄRKE + LAUTSTÄRKE Volume - Lautstärke + Lautstärke CUTOFF - KENNFREQ + KENNFREQ Cutoff frequency - Kennfrequenz + Kennfrequenz RESO - RESO + RESO Resonance - Resonanz + Resonanz Envelopes/LFOs - Hüllkurven/LFOs + Hüllkurven/LFOs Filter type - Filtertyp + Filtertyp Q/Resonance - Q/Resonanz + Q/Resonanz LowPass - Tiefpass + Tiefpass HiPass - Hochpass + Hochpass BandPass csg - Bandpass csg + Bandpass csg BandPass czpg - Bandpass czpg + Bandpass czpg Notch - Notch + Notch Allpass - Allpass + Allpass Moog - Moog + Moog 2x LowPass - 2x Tiefpass + 2x Tiefpass RC LowPass 12dB - + RC Tiefpass 12dB RC BandPass 12dB - + RC Bandpass 12dB RC HighPass 12dB - + RC Hochpass 12dB RC LowPass 24dB - + RC Tiefpass 24dB RC BandPass 24dB - + RC Bandpass 24dB RC HighPass 24dB - + RC Hochpass 24dB Vocal Formant Filter - + Vokal-Formant-Filter InstrumentSoundShapingView TARGET - ZIEL + ZIEL These tabs contain envelopes. They're very important for modifying a sound, in that they are almost always neccessary for substractive synthesis. For example if you have a volume envelope, you can set when the sound should have a specific volume. If you want to create some soft strings then your sound has to fade in and out very softly. This can be done by setting large attack and release times. It's the same for other envelope targets like panning, cutoff frequency for the used filter and so on. Just monkey around with it! You can really make cool sounds out of a saw-wave with just some envelopes...! - Diese Tabs enthalten Hüllkurven. Diese sind sehr wichtig, um einen Klang zu verändern, insbesondere bei der substraktiven Synthese. Wenn Sie zum Beispiel eine Lautstärke-Hüllkurve haben, können Sie festlegen, wann der Klang welchen Lautstärke-Pegel haben soll. Vielleicht wollen Sie ein weiches Streichinstrument erstellen. Dann muss ihr Sound sehr sanft ein- und ausgeblendet werden. Das kann man ganz einfach erreichen, indem man eine große Anschwell(attack)- und Ausklingzeit (release) einstellt. Mit anderen Hüllkurven, wie Balance, Kennfrequenz des benutzten Filters usw., ist es genau das Gleiche. Probieren Sie einfach ein bisschen herum! Mit ein paar Hüllkurven kann man aus einer Sägezahn-Welle wirklich coole Klänge machen...! + Diese Tabs enthalten Hüllkurven. Diese sind sehr wichtig, um einen Klang zu verändern, insbesondere bei der substraktiven Synthese. Wenn Sie zum Beispiel eine Lautstärke-Hüllkurve haben, können Sie festlegen, wann der Klang welchen Lautstärke-Pegel haben soll. Vielleicht wollen Sie ein weiches Streichinstrument erstellen. Dann muss ihr Sound sehr sanft ein- und ausgeblendet werden. Das kann man ganz einfach erreichen, indem man eine große Anschwell(attack)- und Ausklingzeit (release) einstellt. Mit anderen Hüllkurven, wie Balance, Kennfrequenz des benutzten Filters usw., ist es genau das Gleiche. Probieren Sie einfach ein bisschen herum! Mit ein paar Hüllkurven kann man aus einer Sägezahn-Welle wirklich coole Klänge machen...! FILTER - FILTER + FILTER Here you can select the built-in filter you want to use for this instrument-track. Filters are very important for changing the characteristics of a sound. - Hier können Sie den eingebauten Filter wählen, den Sie in dieser Instrument-Spur nutzen wollen. Filter sind sehr wichtig, um die Charakteristik eines Klangs zu verändern. + Hier können Sie den eingebauten Filter wählen, den Sie in dieser Instrument-Spur nutzen wollen. Filter sind sehr wichtig, um die Charakteristik eines Klangs zu verändern. CUTOFF - KENNFREQ + KENNFREQ cutoff-frequency: - Kennfrequenz: + Kennfrequenz: Hz - Hz + Hz Use this knob for setting the cutoff frequency for the selected filter. The cutoff frequency specifies the frequency for cutting the signal by a filter. For example a lowpass-filter cuts all frequencies above the cutoff frequency. A highpass-filter cuts all frequencies below cutoff frequency, and so on... - Benutzen Sie diesen Knopf, um die Kennfrequenz (cutoff-frequency) für den gewählten Filter einzustellen. Die Kennfrequenz wird vom Filter zum Beschneiden des Signals verwendet. Zum Beispiel filtert ein Tiefpass-Filter alle Frequenzen oberhalb der Kennfrequenz heraus. Ein Hochpass-Filter filtert alle Frequenzen unterhalb der Kennfrequenz heraus usw... + Benutzen Sie diesen Knopf, um die Kennfrequenz (cutoff-frequency) für den gewählten Filter einzustellen. Die Kennfrequenz wird vom Filter zum Beschneiden des Signals verwendet. Zum Beispiel filtert ein Tiefpass-Filter alle Frequenzen oberhalb der Kennfrequenz heraus. Ein Hochpass-Filter filtert alle Frequenzen unterhalb der Kennfrequenz heraus usw... RESO - RESO + RESO Resonance: - Resonanz: + Resonanz: Use this knob for setting Q/Resonance for the selected filter. Q/Resonance tells the filter how much it should amplify frequencies near Cutoff-frequency. - Benutzen Sie diesen Knopf, um Q/die Resonanz für den gewählten Filter einzustellen. Q/Resonanz teilt dem Filter mit, wie stark er die Frequenzen in der Nähe der Cutoff-Frequenz verstärken soll. + Benutzen Sie diesen Knopf, um Q/die Resonanz für den gewählten Filter einzustellen. Q/Resonanz teilt dem Filter mit, wie stark er die Frequenzen in der Nähe der Cutoff-Frequenz verstärken soll. InstrumentTrack unnamed_track - Unbenannter_Kanal + Unbenannter_Kanal Volume - Lautstärke + Lautstärke Panning - Panning + Panning Pitch - Tonhöhe + Tonhöhe Pitch range - + Tonhöhen-Bereich FX channel - FX-Kanal + FX-Kanal Default preset - Standard-Preset + Standard-Preset InstrumentTrackView Volume - Lautstärke + Lautstärke Volume: - Lautstärke: + Lautstärke: VOL - VOL + VOL Panning - Panning + Panning Panning: - Panning: + Panning: PAN - PAN + PAN MIDI - MIDI + MIDI Input - Eingang + Eingang Output - Ausgang + Ausgang InstrumentTrackWindow GENERAL SETTINGS - GRUNDLEGENDE EINSTELLUNGEN + GRUNDLEGENDE EINSTELLUNGEN Save instrument track settings in a preset file - + Instrumentspur-Einstellungen in einer Preset-Datei speichern Click here, if you want to save current channel settings in a preset-file. Later you can load this preset by double-clicking it in the preset-browser. - Klicken Sie hier, wenn Sie die aktuellen Kanal-Einstellungen in einer Preset-Datei speichern wollen. Spätern können Sie dieses Preset laden, indem Sie es im Preset-Browser doppelt anklicken. + Klicken Sie hier, wenn Sie die aktuellen Kanal-Einstellungen in einer Preset-Datei speichern wollen. Spätern können Sie dieses Preset laden, indem Sie es im Preset-Browser doppelt anklicken. Instrument volume - Instrument-Lautstärke + Instrument-Lautstärke Volume: - Lautstärke: + Lautstärke: VOL - VOL + VOL Panning - Panning + Panning Panning: - Panning: + Panning: PAN - PAN + PAN Pitch - Tonhöhe + Tonhöhe Pitch: - Tonhöhe: + Tonhöhe: cents - Cent + Cent PITCH - PITCH + PITCH Pitch range (semitones) - + Tonhöhen-Bereich (Halbtöne) RANGE - BEREICH + BEREICH FX channel - FX-Kanal + FX-Kanal FX CHNL - FX KANAL + FX KANAL ENV/LFO - ENV/LFO + ENV/LFO FUNC - FUNC + FUNC FX - FX + FX MIDI - MIDI + MIDI Save preset - Preset speichern + Preset speichern XML preset file (*.xpf) - XML Preset Datei (*.xpf) + XML Preset Datei (*.xpf) PLUGIN - PLUGIN + PLUGIN LadspaControl Link channels - Kanäle verbinden + Kanäle verbinden LadspaControlDialog Link Channels - Kanäle verbinden + Kanäle verbinden Channel - Kanal + Kanal LadspaControlView Link channels - Kanäle verbinden + Kanäle verbinden Value: - Wert: + Wert: Sorry, no help available. - Sorry, keine Hilfe verfügbar. + Sorry, keine Hilfe verfügbar. LadspaEffect Effect - Effekt + Effekt Unknown LADSPA plugin %1 requested. - Unbekanntes LADSPA-Plugin %1 angefordert. + Unbekanntes LADSPA-Plugin %1 angefordert. LfoController LFO Controller - LFO-Controller + LFO-Controller Base value - Grundwert + Grundwert Oscillator speed - Oszillator-Geschwindigkeit + Oszillator-Geschwindigkeit Oscillator amount - Oszillator-Stärke + Oszillator-Stärke Oscillator phase - Oszillator-Phase + Oszillator-Phase Oscillator waveform - Oszillator-Wellenform + Oszillator-Wellenform Frequency Multiplier - Frequenzmultiplikator + Frequenzmultiplikator LfoControllerDialog LFO - LFO + LFO LFO Controller - LFO-Controller + LFO-Controller BASE - BASE + BASE Base amount: @@ -1670,27 +1883,27 @@ Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei und das Verzeic SPD - SPD + SPD LFO-speed: - LFO-Geschwindigkeit: + LFO-Geschwindigkeit: Use this knob for setting speed of the LFO. The bigger this value the faster the LFO oscillates and the faster the effect. - Benutzen Sie diesen Knopf, um die Geschwindigkeit des LFOs einzustellen. Je größer der Wert, desto schneller schwingt der LFO und desto schneller ist der entsprechende Effekt. + Benutzen Sie diesen Knopf, um die Geschwindigkeit des LFOs einzustellen. Je größer der Wert, desto schneller schwingt der LFO und desto schneller ist der entsprechende Effekt. AMT - AMT + AMT Modulation amount: - Modulationsintensität: + Modulationsintensität: Use this knob for setting modulation amount of the LFO. The bigger this value, the more the connected control (e.g. volume or cutoff-frequency) will be influenced by the LFO. - Benutzen Sie diesen Knopf, um die Modulationsintensität des LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. + Benutzen Sie diesen Knopf, um die Modulationsintensität des LFOs einzustellen. Je größer der Wert, desto mehr wird die gewählte Größe (z.B. Lautstärke oder Cuttoff-Frequenz) von diesem LFO beeinflusst. PHS @@ -1698,116 +1911,116 @@ Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei und das Verzeic Phase offset: - Phasenverschiebung: + Phasenverschiebung: degrees - Grad + Grad With this knob you can set the phase offset of the LFO. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. - Mit diesem Knopf können Sie die Phasen-Verschiebung des LFOs einstellen. Das heißt, Sie können den Punkt innerhalb einer Schwingung verschieben, an dem der Oszillator anfangen soll zu schwingen. Wenn Sie zum Beispiel eine Sinus-Welle haben und eine Phasen-Verschiebung von 180 Grad einstellen, wird die Welle zu erst runter gehen. Das gleiche trifft auch bei einer Rechteck-Welle zu. + Mit diesem Knopf können Sie die Phasen-Verschiebung des LFOs einstellen. Das heißt, Sie können den Punkt innerhalb einer Schwingung verschieben, an dem der Oszillator anfangen soll zu schwingen. Wenn Sie zum Beispiel eine Sinus-Welle haben und eine Phasen-Verschiebung von 180 Grad einstellen, wird die Welle zu erst runter gehen. Das gleiche trifft auch bei einer Rechteck-Welle zu. Click here for a sine-wave. - Klick für eine Sinuswelle. + Klick für eine Sinuswelle. Click here for a triangle-wave. - Klick für eine Dreieckswelle. + Klick für eine Dreieckswelle. Click here for a saw-wave. - Klick für eine Sägezahnwelle. + Klick für eine Sägezahnwelle. Click here for a square-wave. - Klick für eine Rechteckswelle. + Klick für eine Rechteckswelle. Click here for a a moog saw-wave. - Klick für eine Moog-ähnliche Welle. + Klick für eine Moog-ähnliche Welle. Click here for an exponential wave. - + Klick für eine Exponential-Welle. Click here for white-noise. - Klick für weißes Rauschen. + Klick für weißes Rauschen. Click here for a user-defined shape. - Klick für eine benutzerdefinierte Wellenform. + Klick für eine benutzerdefinierte Wellenform. MainWindow Working directory - Arbeitsverzeichnis + Arbeitsverzeichnis The LMMS working directory %1 does not exist. Create it now? You can change the directory later via Edit -> Settings. - Das LMMS-Arbeitsverzeichnis %1 existiert nicht. Soll es jetzt erstellt werden? Sie können das Verzeichnis später über Bearbeiten -> Einstellungen ändern. + Das LMMS-Arbeitsverzeichnis %1 existiert nicht. Soll es jetzt erstellt werden? Sie können das Verzeichnis später über Bearbeiten -> Einstellungen ändern. Could not save config-file - Konnte Konfigurationsdatei nicht speichern + Konnte Konfigurationsdatei nicht speichern Could not save configuration file %1. You're probably not permitted to write to this file. Please make sure you have write-access to the file and try again. - Konnte die Konfigurationsdatei %1 nicht speichern. Sie haben möglicherweise keine Schreibrechte auf diese Datei. + Konnte die Konfigurationsdatei %1 nicht speichern. Sie haben möglicherweise keine Schreibrechte auf diese Datei. Bitte überprüfen Sie Ihre Rechte und versuchen es erneut. &Project - &Projekt + &Projekt &New - &Neu + &Neu &Open... - Ö&ffnen... + Ö&ffnen... Recently opened projects - Zuletzt geöffnete Projekte + Zuletzt geöffnete Projekte &Save - &Speichern + &Speichern Save &As... - Speichern &als... + Speichern &als... Import... - Importieren... + Importieren... E&xport... - E&xportieren... + E&xportieren... &Quit - &Beenden + &Beenden &Edit - &Bearbeiten + &Bearbeiten Undo - Rückgängig + Rückgängig Redo - Wiederherstellen + Wiederherstellen Load resource into current context @@ -1815,147 +2028,147 @@ Bitte überprüfen Sie Ihre Rechte und versuchen es erneut. Settings - Einstellungen + Einstellungen &Tools - &Werkzeuge + &Werkzeuge &Help - &Hilfe + &Hilfe Online help - Online-Hilfe + Online-Hilfe Help - Hilfe + Hilfe What's this? - Was ist das? + Was ist das? About - Über + Über Create new project - Neues Projekt erstellen + Neues Projekt erstellen Create new project from template - Neues Projekt aus Vorlage erstellen + Neues Projekt aus Vorlage erstellen Open existing project - Existierendes Projekt öffnen + Existierendes Projekt öffnen Recently opened project - Zuletzt geöffnete Projekte + Zuletzt geöffnete Projekte Save current project - Aktuelles Projekt speichern + Aktuelles Projekt speichern Export current project - Aktuelles Projekt exportieren + Aktuelles Projekt exportieren Show/hide Song-Editor - Zeige/verstecke Song-Editor + Zeige/verstecke Song-Editor By pressing this button, you can show or hide the Song-Editor. With the help of the Song-Editor you can edit song-playlist and specify when which track should be played. You can also insert and move samples (e.g. rap samples) directly into the playlist. - Mit diesem Knopf können Sie den Song-Editor zeigen oder verstecken. Mit Hilfe des Song-Editors können Sie die Song-Playliste bearbeiten und angeben, wann welche Spur abgespielt werden soll. Außerdem können Sie Samples (z.B. Rap samples) direkt in die Playliste einfügen und verschieben. + Mit diesem Knopf können Sie den Song-Editor zeigen oder verstecken. Mit Hilfe des Song-Editors können Sie die Song-Playliste bearbeiten und angeben, wann welche Spur abgespielt werden soll. Außerdem können Sie Samples (z.B. Rap samples) direkt in die Playliste einfügen und verschieben. Show/hide Beat+Bassline Editor - Zeige/verstecke Beat+Bassline Editor + Zeige/verstecke Beat+Bassline Editor By pressing this button, you can show or hide the Beat+Bassline Editor. The Beat+Bassline Editor is needed for creating beats, and for opening, adding, and removing channels, and for cutting, copying and pasting beat and bassline-patterns, and for other things like that. - Mit diesem Knopf können Sie den Beat+Bassline-Editor zeigen oder verstecken. Mit dem Beat+Bassline-Editor kann man Beats erstellen, Bassline-Patterns bearbeiten uvm. + Mit diesem Knopf können Sie den Beat+Bassline-Editor zeigen oder verstecken. Mit dem Beat+Bassline-Editor kann man Beats erstellen, Bassline-Patterns bearbeiten uvm. Show/hide Piano-Roll - Zeige/verstecke Piano-Roll + Zeige/verstecke Piano-Roll Click here to show or hide the Piano-Roll. With the help of the Piano-Roll you can edit melodies in an easy way. - Hier klicken, um das Piano-Roll zu zeigen oder verstecken. Mit Hilfe des Piano-Rolls können Sie Melodien auf einfache Art und Weise bearbeiten. + Hier klicken, um das Piano-Roll zu zeigen oder verstecken. Mit Hilfe des Piano-Rolls können Sie Melodien auf einfache Art und Weise bearbeiten. Show/hide Automation Editor - Zeige/Verstecke Automation-Editor + Zeige/Verstecke Automation-Editor Click here to show or hide the Automation Editor. With the help of the Automation Editor you can edit dynamic values in an easy way. - Hier klicken, um den Automation-Editor zu zeigen oder verstecken. Mit Hilfe des Automation-Editors können Sie Automation-Patterns auf einfache Art und Weise bearbeiten. + Hier klicken, um den Automation-Editor zu zeigen oder verstecken. Mit Hilfe des Automation-Editors können Sie Automation-Patterns auf einfache Art und Weise bearbeiten. Show/hide FX Mixer - Zeige/verstecke FX-Mixer + Zeige/verstecke FX-Mixer Click here to show or hide the FX Mixer. The FX Mixer is a very powerful tool for managing effects for your song. You can insert effects into different effect-channels. - Hier klicken, um den FX-Mixer zu zeigen oder verstecken. Der FX-Mixer ist ein leistungsfähiges Werkzeug, um Effekte für Ihren Song zu verwalten. Sie können verschiedene Effekte in unterschiedliche Effekt-Kanäle einfügen. + Hier klicken, um den FX-Mixer zu zeigen oder verstecken. Der FX-Mixer ist ein leistungsfähiges Werkzeug, um Effekte für Ihren Song zu verwalten. Sie können verschiedene Effekte in unterschiedliche Effekt-Kanäle einfügen. Show/hide project notes - Zeige/verstecke Projekt-Notizen + Zeige/verstecke Projekt-Notizen Click here to show or hide the project notes window. In this window you can put down your project notes. - Hier klicken, um die Projektnotizen zu zeigen oder verstecken. + Hier klicken, um die Projektnotizen zu zeigen oder verstecken. Show/hide controller rack - Zeige/verstecke Controller-Rack + Zeige/verstecke Controller-Rack Tempo - Tempo + Tempo TEMPO/BPM - TEMPO/BPM + TEMPO/BPM tempo of song - Geschwindigkeit des Songs + Geschwindigkeit des Songs The tempo of a song is specified in beats per minute (BPM). If you want to change the tempo of your song, change this value. Every measure has four beats, so the tempo in BPM specifies, how many measures / 4 should be played within a minute (or how many measures should be played within four minutes). - Das Tempo eines Liedes wird in Beats pro Minute (BPM) angegeben. Wenn Sie das Tempo Ihres Songs ändern wollen, ändern Sie diesen Wert. Jeder Takt hat vier Schläge (Beats); das Tempo gibt also an, wie viele Takte / 4 innerhalb einer Minute gespielt werden sollen (bzw. wie viele Takte innerhalb von vier Minuten gespielt werden sollen). + Das Tempo eines Liedes wird in Beats pro Minute (BPM) angegeben. Wenn Sie das Tempo Ihres Songs ändern wollen, ändern Sie diesen Wert. Jeder Takt hat vier Schläge (Beats); das Tempo gibt also an, wie viele Takte / 4 innerhalb einer Minute gespielt werden sollen (bzw. wie viele Takte innerhalb von vier Minuten gespielt werden sollen). High quality mode - High-Quality-Modus + High-Quality-Modus Master volume - Master-Lautstärke + Master-Lautstärke master volume - Master-Lautstärke + Master-Lautstärke Master pitch - Master-Tonhöhe + Master-Tonhöhe master pitch - Master-Tonhöhe + Master-Tonhöhe PLAYBACK - + WIEDERGABE Play/pause the project (Space) @@ -1975,324 +2188,324 @@ Bitte überprüfen Sie Ihre Rechte und versuchen es erneut. Song - + Song Playback: song mode - + Wiedergabe: Song-Modus B+B - + B+B Playback: beat+bassline mode - + Wiedergabe: Beat+Bassline-Modus Piano Roll - + Piano Roll Playback: piano roll mode - + Wiedergabe: Piano-Roll-Modus Audio-device - + Audiogerät Automation - + Automation MIDI - MIDI + MIDI RECORD - + AUFNAHME Untitled - Unbenannt + Unbenannt LMMS %1 - LMMS %1 + LMMS %1 Project not saved - Projekt nicht gespeichert + Projekt nicht gespeichert The current project was modified since last saving. Do you want to save it now? - Das aktuelle Projekt wurde seit dem letzten Speichern geändert. Wollen Sie es jetzt speichern? + Das aktuelle Projekt wurde seit dem letzten Speichern geändert. Wollen Sie es jetzt speichern? Open project - Projekt öffnen + Projekt öffnen MultiMedia Project (*.mmp *.mmpz *.xml) - MultiMedia Projekt (*.mmp *.mmpz *.xml) + MultiMedia Projekt (*.mmp *.mmpz *.xml) Save project - Projekt speichern + Projekt speichern MultiMedia Project (*.mmp *.mmpz);;MultiMedia Project Template (*.mpt) - MultiMedia Projekt (*.mmp *.mmpz);;MultiMedia Projekt-Vorlage (*.mpt) + MultiMedia Projekt (*.mmp *.mmpz);;MultiMedia Projekt-Vorlage (*.mpt) Help not available - Hilfe nicht verfügbar + Hilfe nicht verfügbar Currently there's no help available in LMMS. Please visit http://lmms.sf.net/wiki for documentation on LMMS. - Derzeit ist in LMMS keine Hilfe verfügbar. + Derzeit ist in LMMS keine Hilfe verfügbar. Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. Value: %1% - Wert: %1% + Wert: %1% Value: %1 semitones - Wert: %1 Halbtöne + Wert: %1 Halbtöne MeterDialog Meter Numerator - Takt/Zähler + Takt/Zähler Meter Denominator - Takt/Nenner + Takt/Nenner TIME SIG - TAKTART + TAKTART MeterModel Numerator - Zähler + Zähler Denominator - Nenner + Nenner MidiAlsaRaw::setupWidget DEVICE - GERÄT + GERÄT MidiAlsaSeq::setupWidget DEVICE - GERÄT + GERÄT MidiController MIDI Controller - MIDI-Controller + MIDI-Controller unnamed_midi_controller - unbenannter_midi_controller + unbenannter_midi_controller MidiImport Setup incomplete - + Unvollständige Einrichtung You do not have set up a default soundfont in the settings dialog (Edit->Settings). Therefore no sound will be played back after importing this MIDI file. You should download a General MIDI soundfont, specify it in settings dialog and try again. - + Sie haben keine Standard-Soundfont im Einstellungsdialog (Bearbeiten->Einstellungen) festgelegt. Aus diesem Grund werden Sie nach dem Import der MIDI-Datei während der Wiedergabe nichts hören. Sie sollten eine General-MIDI-Soundfont herunterladen, diese im Einstellungsdialog angeben und es erneut versuchen. You did not compile LMMS with support for SoundFont2 player, which is used to add default sound to imported MIDI files. Therefore no sound will be played back after importing this MIDI file. - + Sie haben LMMS ohne das SoundFont2-Player-Plugin gebaut. Dieses Plugin wird normalerweise benutzt, um Standardklänge bei importierten MIDI-Dateien einzurichten. Aus diesem Grund werden Sie nach dem Import der MIDI-Datei nichts hören. MidiOss::setupWidget DEVICE - GERÄT + GERÄT MidiPort Input channel - Eingangskanal + Eingangskanal Output channel - Ausgangskanal + Ausgangskanal Input controller - Eingangscontroller + Eingangscontroller Output controller - Ausgangscontroller + Ausgangscontroller Fixed input velocity - Feste Eingangslautstärke + Feste Eingangslautstärke Fixed output velocity - Feste Ausgangslautstärke + Feste Ausgangslautstärke Output MIDI program - Ausgangs-MIDI-Programm + Ausgangs-MIDI-Programm Receive MIDI-events - MIDI-Ereignisse empfangen + MIDI-Ereignisse empfangen Send MIDI-events - MIDI-Ereignisse senden + MIDI-Ereignisse senden OscillatorObject Osc %1 volume - Oszillator %1 Lautstärke + Oszillator %1 Lautstärke Osc %1 panning - Oszillator %1 Balance + Oszillator %1 Balance Osc %1 coarse detuning - Oszillator %1 Grob-Verstimmung + Oszillator %1 Grob-Verstimmung Osc %1 fine detuning left - Oszillator %1 Fein-Verstimmung links + Oszillator %1 Fein-Verstimmung links Osc %1 fine detuning right - Oszillator %1 Fein-Verstimmung rechts + Oszillator %1 Fein-Verstimmung rechts Osc %1 phase-offset - Oszillator %1 Phasen-Verschiebung + Oszillator %1 Phasen-Verschiebung Osc %1 stereo phase-detuning - Oszillator %1 Stereo Phasen-Verschiebung + Oszillator %1 Stereo Phasen-Verschiebung Osc %1 phase randomness - + Osc %1 Phasenzufälligkeit (phase randomness) Osc %1 wave shape - Oszillator %1 Wellenform + Oszillator %1 Wellenform Modulation type %1 - Modulationsart %1 + Modulationsart %1 Osc %1 waveform - Oszillator %1 Wellenform + Oszillator %1 Wellenform PatmanView Open other patch - Andere Patch-Datei öffnen + Andere Patch-Datei öffnen Click here to open another patch-file. Loop and Tune settings are not reset. - Klicken Sie hier, um eine andere Patch-Datei zu laden. Wiederholungs- und Stimmungseinstellungen werden nicht zurückgesetzt. + Klicken Sie hier, um eine andere Patch-Datei zu laden. Wiederholungs- und Stimmungseinstellungen werden nicht zurückgesetzt. Loop - Wiederholen + Wiederholen Loop mode - Modus beim Wiederholen + Modus beim Wiederholen Here you can toggle the Loop mode. If enabled, PatMan will use the loop information available in the file. - Hier können Sie den Wiederholen-Modus (de-)aktivieren. Wenn aktiviert, verwendet PatMan die in der Datei verfügbaren Informationen zum Wiederholen. + Hier können Sie den Wiederholen-Modus (de-)aktivieren. Wenn aktiviert, verwendet PatMan die in der Datei verfügbaren Informationen zum Wiederholen. Tune - Stimmung + Stimmung Tune mode - Stimmungsmodus + Stimmungsmodus Here you can toggle the Tune mode. If enabled, PatMan will tune the sample to match the note's frequency. - Hier können Sie den Stimmungs-Modus (de-)aktivieren. Wenn aktiviert, wird der Klang automatisch an die Frequenz der Note angepasst. + Hier können Sie den Stimmungs-Modus (de-)aktivieren. Wenn aktiviert, wird der Klang automatisch an die Frequenz der Note angepasst. No file selected - Keine Datei ausgewählt + Keine Datei ausgewählt Open patch file - Patch-Datei öffnen + Patch-Datei öffnen Patch-Files (*.pat) - Patch-Dateien (*.pat) + Patch-Dateien (*.pat) PeakController Peak Controller - Peak Controller + Peak Controller PeakControllerDialog PEAK - PEAK + PEAK LFO Controller - LFO-Controller + LFO-Controller PeakControllerEffectControlDialog BASE - BASE + BASE Base amount: @@ -2300,11 +2513,11 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. AMT - AMT + AMT Modulation amount: - Modulationsintensität: + Modulationsintensität: ATTACK @@ -2312,92 +2525,92 @@ Bitte besuchen Sie http://lmms.sf.net/wiki für Dokumentationen über LMMS. Attack: - Anschwellzeit (attack): + Anschwellzeit (attack): DECAY - DECAY + DECAY Release: - Ausklingzeit (release): + Ausklingzeit (release): PeakControllerEffectControls Base value - Grundwert + Grundwert Modulation amount - Modulationsintensität + Modulationsintensität Attack - Anschwellzeit (attack) + Anschwellzeit (attack) Release - Ausklingzeit (release) + Ausklingzeit (release) Mute output - Ausgang stummschalten + Ausgang stummschalten PianoView Base note - Grundton + Grundton Plugin Plugin not found - Plugin nicht gefunden + Plugin nicht gefunden The plugin "%1" wasn't found or could not be loaded! Reason: "%2" - Das Plugin "%1" konnte nicht gefunden oder geladen werden! + Das Plugin "%1" konnte nicht gefunden oder geladen werden! Grund: "%2" Error while loading plugin - Fehler beim Laden des Plugins + Fehler beim Laden des Plugins Failed to load plugin "%1"! - Das Plugin "%1" konnte nicht geladen werden! + Das Plugin "%1" konnte nicht geladen werden! ProjectRenderer WAV-File (*.wav) - WAV-Datei (*.wav) + WAV-Datei (*.wav) Compressed OGG-File (*.ogg) - Komprimierte OGG-Datei (*.ogg) + Komprimierte OGG-Datei (*.ogg) MP3 File (*.mp3) - + MP3-Datei (*.mp3) FLAC File (*.flac) - + FLAC-Datei (*.flac) QObject Unrecognized audio format - + Nicht erkanntes Audioformat None of the available audio decoders recognized the format you are trying to load. Try converting the file to a format LMMS understands. @@ -2409,27 +2622,27 @@ Available decoders: %2 File not found - + Datei nicht gefunden The file %1 could not be found! You should set a valid file in order to allow proper playback. - + Die Datei %1 wurde nicht gefunden. Sie sollten eine existierende Datei festlegen, um eine ordnungsgemäße Wiedergabe zu ermöglichen. Unable to load LAME - + Konnte LAME nicht laden LMMS was unable to load Lame MP3 encoder. Please make sure you have Lame installed and then check your folder settings and make sure you tell LMMS where libmp3lame.so.0 is. - + LMMS konnte den LAME-MP3-Enkoder nicht laden. Bitte stellen Sie sicher, dass Sie LAME installiert haben, überprüfen ihre Ordnereinstellungen und stellen sicher, dass Sie LMMS mitgeteilt haben, wo sich libmp3lame.so.0 befindet. LAME missing symbols - + Fehlende Symbole in LAME Some symbols are missing from your Lame library. Make sure you have the latest version of Lame and/or LMMS installed. - + Einige Symbole fehlen in Ihrer LAME-Bibliothek. Stellen Sie sicher, dass Sie die neueste Version von LAME und/oder LMMS installiert haben. @@ -2479,299 +2692,314 @@ Available decoders: %2 Datei: + + QuickLoadDialog + + Load resource + Ressource laden + + + Resource type: + Ressourcentyp: + + + All types + Alle Typen + + ResourceBrowser Show/edit properties - + Eigenschaften zeigen/bearbeiten Load project - + Projekt laden Load in new track in Song Editor - + In neuer Spur im Song-Editor laden Load in new track in B+B Editor - + In neuer Spur in B+B-Editor laden Load into active instrument track - + In aktive Instrumentspur laden Download into collection - + In Sammlung herunterladen Upload to WWW - + Ins WWW hochladen Delete resource - + Ressource löschen Import file - Datei importieren + Datei importieren Resource Browser - + Ressourcen-Browser Manage locations - + Orte verwalten Show piano - + Piano zeigen ResourceDB Directory - + Verzeichnis Sample - + Sample Preset - + Preset Plugin-specific resource - + Plugin-spezifische Ressource Project - + Projekt MIDI file - + MIDI-Datei Foreign project - + Externes Projekt Plugin - + Plugin Image - + Bild Unknown - + Unbekannt ResourceModel My LMMS files - + Meine LMMS-Dateien Shipped LMMS files - + Mitgelieferte LMMS-Dateien TempoSyncKnob Tempo Sync - Tempo-Synchronisation + Tempo-Synchronisation No Sync - Keine Synchronisation + Keine Synchronisation Eight beats - Acht Schläge + Acht Schläge Whole note - Ganze Note + Ganze Note Half note - Halbe Note + Halbe Note Quarter note - Viertelnote + Viertelnote 8th note - Achtelnote + Achtelnote 16th note - 16tel Note + 16tel Note 32nd note - 32tel Note + 32tel Note Custom... - Benutzerdefiniert... + Benutzerdefiniert... &Help - &Hilfe + &Hilfe Custom - Benutzerdefiniert + Benutzerdefiniert Synced to Eight Beats - Mit acht Schlägen synchronisiert + Mit acht Schlägen synchronisiert Synced to Whole Note - Mit ganzer Note synchronisiert + Mit ganzer Note synchronisiert Synced to Half Note - Mit halber Note synchronisiert + Mit halber Note synchronisiert Synced to Quarter Note - Mit Viertelnote synchronisiert + Mit Viertelnote synchronisiert Synced to 8th Note - Mit Achtelnote synchronisiert + Mit Achtelnote synchronisiert Synced to 16th Note - Mit 16tel Note synchronisiert + Mit 16tel Note synchronisiert Synced to 32nd Note - Mit 32tel Note synchronisiert + Mit 32tel Note synchronisiert TripleOscillatorView Use phase modulation for modulating oscillator 2 with oscillator 1 - Phasenmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren + Phasenmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren Use amplitude modulation for modulating oscillator 2 with oscillator 1 - Amplitudenmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren + Amplitudenmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren Mix output of oscillator 1 & 2 - Mische Ausgang von Oszillator 1 & 2 + Mische Ausgang von Oszillator 1 & 2 Synchronize oscillator 1 with oscillator 2 - Synchronisiere Oszillator 1 mit Oszillator 2 + Synchronisiere Oszillator 1 mit Oszillator 2 Use frequency modulation for modulating oscillator 2 with oscillator 1 - Frequenzmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren + Frequenzmodulation benutzen, um Oszillator 2 mit Oszillator 1 zu modulieren Use phase modulation for modulating oscillator 3 with oscillator 2 - Phasenmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren + Phasenmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren Use amplitude modulation for modulating oscillator 3 with oscillator 2 - Amplitudenmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren + Amplitudenmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren Mix output of oscillator 2 & 3 - Mische Ausgang von Oszillator 2 & 3 + Mische Ausgang von Oszillator 2 & 3 Synchronize oscillator 2 with oscillator 3 - Synchronisiere Oszillator 2 mit Oszillator 3 + Synchronisiere Oszillator 2 mit Oszillator 3 Use frequency modulation for modulating oscillator 3 with oscillator 2 - Frequenzmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren + Frequenzmodulation benutzen, um Oszillator 3 mit Oszillator 2 zu modulieren Osc %1 volume: - Oszillator %1 Lautstärke: + Oszillator %1 Lautstärke: With this knob you can set the volume of oscillator %1. When setting a value of 0 the oscillator is turned off. Otherwise you can hear the oscillator as loud as you set it here. - Mit diesem Knopf können Sie die Lautstärke von Oszillator %1 setzen. Wenn Sie einen Wert von 0 setzen, wird der Oszillator ausgeschaltet. Ansonsten können Sie ihn so laut hören, wie Sie es hier einstellen. + Mit diesem Knopf können Sie die Lautstärke von Oszillator %1 setzen. Wenn Sie einen Wert von 0 setzen, wird der Oszillator ausgeschaltet. Ansonsten können Sie ihn so laut hören, wie Sie es hier einstellen. Osc %1 panning: - Oszillator %1 Balance: + Oszillator %1 Balance: With this knob you can set the panning of the oscillator %1. A value of -100 means 100% left and a value of 100 moves oscillator-output right. - Mit diesem Knopf können Sie die Balance von Oszillator %1 setzen. Ein Wert von -100 heißt 100% links und ein Wert von 100 verschiebt den Oszillator-Ausgang nach rechts. + Mit diesem Knopf können Sie die Balance von Oszillator %1 setzen. Ein Wert von -100 heißt 100% links und ein Wert von 100 verschiebt den Oszillator-Ausgang nach rechts. Osc %1 coarse detuning: - Oszillator %1 Grob-Verstimmung: + Oszillator %1 Grob-Verstimmung: semitones - Halbtöne + Halbtöne With this knob you can set the coarse detuning of oscillator %1. You can detune the oscillator 12 semitones (1 octave) up and down. This is useful for creating sounds with a chord. - Mit diesem Knopf können Sie die grobe Verstimmung von Oszillator %1 setzen. Sie können den Oszillator 12 Halbtöne (1 Oktave) nach oben und unten verstimmen. Das ist nützlich, wenn Sie einen Sound mit einem Akkord erstellen möchten. + Mit diesem Knopf können Sie die grobe Verstimmung von Oszillator %1 setzen. Sie können den Oszillator 12 Halbtöne (1 Oktave) nach oben und unten verstimmen. Das ist nützlich, wenn Sie einen Sound mit einem Akkord erstellen möchten. Osc %1 fine detuning left: - Oszillator %1 Fein-Verstimmung links: + Oszillator %1 Fein-Verstimmung links: cents - Cent + Cent With this knob you can set the fine detuning of oscillator %1 for the left channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. - Mit diesem Knopf können Sie die Fein-Verstimmung von Oszillator %1 für den linken Kanal einstellen. Die Fein-Verstimmung liegt zwischen -100 Cent und +100 Cent. Das ist nützlich, um "fette" Sounds zu erzeugen. + Mit diesem Knopf können Sie die Fein-Verstimmung von Oszillator %1 für den linken Kanal einstellen. Die Fein-Verstimmung liegt zwischen -100 Cent und +100 Cent. Das ist nützlich, um "fette" Sounds zu erzeugen. Osc %1 fine detuning right: - Oszillator %1 Fein-Verstimmung rechts: + Oszillator %1 Fein-Verstimmung rechts: With this knob you can set the fine detuning of oscillator %1 for the right channel. The fine-detuning is ranged between -100 cents and +100 cents. This is useful for creating "fat" sounds. - Mit diesem Knopf können Sie die Fein-Verstimmung von Oszillator %1 für den rechten Kanal einstellen. Die Fein-Verstimmung liegt zwischen -100 Cent und +100 Cent. Das ist nützlich, um "fette" Sounds zu erzeugen. + Mit diesem Knopf können Sie die Fein-Verstimmung von Oszillator %1 für den rechten Kanal einstellen. Die Fein-Verstimmung liegt zwischen -100 Cent und +100 Cent. Das ist nützlich, um "fette" Sounds zu erzeugen. Osc %1 phase-offset: - Oszillator %1 Phasen-Verschiebung: + Oszillator %1 Phasen-Verschiebung: degrees - Grad + Grad With this knob you can set the phase-offset of oscillator %1. That means you can move the point within an oscillation where the oscillator begins to oscillate. For example if you have a sine-wave and have a phase-offset of 180 degrees the wave will first go down. It's the same with a square-wave. - Mit diesem Knopf können Sie die Phasen-Verschiebung von Oszillator %1 setzen. Das heißt, Sie können den Punkt innerhalb einer Schwingung verschieben, an dem der Oszillator anfangen soll zu schwingen. Wenn Sie zum Beispiel eine Sinus-Welle haben und eine Phasen-Verschiebung von 180 Grad einstellen, wird die Welle zu erst runter gehen. Das gleiche trifft auch bei einer Rechteck-Welle zu. + Mit diesem Knopf können Sie die Phasen-Verschiebung von Oszillator %1 setzen. Das heißt, Sie können den Punkt innerhalb einer Schwingung verschieben, an dem der Oszillator anfangen soll zu schwingen. Wenn Sie zum Beispiel eine Sinus-Welle haben und eine Phasen-Verschiebung von 180 Grad einstellen, wird die Welle zu erst runter gehen. Das gleiche trifft auch bei einer Rechteck-Welle zu. Osc %1 stereo phase-detuning: - Oszillator %1 Stereo Phasen-Verschiebung: + Oszillator %1 Stereo Phasen-Verschiebung: With this knob you can set the stereo phase-detuning of oscillator %1. The stereo phase-detuning specifies the size of the difference between the phase-offset of left and right channel. This is very good for creating wide stereo sounds. - Mit diesem Knopf können Sie die Stereo Phasen-Verschiebung von Oszillator %1 setzen. Die Stereo Phasen-Verschiebung gibt die Differenz zwischen den Phasen-Verschiebungen zwischen dem linken und rechten Kanal an. Dies eignet sich gut, um großräumig-klingende Stereo-Klänge zu erzeugen. + Mit diesem Knopf können Sie die Stereo Phasen-Verschiebung von Oszillator %1 setzen. Die Stereo Phasen-Verschiebung gibt die Differenz zwischen den Phasen-Verschiebungen zwischen dem linken und rechten Kanal an. Dies eignet sich gut, um großräumig-klingende Stereo-Klänge zu erzeugen. Osc %1 phase randomness: @@ -2783,110 +3011,181 @@ Available decoders: %2 Use a sine-wave for current oscillator. - Sinuswelle für aktuellen Oszillator nutzen. + Sinuswelle für aktuellen Oszillator nutzen. Use a triangle-wave for current oscillator. - Dreieckswelle für aktuellen Oszillator nutzen. + Dreieckswelle für aktuellen Oszillator nutzen. Use a saw-wave for current oscillator. - Sägezahnwelle für aktuellen Oszillator nutzen. + Sägezahnwelle für aktuellen Oszillator nutzen. Use a square-wave for current oscillator. - Rechteckswelle für aktuellen Oszillator nutzen. + Rechteckswelle für aktuellen Oszillator nutzen. Use a moog-like saw-wave for current oscillator. - Moog-ähnliche Sägezahnwelle für aktuellen Oszillator nutzen. + Moog-ähnliche Sägezahnwelle für aktuellen Oszillator nutzen. Use an exponential wave for current oscillator. - Exponentialwelle für aktuellen Oszillator nutzen. + Exponentialwelle für aktuellen Oszillator nutzen. Use white-noise for current oscillator. - Weißes Rauschen für aktuellen Oszillator nutzen. + Weißes Rauschen für aktuellen Oszillator nutzen. Use a user-defined waveform for current oscillator. - Benutzerdefinierte Wellenform für aktuellen Oszillator nutzen. + Benutzerdefinierte Wellenform für aktuellen Oszillator nutzen. VestigeInstrumentView Open other VST-plugin - Anderes VST-Plugin laden + Anderes VST-Plugin laden Click here, if you want to open another VST-plugin. After clicking on this button, a file-open-dialog appears and you can select your file. - Klicken Sie hier, wenn Sie ein anderes VST-Plugin öffnen möchten. Nachdem Sie auf diesen Button geklickt haben, erscheint ein Datei-öffnen-Dialog und Sie können Ihre Datei wählen. + Klicken Sie hier, wenn Sie ein anderes VST-Plugin öffnen möchten. Nachdem Sie auf diesen Button geklickt haben, erscheint ein Datei-öffnen-Dialog und Sie können Ihre Datei wählen. Show/hide GUI - GUI zeigen/verstecken + GUI zeigen/verstecken Click here to show or hide the graphical user interface (GUI) of your VST-plugin. - Klicken Sie hier, um die grafische Oberfläche (GUI) Ihers VST-Plugins anzuzeigen bzw. zu verstecken. + Klicken Sie hier, um die grafische Oberfläche (GUI) Ihres VST-Plugins anzuzeigen bzw. zu verstecken. Turn off all notes - Alle Noten ausschalten + Alle Noten ausschalten Open VST-plugin - VST-Plugin öffnen + VST-Plugin öffnen DLL-files (*.dll) - DLL-Dateien (*.dll) + DLL-Dateien (*.dll) EXE-files (*.exe) - EXE-Dateien (*.exe) + EXE-Dateien (*.exe) No VST-plugin loaded - Kein VST-Plugin geladen + Kein VST-Plugin geladen by - von + von VstPlugin Loading plugin - Lade Plugin + Lade Plugin Please wait while loading VST-plugin... - Bitte warten, während das VST-Plugin geladen wird... + Bitte warten, während das VST-Plugin geladen wird... Failed loading VST-plugin - Laden des VST-Plugins fehlgeschlagen + Laden des VST-Plugins fehlgeschlagen The VST-plugin %1 could not be loaded for some reason. If it runs with other VST-software under Linux, please contact an LMMS-developer! - Das VST-Plugin %1 konnte aus irgendeinem Grund nicht geladen werden. -Wenn es mit anderer VST-software unter Linux funktioniert, kontaktieren Sie bitte einen LMMS-Entwickler! + Das VST-Plugin %1 konnte aus irgendeinem Grund nicht geladen werden. +Wenn es mit anderer VST-Software unter Linux funktioniert, kontaktieren Sie bitte einen LMMS-Entwickler! + + + + WelcomeScreen + + Welcome to LMMS + Willkommen zu LMMS + + + New project + Neues Projekt + + + Import project + Projekt importieren + + + Open tutorial + Tutorial öffnen + + + Instant MIDI action + Sofort mit MIDI loslegen + + + Recent projects + Letzte Projekte + + + Recent community resources + Letzte Community-Ressourcen + + + Did you know...? + Wussten Sie...? + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + Onlineressourcen + + + Users forum + Benutzerforum + + + http://sourceforge.net/apps/phpbb/lmms/ + http://sourceforge.net/apps/phpbb/lmms/ + + + Online manual + Onlinehandbuch + + + http://lmms.sourceforge.net/wiki/NewManual + http://lmms.sourceforge.net/wiki/NewManual + + + Wiki + Wiki + + + http://lmms.sourceforge.net/wiki/ + http://lmms.sourceforge.net/wiki/ ZynAddSubFxView Show GUI - + GUI anzeigen Click here to show or hide the graphical user interface (GUI) of ZynAddSubFX. - + Klicken Sie hier, um die grafische Oberfläche von ZynAddSubFX anzuzeigen bzw. auszublenden. @@ -3705,23 +4004,23 @@ Double clicking any of the plugins will bring up information on the ports.lv2BrowserView Available Effects - Verfügbare Effekte + Verfügbare Effekte Unavailable Effects - Nicht verfügbare Effekte + Nicht verfügbare Effekte Instruments - Instrumente + Instrumente Analysis Tools - Analysewerkzeuge + Analysewerkzeuge Don't know - Weiß nicht + Weiß nicht This dialog displays information on all of the LV2 plugins LMMS was able to locate. The plugins are divided into five categories based upon an interpretation of the port types and names. @@ -3741,65 +4040,65 @@ Double clicking any of the plugins will bring up information on the ports. Type: - Typ: + Typ: lv2Description Plugins - Plugins + Plugins Description - Beschreibung + Beschreibung lv2PortDialog Ports - Ports + Ports Name - Name + Name Rate - Rate + Rate Direction - Richtung + Richtung Type - Typ + Typ Min < Default < Max - Min < Standard < Max + Min < Standard < Max Audio - Audio + Audio Control - Steuerung + Steuerung Input - Eingang + Eingang Output - Ausgang + Ausgang Float - Kommazahl + Kommazahl @@ -4554,7 +4853,7 @@ Lautstärke eines Steps kann mit Mausrad geändert werden Detune mode (Shift+T) - + Verstimmungsmodus (Shift+T) Click here and draw mode will be activated. In this mode you can add, resize and move notes. This is the default mode which is used most of the time. You can also press 'Shift+D' on your keyboard to activate this mode. In this mode, hold Ctrl to temporarily go into select mode. @@ -4687,7 +4986,7 @@ Dieser Chip wurde in Commodore 64 Computern genutzt. Embedded ZynAddSubFX - + Eingebettetes ZynAddSubFX-Plugin @@ -5102,15 +5401,15 @@ Latenz: %2 ms Lame MP3 Library - + LAME MP3-Bibliothek MIDI REMOTE CONTROL - + MIDI-FERNSTEUERUNG CHANNEL - KANAL + KANAL MIDI-device to receive remote control events from @@ -5141,27 +5440,27 @@ Latenz: %2 ms setupDialogMCL New action - + Neue Aktion OK - OK + OK Cancel - Abbrechen + Abbrechen MIDI KEYBOARD - + MIDI-KEYBOARD MIDI CONTROLLER - MIDI CONTROLLER + MIDI-CONTROLLER CONTROLLER - CONTROLLER + CONTROLLER @@ -5586,15 +5885,15 @@ Bitte stellen Sie sicher, dass Sie Schreibrechte auf diese Datei besitzen und ve Could not open file %1. You probably have no permissions to read this file. Please make sure to have at least read permissions to the file and try again. - + Konnte die Datei %1 nicht öffnen. Sie sind möglicherweise nicht berechtigt, diese Datei zu lesen. Bitte stellen Sie sicher, dass sie wenigstens Leserechte auf die Datei haben und versuchen es erneut. Error in file - + Fehler in Datei The file %1 seems to contain errors and therefore can't be loaded. - + Die Datei %1 scheint fehlerhaft zu sein und kann daher nicht geladen werden. @@ -6132,7 +6431,7 @@ Die LED rechts unterhalb der Wellenform gibt an, ob die Saite aktiviert ist. Click to enable - + Klick zur Aktivierung diff --git a/data/locale/en.ts b/data/locale/en.ts index b588639f9..f0a8dc935 100644 --- a/data/locale/en.ts +++ b/data/locale/en.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + + FxMixer @@ -2475,6 +2688,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2873,6 +3101,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/es.ts b/data/locale/es.ts index f1172de02..d662f99e0 100644 --- a/data/locale/es.ts +++ b/data/locale/es.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Ayuda + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Cancelar + FxMixer @@ -2475,6 +2688,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2874,6 +3102,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/fr.ts b/data/locale/fr.ts index c59bb20d9..4b88aeb75 100644 --- a/data/locale/fr.ts +++ b/data/locale/fr.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + À propos + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Aide + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1186,6 +1255,150 @@ Assurez-vous d'avoir les droits d'accès en écriture au fichier et au Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Annuler + FxMixer @@ -2476,6 +2689,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2874,6 +3102,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/ir.ts b/data/locale/ir.ts index f8d877ee8..1ec177519 100644 --- a/data/locale/ir.ts +++ b/data/locale/ir.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + درباره + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &راهنما + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + لغو + FxMixer @@ -2475,6 +2688,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2873,6 +3101,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/it.ts b/data/locale/it.ts index 286a4619a..3205e4674 100644 --- a/data/locale/it.ts +++ b/data/locale/it.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + Informazioni su + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Aiuto + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ Aggiungi effetto + + EffectSelectDialog + + Add effect + Aggiungi effetto + + + Plugin description + + + EffectView @@ -1119,7 +1188,7 @@ Con il click destro si apre un menu conestuale che permette di cambiare l'o Click here for a triangle-wave. - + Cliccando qui si ottiene un'onda triangolare. Click here for a saw-wave for current. @@ -1127,7 +1196,7 @@ Con il click destro si apre un menu conestuale che permette di cambiare l'o Click here for a square-wave. - + Cliccando qui si ottiene un'onda quadra. Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. @@ -1180,7 +1249,7 @@ Assicurarsi di avere i permessi in scrittura per il file e la directory contenen Could not open file - + Non è stato possibile aprire il file Export project to %1 @@ -1198,6 +1267,150 @@ Assicurarsi di avere i permessi in scrittura per il file e la directory contenen Rendering: %1% Renderizzazione: %1% + + Export project + + + + Output + Uscita + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Annulla + FxMixer @@ -1726,15 +1939,15 @@ Assicurarsi di avere i permessi in scrittura per il file e la directory contenen Click here for a triangle-wave. - + Cliccando qui si ottiene un'onda triangolare. Click here for a saw-wave. - + Cliccando qui si ottiene un'onda a dente di sega. Click here for a square-wave. - + Cliccando qui si ottiene un'onda quadra. Click here for a a moog saw-wave. @@ -1750,7 +1963,7 @@ Assicurarsi di avere i permessi in scrittura per il file e la directory contenen Click here for a user-defined shape. - + Cliccando qui è possibile definire una forma d'onda personalizzata. @@ -2247,7 +2460,7 @@ Visitare http://lmms.sf.net/wiki per la documentazione di LMMS. Loop - + Ripetizione Loop mode @@ -2491,6 +2704,21 @@ Available decoders: %2 In Place Broken: + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2719,7 +2947,7 @@ Available decoders: %2 Osc %1 volume: - + Volume osc %1: With this knob you can set the volume of oscillator %1. When setting a value of 0 the oscillator is turned off. Otherwise you can hear the oscillator as loud as you set it here. @@ -2727,7 +2955,7 @@ Available decoders: %2 Osc %1 panning: - + Panning osc %1: With this knob you can set the panning of the oscillator %1. A value of -100 means 100% left and a value of 100 moves oscillator-output right. @@ -2747,7 +2975,7 @@ Available decoders: %2 Osc %1 fine detuning left: - + Intonazione precisa osc %1 sinistra: cents @@ -2873,19 +3101,91 @@ Available decoders: %2 VstPlugin Loading plugin - + Caricamento plugin Please wait while loading VST-plugin... - + Prego attendere, caricamento del plugin VST... Failed loading VST-plugin - + Errore nel caricamento del plugin VST The VST-plugin %1 could not be loaded for some reason. If it runs with other VST-software under Linux, please contact an LMMS-developer! + Non è stato possibile caricare il plugin VST %1 a causa di alcuni errori. +Se, con altre applicazioni GNU/Linux il plugin funziona, si prega di contattare uno sviluppatore di LMMS! + + + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ diff --git a/data/locale/ja.ts b/data/locale/ja.ts index d6a871217..c10bb3f4f 100644 --- a/data/locale/ja.ts +++ b/data/locale/ja.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ ヘルプ(&H) + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ エフェクト追加 + + EffectSelectDialog + + Add effect + エフェクト追加 + + + Plugin description + + + EffectView @@ -1181,7 +1250,7 @@ Please make sure you have write-permission to the file and the directory contain Could not open file - + ファイルをオープンã§ãã¾ã›ã‚“ Export project to %1 @@ -1199,6 +1268,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% レンダリング: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + キャンセル + FxMixer @@ -1743,7 +1956,7 @@ Please make sure you have write-permission to the file and the directory contain Click here for an exponential wave. - + ã‚¯ãƒªãƒƒã‚¯ã§æŒ‡æ•°æ³¢å½¢ Click here for white-noise. @@ -1751,7 +1964,7 @@ Please make sure you have write-permission to the file and the directory contain Click here for a user-defined shape. - + クリックã™ã‚‹ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼æ³¢å½¢ @@ -2493,6 +2706,21 @@ Available decoders: %2 ファイル + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2879,7 +3107,7 @@ Available decoders: %2 Please wait while loading VST-plugin... - + VST-プラグインをロードã™ã‚‹é–“ãŠå¾…ã¡ãã ã•ã„ Failed loading VST-plugin @@ -2888,6 +3116,78 @@ Available decoders: %2 The VST-plugin %1 could not be loaded for some reason. If it runs with other VST-software under Linux, please contact an LMMS-developer! + VST-plugin %1 ãŒã„ãã¤ã‹ã®ç†ç”±ã§ãƒ­ãƒ¼ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ +ã‚‚ã—ãã®VSTãŒLinuxã®ã»ã‹ã®VST-ソフトウェアã§å‹•ããªã‚‰ LMMS ã®é–‹ç™ºè€…ã«é€£çµ¡ã—ã¦ãã ã•ã„。 + + + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ diff --git a/data/locale/ko.ts b/data/locale/ko.ts index ae1cac787..0454d1e0c 100644 --- a/data/locale/ko.ts +++ b/data/locale/ko.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + LMMS란 + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -57,7 +108,7 @@ Sync - + ë™ê¸° @@ -755,7 +806,7 @@ Cancel - + 취소 LMMS @@ -804,6 +855,13 @@ ë„움ë§(&H) + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ 효과 ë”하기 + + EffectSelectDialog + + Add effect + 효과 ë”하기 + + + Plugin description + + + EffectView @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + 출력 + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + 취소 + FxMixer @@ -2477,6 +2690,21 @@ Available decoders: %2 파ì¼: + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2859,15 +3087,15 @@ Available decoders: %2 VstPlugin Loading plugin - + í”ŒëŸ¬ê·¸ì¸ ì½ëŠ” 중 Please wait while loading VST-plugin... - + VST í”ŒëŸ¬ê·¸ì¸ ì½ì€ ë™ì•ˆ 잠시 대기... Failed loading VST-plugin - + VST í”ŒëŸ¬ê·¸ì¸ ì½ëŠ” 중 오류 The VST-plugin %1 could not be loaded for some reason. @@ -2875,6 +3103,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView @@ -5146,7 +5445,7 @@ Latency: %2 ms Cancel - + 취소 MIDI KEYBOARD diff --git a/data/locale/nl.ts b/data/locale/nl.ts index e0de1be4c..39ce871cf 100644 --- a/data/locale/nl.ts +++ b/data/locale/nl.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + Over + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Help + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1167,7 +1236,7 @@ Please make sure you have write-permission to the file and the directory contain Could not open file - + Kan bestand niet openen Export project to %1 @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + + FxMixer @@ -2475,6 +2688,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2874,6 +3102,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer Als het wel werkt met andere VST-software onder Linux, neem dan contact op met een LMMS-ontwikkelaar! + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/pt_br.ts b/data/locale/pt_br.ts index 015e20fd6..3517aad21 100644 --- a/data/locale/pt_br.ts +++ b/data/locale/pt_br.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + Sobre + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ Aj&uda + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1168,7 +1237,7 @@ Por favor certifique-se que você tem permissão para gravação no arquivo e se Could not open file - + Não é possível abrir o arquivo Export project to %1 @@ -1186,6 +1255,150 @@ Por favor certifique-se que você tem permissão para gravação no arquivo e se Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Cancelar + FxMixer @@ -2476,6 +2689,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2875,6 +3103,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer Se ele rodar com outro programa VST no Linux, por favor entre em contato com um desenvolvedor do LMMS! + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/locale/ru.ts b/data/locale/ru.ts index 11d0075ad..c2158eb62 100644 --- a/data/locale/ru.ts +++ b/data/locale/ru.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + О программе + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Справка + + DirectorySelectDialog + + Select directory + + + Effect @@ -820,7 +878,7 @@ Decay - + Длит. Ñпада @@ -841,6 +899,17 @@ Добавить фильтр + + EffectSelectDialog + + Add effect + Добавить фильтр + + + Plugin description + + + EffectView @@ -953,7 +1022,7 @@ Right clicking will bring up a context menu where you can change the order in wh Decay - + Длит. Ñпада Sustain @@ -1120,7 +1189,7 @@ Right clicking will bring up a context menu where you can change the order in wh Click here for a triangle-wave. - + Сгенерировать треугольный Ñигнал. Click here for a saw-wave for current. @@ -1128,7 +1197,7 @@ Right clicking will bring up a context menu where you can change the order in wh Click here for a square-wave. - + Сгенерировать меандр. Click here for a user-defined wave. Afterwards, drag an according sample-file onto the LFO graph. @@ -1199,6 +1268,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% Обработка: %1% + + Export project + + + + Output + Выход + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Отменить + FxMixer @@ -1728,15 +1941,15 @@ Please make sure you have write-permission to the file and the directory contain Click here for a triangle-wave. - + Сгенерировать треугольный Ñигнал. Click here for a saw-wave. - + Сгенерировать пилообразный Ñигнал. Click here for a square-wave. - + Сгенерировать меандр. Click here for a a moog saw-wave. @@ -2493,6 +2706,21 @@ Available decoders: %2 Выходных каналов: + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2892,6 +3120,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer ЕÑли другое программное обеÑпечение VST работает у Ð’Ð°Ñ Ð¿Ð¾Ð´ Linux'ом, ÑвÑжитеÑÑŒ Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð¼ LMMS! + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView @@ -3566,7 +3865,7 @@ Double clicking any of the plugins will bring up information on the ports. Click here for a saw-wave. - + Сгенерировать пилообразный Ñигнал. Triangle wave @@ -3574,7 +3873,7 @@ Double clicking any of the plugins will bring up information on the ports. Click here for a triangle-wave. - + Сгенерировать треугольный Ñигнал. Square wave @@ -3582,7 +3881,7 @@ Double clicking any of the plugins will bring up information on the ports. Click here for a square-wave. - + Сгенерировать меандр. Rounded square wave diff --git a/data/locale/sv.ts b/data/locale/sv.ts index 6f333ecad..fdce93019 100644 --- a/data/locale/sv.ts +++ b/data/locale/sv.ts @@ -1,6 +1,57 @@ + + AboutDialog + + About LMMS + + + + LMMS (Linux MultiMedia Studio) + + + + Version %1 (%2/%3, Qt %4, %5) + + + + About + Om + + + LMMS - easy music production for everyone + + + + Copyright (c) 2004-2009, LMMS developers + + + + http://lmms.sourceforge.net + +Join us on Freenode (irc.freenode.net) in ##lmms! + + + + Authors + + + + Translation + + + + Current language not translated (or native English). + +If you're interested in translating LMMS in another language or want to improve existing translations, you're welcome to help us! Simply contact the maintainer! + + + + License + + + Arpeggiator @@ -804,6 +855,13 @@ &Hjälp + + DirectorySelectDialog + + Select directory + + + Effect @@ -841,6 +899,17 @@ + + EffectSelectDialog + + Add effect + + + + Plugin description + + + EffectView @@ -1167,7 +1236,7 @@ Please make sure you have write-permission to the file and the directory contain Could not open file - + kunde inte öppna fil Export project to %1 @@ -1185,6 +1254,150 @@ Please make sure you have write-permission to the file and the directory contain Rendering: %1% + + Export project + + + + Output + + + + File format: + + + + Samplerate: + + + + 44100 Hz + + + + 48000 Hz + + + + 88200 Hz + + + + 96000 Hz + + + + 192000 Hz + + + + Bitrate: + + + + 64 KBit/s + + + + 128 KBit/s + + + + 160 KBit/s + + + + 192 KBit/s + + + + 256 KBit/s + + + + 320 KBit/s + + + + Depth: + + + + 16 Bit Integer + + + + 24 Bit Integer + + + + 32 Bit Float + + + + Please note that not all of the parameters above apply for all file formats. + + + + Quality settings + + + + Interpolation: + + + + Zero Order Hold + + + + Sinc Fastest + + + + Sinc Medium (recommended) + + + + Sinc Best (very slow!) + + + + Oversampling (use with care!): + + + + 1x (None) + + + + 2x + + + + 4x + + + + 8x + + + + Sample-exact controllers + + + + Alias-free oscillators + + + + Start + + + + Cancel + Avbryt + FxMixer @@ -2475,6 +2688,21 @@ Available decoders: %2 + + QuickLoadDialog + + Load resource + + + + Resource type: + + + + All types + + + ResourceBrowser @@ -2873,6 +3101,77 @@ If it runs with other VST-software under Linux, please contact an LMMS-developer + + WelcomeScreen + + Welcome to LMMS + + + + New project + + + + Import project + + + + Open tutorial + + + + Instant MIDI action + + + + Recent projects + + + + Recent community resources + + + + Did you know...? + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Linux Biolinum O'; font-size:12pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + + Online resources + + + + Users forum + + + + http://sourceforge.net/apps/phpbb/lmms/ + + + + Online manual + + + + http://lmms.sourceforge.net/wiki/NewManual + + + + Wiki + + + + http://lmms.sourceforge.net/wiki/ + + + ZynAddSubFxView diff --git a/data/themes/cusis/main_toolbar_bg.png b/data/themes/cusis/main_toolbar_bg.png deleted file mode 100644 index ca5c4ca9a..000000000 Binary files a/data/themes/cusis/main_toolbar_bg.png and /dev/null differ diff --git a/data/themes/cusis/style.css b/data/themes/cusis/style.css index 110e386d2..c158e9bad 100644 --- a/data/themes/cusis/style.css +++ b/data/themes/cusis/style.css @@ -52,6 +52,28 @@ automationEditor { background-color: rgb(0, 0, 0); } +#WelcomeFrame { + border: 2px solid rgb(32,32,32); + border-radius: 8px; + padding:2px; +} + +#TitleSeparator { + border: 1px solid qlineargradient(x1:0, y1:0, x2:1, y2:0, + stop:0 #ccc, stop: 0.5 #444, + stop:1 #ccc); + border-width: 1px 0px 0px 0px; +} +#WelcomeFrame, #WelcomeFrame * { + background-color: rgb(232,232,232); + color: black; +} + +#WelcomeFrame QLabel { + color: rgb(128, 128, 128); +} + + QMenu { border:1px solid black; background-color: rgb( 192, 192, 192 ); @@ -131,13 +153,20 @@ nameLabel, effectLabel, sf2InstrumentView > QLabel { QWidget#mainToolbar { - background-image: url(resources:main_toolbar_bg.png); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #4a4a4a, stop: 1.0 #383838); } QToolBar { - background: url(resources:toolbar_bg.png); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #4a4a4a, stop: 1.0 #383838); } +SideBar { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 #66728c, stop: 1.0 #38404e); +} + +SideBar QToolButton { + font-size: 12px; +} FxMixerView QPushButton, EffectRackView QPushButton, ControllerRackView QPushButton { font-size: 10px; diff --git a/data/themes/cusis/toolbar_bg.png b/data/themes/cusis/toolbar_bg.png deleted file mode 100644 index ada851ff2..000000000 Binary files a/data/themes/cusis/toolbar_bg.png and /dev/null differ diff --git a/data/themes/default/folder-64.png b/data/themes/default/folder-64.png new file mode 100644 index 000000000..6a93840b0 Binary files /dev/null and b/data/themes/default/folder-64.png differ diff --git a/data/themes/default/main_toolbar_bg.png b/data/themes/default/main_toolbar_bg.png deleted file mode 100644 index d6e662ab3..000000000 Binary files a/data/themes/default/main_toolbar_bg.png and /dev/null differ diff --git a/data/themes/default/preferences-desktop-sound.png b/data/themes/default/preferences-desktop-sound.png new file mode 100644 index 000000000..efdedd742 Binary files /dev/null and b/data/themes/default/preferences-desktop-sound.png differ diff --git a/data/themes/default/preferences-system.png b/data/themes/default/preferences-system.png new file mode 100644 index 000000000..9ea5cec44 Binary files /dev/null and b/data/themes/default/preferences-system.png differ diff --git a/data/themes/default/setup-midi.png b/data/themes/default/setup-midi.png new file mode 100755 index 000000000..ec43e3f66 Binary files /dev/null and b/data/themes/default/setup-midi.png differ diff --git a/data/themes/default/setup-plugins.png b/data/themes/default/setup-plugins.png new file mode 100644 index 000000000..81891c373 Binary files /dev/null and b/data/themes/default/setup-plugins.png differ diff --git a/data/themes/default/style.css b/data/themes/default/style.css index de9de28b0..ec41b9f18 100644 --- a/data/themes/default/style.css +++ b/data/themes/default/style.css @@ -12,6 +12,17 @@ automationEditor { background-color: rgb(0, 0, 0); } +#PreferencesDialog QListView::item:selected { + background: qlineargradient(x1: 0, y1:0, x2:0,y2:1, stop:0 rgb(84,87,96), stop:1 rgb(54,57,66)); + border-radius: 8px; + color: white; +} + +#PreferencesDialog QListView::item:hover:!selected { + background: qlineargradient(x1: 0, y1:0, x2:0,y2:1, stop:0 rgb(104,107,116), stop:1 rgb(94,97,106)); + border-radius: 8px; +} + #WelcomeFrame { border: 2px solid rgb(32,32,32); border-radius: 8px; @@ -113,11 +124,11 @@ nameLabel, effectLabel, sf2InstrumentView > QLabel, QComboBox { QWidget#mainToolbar { - background-image: url(resources:main_toolbar_bg.png); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #66728c, stop: 1.0 #38404e); } QToolBar { - background: url(resources:toolbar_bg.png); + background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop: 0 #66728c, stop: 1.0 #38404e); } QToolButton, toolButton { @@ -150,6 +161,14 @@ QToolButton:checked { padding: 3px 0px 0px 3px; } +SideBar { + background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 #66728c, stop: 1.0 #38404e); +} + +SideBar QToolButton { + font-size: 12px; +} + FxMixerView QPushButton, EffectRackView QPushButton, ControllerRackView QPushButton { font-size: 10px; } diff --git a/data/themes/default/toolbar_bg.png b/data/themes/default/toolbar_bg.png deleted file mode 100644 index 78ebb5e0f..000000000 Binary files a/data/themes/default/toolbar_bg.png and /dev/null differ diff --git a/include/AlsaDeviceListModel.h b/include/AlsaDeviceListModel.h index 457ab587a..3a72ca657 100644 --- a/include/AlsaDeviceListModel.h +++ b/include/AlsaDeviceListModel.h @@ -30,7 +30,8 @@ #ifdef LMMS_HAVE_ALSA #include -#include "QAbstractListModel" +#include +#include class AlsaDeviceListModel : public QAbstractListModel diff --git a/include/AudioPulseAudio.h b/include/AudioPulseAudio.h index 99cc9e462..33a11da1f 100644 --- a/include/AudioPulseAudio.h +++ b/include/AudioPulseAudio.h @@ -79,6 +79,7 @@ private: virtual void applyQualitySettings(); virtual void run(); + volatile bool m_quit; bool m_convertEndian; diff --git a/include/DirectorySelectDialog.h b/include/DirectorySelectDialog.h new file mode 100644 index 000000000..b7aab587c --- /dev/null +++ b/include/DirectorySelectDialog.h @@ -0,0 +1,46 @@ +/* + * DirectorySelectDialog.h - header file for DirectorySelectDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _DIRECTORY_SELECT_DIALOG_H +#define _DIRECTORY_SELECT_DIALOG_H + +#include "ResourceSelectDialog.h" + +namespace Ui { class DirectorySelectDialog; } + +class DirectorySelectDialog : public ResourceSelectDialog +{ +public: + DirectorySelectDialog( QWidget * _parent, + DatabaseScope _databaseScope = AllResources ); + ~DirectorySelectDialog(); + + +private: + Ui::DirectorySelectDialog * ui; + +} ; + +#endif + diff --git a/include/MainWindow.h b/include/MainWindow.h index 69090d855..80357e8d5 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -69,8 +69,6 @@ public: return m_toolBar; } - // show MainWidget or WelcomeScreen - void setMainWidgetVisible( bool _visible ); //int addWidgetToToolBar( QWidget * _w, int _row = -1, int _col = -1 ); //void addSpacingToToolBar( int _size ); @@ -109,6 +107,7 @@ public: void setPlaybackMode( ProjectPlaybackMode _playbackMode ); + void showWelcomeScreen(bool _visible = true); public slots: void resetWindowTitle(); @@ -126,6 +125,7 @@ public slots: bool saveProject(); bool saveProjectAs(); void showSettingsDialog(); + void showPreferencesDialog(); void aboutLMMS(); void help(); void toggleAutomationEditorWin(); @@ -145,6 +145,7 @@ public slots: protected: virtual void closeEvent( QCloseEvent * _ce ); + virtual void showEvent( QShowEvent * _se ); virtual void focusOutEvent( QFocusEvent * _fe ); virtual void keyPressEvent( QKeyEvent * _ke ); virtual void keyReleaseEvent( QKeyEvent * _ke ); diff --git a/include/PreferencesDialog.h b/include/PreferencesDialog.h new file mode 100644 index 000000000..67c739484 --- /dev/null +++ b/include/PreferencesDialog.h @@ -0,0 +1,43 @@ +/* + * PreferencesDialog.h - declaration of class PreferencesDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _PREFERENCES_DIALOG_H +#define _PREFERENCES_DIALOG_H + +#include + +namespace Ui { class PreferencesDialog; } + +class PreferencesDialog : public QDialog +{ +public: + PreferencesDialog(); + +private: + Ui::PreferencesDialog * ui; + +} ; + +#endif + diff --git a/include/QuickLoadDialog.h b/include/QuickLoadDialog.h index e9abb6ee2..0e1cf3ee8 100644 --- a/include/QuickLoadDialog.h +++ b/include/QuickLoadDialog.h @@ -25,29 +25,22 @@ #ifndef _QUICK_LOAD_DIALOG_H #define _QUICK_LOAD_DIALOG_H -#include - #include "ResourceItem.h" +#include "ResourceSelectDialog.h" namespace Ui { class QuickLoadDialog; } -class ResourceListModel; -class QuickLoadDialog : public QDialog +class QuickLoadDialog : public ResourceSelectDialog { - Q_OBJECT public: QuickLoadDialog( QWidget * _parent, ResourceItem::Type _typeFilter = - ResourceItem::TypeUnknown ); + ResourceItem::TypeUnknown, + DatabaseScope _databaseScope = AllResources ); virtual ~QuickLoadDialog(); -private slots: - void setTypeFilter( int ); - - private: Ui::QuickLoadDialog * ui; - ResourceListModel * m_listModel; } ; diff --git a/include/ResourceAction.h b/include/ResourceAction.h index 3960dcebe..81ba85a0e 100644 --- a/include/ResourceAction.h +++ b/include/ResourceAction.h @@ -30,35 +30,60 @@ class trackContainer; class ResourceItem; +/*! \brief The ResourceAction class provides centralized functionality for all actions + * related to a ResourceItem. + * + * These actions are for example loading projects, samples, presets, + * plugin-specific presets etc. Using this class we can avoid duplicated + * functionality in ResourcePreviewer, ResourceBrowser, TrackContainerView, + * InstrumentTrack & Co. + */ + class ResourceAction { public: + /*! Lists all supported actions. */ enum Actions { - EditProperties, - LoadProject, - LoadInNewTrackSongEditor, - LoadInNewTrackBBEditor, - LoadInActiveInstrumentTrack, - DownloadIntoCollection, - UploadToWWW, - DeleteLocalResource, - ImportFile, + EditProperties, /*!< Open a dialog to edit properties of the ResourceItem */ + LoadProject, /*!< Load the project represented by the ResourceItem */ + LoadInNewTrackSongEditor, /*!< Load preset, sample etc. in a new track in Song Editor */ + LoadInNewTrackBBEditor, /*!< Load preset, sample etc. in a new track in BB Editor */ + LoadInActiveInstrumentTrack,/*!< Load preset, sample etc. in active instrument track */ + DownloadIntoCollection, /*!< Download the resource into local collection */ + UploadToWWW, /*!< Upload the resource to Web */ + DeleteLocalResource, /*!< Delete local resource (=file) */ + ImportFile, /*!< Try to import the resource via import filter plugins */ NumActions } ; typedef Actions Action; - ResourceAction( const ResourceItem * _item, - Action _action = NumActions ) : - m_action( _action ), - m_item( _item ) + /*! \brief Constructs a ResourceAction object. + * \param item The ResourceItem the action is about + * \param action An optional action from the Action enumeration used for the defaultTrigger() method + */ + ResourceAction( const ResourceItem * item, + Action action = NumActions ) : + m_action( action ), + m_item( item ) { } bool loadProject(); - bool loadByPlugin( InstrumentTrack * _target ); - bool loadPreset( InstrumentTrack * _target ); - bool importProject( trackContainer * _target ); + bool loadByPlugin( InstrumentTrack * target ); + bool loadPreset( InstrumentTrack * target ); + bool importProject( trackContainer * target ); + + /*! \brief Triggers the action passed to the constructor without any further options. + * + * Most actions can be triggered without any further information. + * This allows simple but powerful code constructs: + * \code + * ResourceAction( myItem, ResourceAction::LoadProject ).defaultTrigger(); + * \endcode + * \return true if the operation succeeded, otherwise false. + */ + bool defaultTrigger(); private: diff --git a/include/ResourceBrowser.h b/include/ResourceBrowser.h index c0695fd83..bebb354d3 100644 --- a/include/ResourceBrowser.h +++ b/include/ResourceBrowser.h @@ -26,9 +26,10 @@ #ifndef _RESOURCE_BROWSER_H #define _RESOURCE_BROWSER_H +#include "ResourceAction.h" #include "ResourcePreviewer.h" #include "ResourceTreeModel.h" -#include "side_bar_widget.h" +#include "SideBarWidget.h" class QAction; class QLabel; @@ -36,24 +37,10 @@ class ResourceItem; class ResourceTreeView; -class ResourceBrowser : public sideBarWidget +class ResourceBrowser : public SideBarWidget { Q_OBJECT public: - enum Actions - { - EditProperties, - LoadProject, - LoadInNewTrackSongEditor, - LoadInNewTrackBBEditor, - LoadInActiveInstrumentTrack, - DownloadIntoCollection, - UploadToWWW, - DeleteLocalResource, - ImportFile, - NumActions - } ; - ResourceBrowser( QWidget * _parent ); virtual ~ResourceBrowser(); @@ -72,9 +59,9 @@ private slots: private: - void triggerAction( Actions _action, ResourceItem * _item ); + void triggerAction( ResourceAction::Action _action, ResourceItem * _item ); - QAction * m_actions[NumActions]; + QAction * m_actions[ResourceAction::NumActions]; // the object that will preview individual resources ResourcePreviewer m_previewer; diff --git a/include/ResourceDB.h b/include/ResourceDB.h index f7711c639..29be71e98 100644 --- a/include/ResourceDB.h +++ b/include/ResourceDB.h @@ -34,20 +34,45 @@ #include "ResourceItem.h" +/*! \brief The ResourceDB class organizes and caches ResourceItems. + * + * ResourceItem sets are organized in the ResourceDB::ItemHashMap. This + * allows fast lookup of ResourceItems by hash string. ResourceItems are added + * and removed by a ResourceProvider. + * + * The ResourceItem array can be cached to a file and restored later. This is + * essential as otherwise e.g. the LocalResourceProvider would have to re-read + * all directories and files and recompute hash strings based on file contents. + * + * One can also descend the hierarchical ResourceItem tree by starting from + * ResourceDB::topLevelNode(). + */ + class EXPORT ResourceDB : public QObject { Q_OBJECT public: + /*! A QHash instantiation used for storing ResourceItems and allow lookup + * by hash string */ typedef QHash ItemHashMap; - ResourceDB( ResourceProvider * _provider ); + /*! \brief Constructs a ResourceDB object. + * \param provider The ResourceProvider that will manage ResourceItems in this DB + */ + ResourceDB( ResourceProvider * provider ); ~ResourceDB(); + /*! \brief Initializes ResourceDB object, i.e. restore cache and update itself via the ResourceProvider. */ void init(); - void load( const QString & _file ); - void save( const QString & _file ); + /*! \brief Dumps all ResourceItems with their relations to a file. + * \param file The filename to save data to */ + void load( const QString & file ); + + /*! \brief Restores ResourceItems with their relations from a file. + * \param file The filename to load data from */ + void save( const QString & file ); inline ResourceProvider * provider() { @@ -69,21 +94,31 @@ public: return &m_topLevelNode; } - // similiar to items()[_hash] but faster and returns NULL if not found - const ResourceItem * itemByHash( const QString & _hash ) const; + /*! \brief Looks up a ResourceItem by hash string - similiar to items()[hash] + * but faster and returns NULL if not found. + * \param hash The hash string that is searched for + * \return A const pointer to the matching ResourceItem */ + const ResourceItem * itemByHash( const QString & hash ) const; - // return a list of ResourceItems who somehow match the given keywords - ResourceItemList matchItems( const QStringList & _keyWords ); + /*! \brief Return a list of ResourceItems which somehow match the given keywords. + * \param keywords A list of keywords that are searched for + * \return A ResourceItemList which the result */ + ResourceItemList matchItems( const QStringList & keywords ); - // return an item which matches a resource desceibed in _item as - // good as possible - const ResourceItem * nearestMatch( const ResourceItem & _item ); + /*! \brief Returns a ResourceItem which matches a given ResourceItem best. + * \param item A ResourceItem to search the best match for + * \return A const pointer to the best marching ResourceItem in the DB */ + const ResourceItem * nearestMatch( const ResourceItem & item ); - // add given item to DB - void addItem( ResourceItem * _newItem ); + /*! \brief Adds given ResourceItem to DB. + * \param newItem The ResourceItem to be added */ + void addItem( ResourceItem * newItem ); - void recursiveRemoveItems( ResourceItem::Relation * parent, - bool removeTopLevelParent = true ); + /*! \brief Remove items recursively starting from a certain ResourceItem::Relation + * \param parent The parent relation to start from with removing + * \param removeParent A boolean which specifies whether to also remove the parent item */ + void removeItemsRecursively( ResourceItem::Relation * parent, + bool removeParent = true ); private: @@ -140,9 +175,12 @@ private: signals: + /*! \brief Forwarded signal of ResourceProvider::itemsChanged() */ void itemsChanged(); - void directoryItemAdded( const QString & _path ); - void directoryItemRemoved( const QString & _path ); + /*! \brief Emitted whenever a ResourceItem of type ResourceItem::TypeDirectory is added */ + void directoryItemAdded( const QString & path ); + /*! \brief Emitted whenever a ResourceItem of type ResourceItem::TypeDirectory is removed */ + void directoryItemRemoved( const QString & path ); } ; diff --git a/include/ResourceItem.h b/include/ResourceItem.h index a3ca8795e..2da1436ba 100644 --- a/include/ResourceItem.h +++ b/include/ResourceItem.h @@ -35,59 +35,96 @@ #include "TreeRelation.h" +/*! \brief The ResourceItem class provides information about a local/remote file/directory. + * + * All relevant properties of a file or directory are stored within a + * ResourceItem and can be accessed easily. All resources are identified by + * a unique hash (based on file content or (absolute) directory name). + * + * ResourceItems are managed within a ResourceDB. Reading and writing resource + * data is abstracted into the ResourceProvider class. + * + * The ResourceItem class does not provide any actual functionality. + * Use ResourceAction or more high level classes like ResourcePreviewer and + * ResourceBrowser. + */ + class EXPORT ResourceItem { public: + /*! A relation specifies how ResourceItems are organized among each other. + * See documentation of TreeRelation for details. */ typedef TreeRelation Relation; + /*! Lists all supported base directories for ResourceItems. */ enum BaseDirectories { - BaseRoot, - BaseWorkingDir, - BaseDataDir, - BaseHome, - BaseURL, + BaseRoot, /*!< Item is relative to root directory */ + BaseWorkingDir, /*!< Item is relative to working directory */ + BaseDataDir, /*!< Item is relative to LMMS' data directory */ + BaseHome, /*!< Item is relative to user's home directory */ + BaseURL, /*!< Item is relative to the URL of the ResourceProvider */ NumBaseDirectories } ; typedef BaseDirectories BaseDirectory; + /*! Lists all supported ResourceItem types. */ enum Types { - TypeUnknown, - TypeDirectory, - TypeSample, - TypePreset, - TypePluginSpecificResource, - TypeProject, - TypeMidiFile, - TypeForeignProject, - TypePlugin, - TypeImage, + TypeUnknown, /*!< No known resource type */ + TypeDirectory, /*!< Item is a directory */ + TypeSample, /*!< Item is a supported sample file */ + TypePreset, /*!< Item is a LMMS-specific preset */ + TypePluginSpecificResource, /* Item is a file supported by one of the available plugins */ + TypeProject, /*!< Item is a LMMS project */ + TypeMidiFile, /*!< Item is a MIDI file (and can be imported via MIDI import filter) */ + TypeForeignProject, /*!< Item is any other kind of project which can be imported via an ImportFilter plugin */ + TypePlugin, /*!< Item is a Plugin binary */ + TypeImage, /*!< Item is an image */ NumTypes } ; typedef Types Type; - ResourceItem( ResourceProvider * _provider, - const QString & _name, + /*! \brief Constructs a ResourceItem object. + * \param provider The provider this item belongs to + * \param name The name used to identify the item towards the user + * \param baseDir The base directory this item is relative to + * \param path The path from base directory to this item + * \param hash A unique hash based on file content, pass QString::null to compute it automatically + * \param author A string describing the author + * \param tags A comma-separated list of tags for this item + * \param size The size of the item, pass -1 to compute it automatically + * \param lastMod The date and time of the last modification of the item + */ + ResourceItem( ResourceProvider * provider, + const QString & name, Type _type, - BaseDirectory _base_dir = BaseWorkingDir, - const QString & _path = QString::null, - const QString & _hash = QString::null, - const QString & _author = QString::null, - const QString & _tags = QString::null, - int _size = -1, - const QDateTime & _last_mod = QDateTime() ); - // copy constructor - ResourceItem( const ResourceItem & _item ); + BaseDirectory baseDir = BaseWorkingDir, + const QString & path = QString::null, + const QString & hash = QString::null, + const QString & author = QString::null, + const QString & tags = QString::null, + int size = -1, + const QDateTime & lastMod = QDateTime() ); + /*! \brief Copy constructor. */ + ResourceItem( const ResourceItem & item ); - inline void setHidden( bool _h, const QAbstractItemModel * _model ) + /*! \brief Sets hidden property for the given item model + * \param hidden A boolean specifying the desired value + * \param model A pointer to a QAbstractItemModel (allows to use this item + * for multiple models and views) */ + inline void setHidden( bool hidden, const QAbstractItemModel * model ) { - m_hidden[_model] = _h; + m_hidden[model] = hidden; } - inline bool isHidden( const QAbstractItemModel * _model ) const + /*! \brief Returns whether item is hidden for the given item model + * \param model A pointer to a QAbstractItemModel (allows to use this item + * for multiple models and views) + * \return true if the item is hidden, false otherwise */ + inline bool isHidden( const QAbstractItemModel * model ) const { - return m_hidden[_model]; + return m_hidden[model]; } @@ -206,6 +243,8 @@ public: return m_provider->dataSize( this ); } + /*! \brief Fetch data (contents) of the resource via ResourceProvider. + * \return QByteArray with complete contents of the resource */ QByteArray fetchData( int _maxSize = -1 ) const { return m_provider->fetchData( this ); @@ -213,15 +252,19 @@ public: void reload(); - // returns true if all given keywords match name, tags etc. + /*! \brief Returns, whether keywords match certain properties. + * \return true if all given keywords match name, tags etc. */ bool keywordMatch( const QStringList & _keywords ) const; - // return true, if given ResourceItem is equal + /*! \brief Tests for equality with another ResourceItem. + * \return true, if given ResourceItem is equal */ bool operator==( const ResourceItem & _other ) const; - // rates equality with given item + /*! \brief Rates equality with another ResourceItem. + * \return An integer specifying how close the two ResourceItems are (between 0 and about 250) */ int equalityLevel( const ResourceItem & _other ) const; + /*! \brief Guesses resource type by various criteria */ Type guessType() const; static const char * mimeKey() diff --git a/include/ResourceModel.h b/include/ResourceModel.h index a6ed4a3ac..43d5b6f46 100644 --- a/include/ResourceModel.h +++ b/include/ResourceModel.h @@ -56,7 +56,7 @@ public: // used for drag'n'drop - return proper MIME data for indexes virtual QMimeData * mimeData( const QModelIndexList & _indexes ) const; - // return ResourceTreeItem belonging to a certain index + // return ResourceItem::Relation belonging to a certain index static inline ResourceItem::Relation * relation( const QModelIndex & _idx ) { return static_cast( _idx.internalPointer() ); diff --git a/include/ResourceSelectDialog.h b/include/ResourceSelectDialog.h new file mode 100644 index 000000000..0b603e2fd --- /dev/null +++ b/include/ResourceSelectDialog.h @@ -0,0 +1,73 @@ +/* + * ResourceSelectDialog.h - header file for ResourceSelectDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _RESOURCE_SELECT_DIALOG_H +#define _RESOURCE_SELECT_DIALOG_H + +#include + +class ResourceItem; +class ResourceModel; + +class ResourceSelectDialog : public QDialog +{ + Q_OBJECT +public: + enum ModelTypes + { + ListModel, + TreeModel + } ; + + enum DatabaseScope + { + WorkingDirResources, + WebResources, + AllResources + } ; + + ResourceSelectDialog( QWidget * _parent, ModelTypes _modelType, + DatabaseScope _databaseScope = AllResources ); + virtual ~ResourceSelectDialog(); + + // returns the selected item (NULL if the dialog was not accepted or no + // valid item was selected) + ResourceItem * selectedItem(); + + +protected: + void setupUi(); + + +private slots: + void setTypeFilter( int ); + + +private: + ResourceModel * m_model; + +} ; + +#endif + diff --git a/include/ResourceTreeView.h b/include/ResourceTreeView.h index fe1622377..66de54f2c 100644 --- a/include/ResourceTreeView.h +++ b/include/ResourceTreeView.h @@ -34,7 +34,10 @@ class ResourceTreeView : public QTreeView { Q_OBJECT public: - ResourceTreeView( ResourceTreeModel * _tm, QWidget * _parent ); + ResourceTreeView( QWidget * _parent, ResourceTreeModel * _tm = NULL ); + virtual ~ResourceTreeView(); + + virtual void setModel( QAbstractItemModel * _model ); public slots: @@ -51,7 +54,7 @@ protected: private: - ResourceTreeModel * m_tm; + ResourceTreeModel * m_treeModel; QString m_lastFilter; diff --git a/include/SideBar.h b/include/SideBar.h new file mode 100644 index 000000000..9a544b8bb --- /dev/null +++ b/include/SideBar.h @@ -0,0 +1,57 @@ +/* + * SideBar.h - side-bar in LMMS' MainWindow + * + * Copyright (c) 2004-2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef _SIDE_BAR_H +#define _SIDE_BAR_H + +#include +#include +#include + +class QToolButton; +class SideBarWidget; + + +class SideBar : public QToolBar +{ + Q_OBJECT +public: + SideBar( Qt::Orientation _orientation, QWidget * _parent ); + virtual ~SideBar(); + + void appendTab( SideBarWidget * _sbw ); + + +private slots: + void toggleButton( QAbstractButton * _btn ); + + +private: + QButtonGroup m_btnGroup; + typedef QMap ButtonMap; + ButtonMap m_widgets; + +} ; + +#endif diff --git a/include/side_bar_widget.h b/include/SideBarWidget.h similarity index 78% rename from include/side_bar_widget.h rename to include/SideBarWidget.h index ab87882df..0efc0da9b 100644 --- a/include/side_bar_widget.h +++ b/include/SideBarWidget.h @@ -1,8 +1,8 @@ /* - * side_bar_widget.h - base-class for all side-bar-widgets + * SideBarWidget.h - base-class for all side-bar-widgets * * Copyright (c) 2004-2009 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -22,7 +22,6 @@ * */ - #ifndef _SIDE_BAR_WIDGET_H #define _SIDE_BAR_WIDGET_H @@ -31,41 +30,42 @@ #include -class sideBarWidget : public QWidget +class SideBarWidget : public QWidget { Q_OBJECT public: - sideBarWidget( const QString & _title, const QPixmap & _icon, + SideBarWidget( const QString & _title, const QPixmap & _icon, QWidget * _parent ); - virtual ~sideBarWidget(); + virtual ~SideBarWidget(); + inline const QPixmap & icon() const { - return( m_icon ); + return m_icon; } inline const QString & title() const { - return( m_title ); + return m_title; } protected: virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ); - inline virtual void contextMenuEvent( QContextMenuEvent * ) + virtual void contextMenuEvent( QContextMenuEvent * ) { } - inline QWidget * contentParent() + QWidget * contentParent() { return( m_contents ); } - inline void addContentWidget( QWidget * _w ) + void addContentWidget( QWidget * _w ) { m_layout->addWidget( _w ); } - inline void addContentLayout( QLayout * _l ) + void addContentLayout( QLayout * _l ) { m_layout->addLayout( _l ); } @@ -79,5 +79,4 @@ private: } ; - #endif diff --git a/include/WelcomeScreen.h b/include/WelcomeScreen.h index 9f73476b7..d1e38b48a 100644 --- a/include/WelcomeScreen.h +++ b/include/WelcomeScreen.h @@ -53,7 +53,7 @@ private slots: private: - void switchView(); + void hideWelcomeScreen(); Ui::WelcomeScreen * ui; RecentResourceListModel * m_recentProjectsModel; diff --git a/include/kmultitabbar.h b/include/kmultitabbar.h deleted file mode 100644 index 3bec1ee9d..000000000 --- a/include/kmultitabbar.h +++ /dev/null @@ -1,309 +0,0 @@ -/*************************************************************************** - kmultitabbar.h - description - ------------------- - begin : 2001 - copyright : (C) 2001,2002,2003 by Joseph Wenninger - ***************************************************************************/ - -/*************************************************************************** - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - ***************************************************************************/ - -#ifndef _KMultitabbar_h_ -#define _KMultitabbar_h_ - -#include -#include -#include -#include - -class QPixmap; -class QPainter; -class QFrame; -class QMenu; - -class KMultiTabBarPrivate; -class KMultiTabBarTabPrivate; -class KMultiTabBarButtonPrivate; -class KMultiTabBarInternal; - -/** - * A Widget for horizontal and vertical tabs. - * It is possible to add normal buttons to the top/left - * The handling if only one tab at a time or multiple tabs - * should be raisable is left to the "user". - *@author Joseph Wenninger - */ -class KMultiTabBar: public QWidget -{ - Q_OBJECT -public: - enum KMultiTabBarMode{Horizontal, Vertical}; - enum KMultiTabBarPosition{Left, Right, Top, Bottom}; - - /** - * The list of available styles for KMultiTabBar - * - VSNET - Visual Studio .Net like (only show the text of active tabs - * - KDEV3 - Kdevelop 3 like (always show the text) - * - KONQSBC - konqy's classic sidebar style (unthemed) (currently disabled) - */ - enum KMultiTabBarStyle{VSNET=0, KDEV3=1, KONQSBC=2, KDEV3ICON=3,STYLELAST=0xffff}; - - KMultiTabBar(KMultiTabBarMode bm,QWidget *parent=0 ); - virtual ~KMultiTabBar(); - - /** - * append a new button to the button area. The button can later on be accessed with button(ID) - * eg for connecting signals to it - * @param pic a pixmap for the button - * @param id an arbitraty ID value. It will be emitted in the clicked signal for identifying the button - * if more than one button is connected to a signals. - * @param popup A popup menu which should be displayed if the button is clicked - * @param not_used_yet will be used for a popup text in the future - */ - int appendButton(const QPixmap &pic,int id=-1,QMenu* popup=0,const QString& not_used_yet=QString()); - /** - * remove a button with the given ID - */ - void removeButton(int id); - /** - * append a new tab to the tab area. It can be accessed lateron with tabb(id); - * @param pic a bitmap for the tab - * @param id an arbitrary ID which can be used later on to identify the tab - * @param text if a mode with text is used it will be the tab text, otherwise a mouse over hint - */ - int appendTab(const QPixmap &pic,int id=-1,const QString& text=QString()); - /** - * remove a tab with a given ID - */ - void removeTab(int id); - /** - * set a tab to "raised" - * @param id The ID of the tab to manipulate - * @param state true == activated/raised, false == not active - */ - void setTab(int id ,bool state); - /** - * return the state of a tab, identified by it's ID - */ - bool isTabRaised(int id) const; - /** - * get a pointer to a button within the button area identified by its ID - */ - class KMultiTabBarButton *button(int id) const; - - /** - * get a pointer to a tab within the tab area, identiifed by its ID - */ - class KMultiTabBarTab *tab(int id) const; - /** - * set the real position of the widget. - * @param pos if the mode is horizontal, only use top, bottom, if it is vertical use left or right - */ - void setPosition(KMultiTabBarPosition pos); - /** - * get the tabbar position. - * @return position - */ - KMultiTabBarPosition position() const; - /** - * set the display style of the tabs - */ - void setStyle(KMultiTabBarStyle style); - /** - * get the display style of the tabs - * @return display style - */ - KMultiTabBarStyle tabStyle() const; - /** - * be carefull, don't delete tabs yourself and don't delete the list itself - */ - QList* tabs(); - /** - * be carefull, don't delete buttons yourself and don't delete the list itself - */ - QList* buttons(); - - /** - * might vanish, not sure yet - */ - void showActiveTabTexts(bool show=true); -protected: - friend class KMultiTabBarButton; - virtual void fontChange( const QFont& ); - void updateSeparator(); -private: - class KMultiTabBarInternal *m_internal; - QBoxLayout *m_l; - QFrame *m_btnTabSep; - QList m_buttons; - KMultiTabBarPosition m_position; - KMultiTabBarPrivate *d; -}; - -/** - * This class should never be created except with the appendButton call of KMultiTabBar - */ -class KMultiTabBarButton: public QPushButton -{ - Q_OBJECT -public: - KMultiTabBarButton(const QPixmap& pic,const QString&, QMenu *popup, - int id,QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style); - KMultiTabBarButton(const QString&, QMenu *popup, - int id,QWidget *parent, KMultiTabBar::KMultiTabBarPosition pos, KMultiTabBar::KMultiTabBarStyle style); - virtual ~KMultiTabBarButton(); - int id() const; - -public slots: - /** - * this is used internaly, but can be used by the user, if (s)he wants to - * It the according call of KMultiTabBar is invoked though this modifications will be overwritten - */ - void setPosition(KMultiTabBar::KMultiTabBarPosition); - /** - * this is used internaly, but can be used by the user, if (s)he wants to - * It the according call of KMultiTabBar is invoked though this modifications will be overwritten - */ - void setStyle(KMultiTabBar::KMultiTabBarStyle); - - /** - * modify the text of the button - */ - void setText(const QString &); - - QSize sizeHint() const; - -protected: - KMultiTabBar::KMultiTabBarPosition m_position; - KMultiTabBar::KMultiTabBarStyle m_style; - QString m_text; - virtual void hideEvent( class QHideEvent*); - virtual void showEvent( class QShowEvent*); -private: - int m_id; - KMultiTabBarButtonPrivate *d; -signals: - /** - * this is emitted if the button is clicked - * @param id the ID identifying the button - */ - void clicked(int id); -protected slots: - virtual void slotClicked(); -}; - -/** - * This class should never be created except with the appendTab call of KMultiTabBar - */ -class KMultiTabBarTab: public KMultiTabBarButton -{ - Q_OBJECT -public: - KMultiTabBarTab(const QPixmap& pic,const QString&,int id,QWidget *parent, - KMultiTabBar::KMultiTabBarPosition pos,KMultiTabBar::KMultiTabBarStyle style); - virtual ~KMultiTabBarTab(); - /** - * set the active state of the tab - * @param state true==active false==not active - */ - void setState(bool state); - /** - * choose if the text should always be displayed - * this is only used in classic mode if at all - */ - void showActiveTabText(bool show); - void resize(){ setSize( neededSize() ); } -private: - bool m_showActiveTabText; - int m_expandedSize; - KMultiTabBarTabPrivate *d; -protected: - friend class KMultiTabBarInternal; - void setSize(int); - int neededSize(); - void updateState(); - virtual void paintEvent(QPaintEvent *); - virtual void drawButton(QPainter *); - virtual void drawButtonLabel(QPainter *); - void drawButtonStyled(QPainter *); - void drawButtonClassic(QPainter *); -protected slots: - virtual void slotClicked(); - void setTabsPosition(KMultiTabBar::KMultiTabBarPosition); - -public slots: - virtual void setIcon(const QString&); - virtual void setIcon(const QPixmap&); -}; -/*************************************************************************** - kmultitabbar_p.h - description - ------------------- - begin : 2003 - copyright : (C) 2003 by Joseph Wenninger - ***************************************************************************/ - -/*************************************************************************** - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - ***************************************************************************/ - - -class KMultiTabBarInternal: public QWidget -{ - Q_OBJECT -public: - KMultiTabBarInternal(QWidget *parent,KMultiTabBar::KMultiTabBarMode bm); - int appendTab(const QPixmap &,int=-1,const QString& =QString()); - KMultiTabBarTab *tab(int) const; - void removeTab(int); - void setPosition(enum KMultiTabBar::KMultiTabBarPosition pos); - void setStyle(enum KMultiTabBar::KMultiTabBarStyle style); - void showActiveTabTexts(bool show); - QList* tabs(){return &m_tabs;} -private: - friend class KMultiTabBar; - QWidget *box; - QBoxLayout *mainLayout; - QList m_tabs; - enum KMultiTabBar::KMultiTabBarPosition m_position; - bool m_showActiveTabTexts; - enum KMultiTabBar::KMultiTabBarStyle m_style; - int m_expandedTabSize; - int m_lines; - KMultiTabBar::KMultiTabBarMode m_barMode; -protected: - virtual bool eventFilter(QObject *,QEvent*); -// virtual void paintEvent( QPaintEvent * ); - - virtual void resizeEvent(QResizeEvent *); -}; - - - -#endif diff --git a/include/plugin_browser.h b/include/plugin_browser.h index b0d66ae06..b0473b7f4 100644 --- a/include/plugin_browser.h +++ b/include/plugin_browser.h @@ -28,14 +28,14 @@ #include #include -#include "side_bar_widget.h" +#include "SideBarWidget.h" #include "Plugin.h" class trackContainer; -class pluginBrowser : public sideBarWidget +class pluginBrowser : public SideBarWidget { Q_OBJECT public: diff --git a/include/side_bar.h b/include/side_bar.h deleted file mode 100644 index 29fd4e6bc..000000000 --- a/include/side_bar.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * side_bar.h - code for side-bar in LMMS - * - * Copyright (c) 2004-2008 Tobias Doerffel - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#ifndef _SIDE_BAR_H -#define _SIDE_BAR_H - -#include - -#include "kmultitabbar.h" -#include "side_bar_widget.h" - - -class sideBar : public KMultiTabBar -{ - Q_OBJECT -public: - sideBar( KMultiTabBarMode _m, QWidget * _parent ) : - KMultiTabBar( _m, _parent ) - { - } - - virtual ~sideBar() - { - } - - inline int appendTab( sideBarWidget * _sbw, int _id ) - { - int ret = KMultiTabBar::appendTab( _sbw->icon(), _id, - _sbw->title() ); - m_widgets[_id] = _sbw; - _sbw->hide(); - _sbw->setMinimumWidth( 200 ); - connect( tab( _id ), SIGNAL( clicked( int ) ), this, - SLOT( tabClicked( int ) ) ); - return( ret ); - } - - -private slots: - inline void tabClicked( int _id ) - { - // disable all other tabbar-buttons - QMap::Iterator it; - for( it = m_widgets.begin(); it != m_widgets.end(); ++it ) - { - if( it.key() != _id/* && isTabRaised(it.key()) == true*/ ) - { - setTab( it.key(), false ); - } - if( m_widgets[it.key()] != NULL ) - { - m_widgets[it.key()]->hide(); - } - } - if( m_widgets[_id] != NULL ) - { - if( isTabRaised( _id ) ) - { - m_widgets[_id]->show(); - } - else - { - m_widgets[_id]->hide(); - } - } - } - - -private: - QMap m_widgets; - -} ; - - -#endif diff --git a/plugins/flp_import/FlpImport.cpp b/plugins/flp_import/FlpImport.cpp index 5cebea7b3..a4672511f 100644 --- a/plugins/flp_import/FlpImport.cpp +++ b/plugins/flp_import/FlpImport.cpp @@ -2034,7 +2034,8 @@ extern "C" // neccessary for getting instance out of shared lib Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) { - return new FlpImport( static_cast( _data ) ); + return new FlpImport( QString::fromUtf8( + static_cast( _data ) ) ); } } diff --git a/plugins/ladspa_effect/calf/calf/giface.h b/plugins/ladspa_effect/calf/calf/giface.h index 4a23300ca..56305bcb9 100644 --- a/plugins/ladspa_effect/calf/calf/giface.h +++ b/plugins/ladspa_effect/calf/calf/giface.h @@ -69,6 +69,7 @@ enum parameter_flags PF_CTL_BUTTON = 0x0600, ///< push button PF_CTL_METER = 0x0700, ///< volume meter PF_CTL_LED = 0x0800, ///< light emitting diode + PF_CTL_LABEL = 0x0900, ///< label PF_CTLOPTIONS = 0x00F000, ///< bit mask for control (widget) options PF_CTLO_HORIZ = 0x001000, ///< horizontal version of the control (unused) diff --git a/plugins/ladspa_effect/calf/calf/metadata.h b/plugins/ladspa_effect/calf/calf/metadata.h index fd89b6040..c959e1940 100644 --- a/plugins/ladspa_effect/calf/calf/metadata.h +++ b/plugins/ladspa_effect/calf/calf/metadata.h @@ -63,7 +63,7 @@ struct filterclavier_metadata: public plugin_metadata struct reverb_metadata: public plugin_metadata { - enum { par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count }; + enum { par_clip, par_meter_wet, par_meter_out, par_decay, par_hfdamp, par_roomsize, par_diffusion, par_amount, par_dry, par_predelay, par_basscut, par_treblecut, param_count }; enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("reverb", "reverb", "Reverb") }; @@ -78,7 +78,7 @@ struct vintage_delay_metadata: public plugin_metadata struct rotary_speaker_metadata: public plugin_metadata { public: - enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, param_count }; + enum { par_speed, par_spacing, par_shift, par_moddepth, par_treblespeed, par_bassspeed, par_micdistance, par_reflection, par_meter_l, par_meter_h, param_count }; enum { in_count = 2, out_count = 2, support_midi = true, require_midi = false, rt_capable = true }; PLUGIN_NAME_ID_LABEL("rotary_speaker", "rotaryspeaker", "Rotary Speaker") }; @@ -126,16 +126,27 @@ struct monosynth_metadata: public plugin_metadata }; PLUGIN_NAME_ID_LABEL("monosynth", "monosynth", "Monosynth") }; - + /// Thor's compressor - metadata struct compressor_metadata: public plugin_metadata { enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; - enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, // param_freq, param_bw, + enum { param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_aweighting, param_compression, param_peak, param_clip, param_bypass, param_input,// param_freq, param_bw, param_count }; PLUGIN_NAME_ID_LABEL("compressor", "compressor", "Compressor") }; +/// Markus's sidechain compressor - metadata +struct sidechaincompressor_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_meter_in, param_meter_out, param_clip_in, param_clip_out, + param_threshold, param_ratio, param_attack, param_release, param_makeup, param_knee, param_detection, param_stereo_link, param_compression, + param_sc_mode, param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, + param_sc_listen, param_f1_active, param_f2_active, param_count }; + PLUGIN_NAME_ID_LABEL("sidechaincompressor", "sidechaincompressor", "Sidechain Compressor") +}; + /// Markus's multibandcompressor - metadata struct multibandcompressor_metadata: public plugin_metadata { @@ -157,6 +168,71 @@ struct multibandcompressor_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_detected, param_compression, param_detected_led, param_clip_out, + param_detection, param_mode, + param_threshold, param_ratio, param_laxity, param_makeup, + param_f1_freq, param_f2_freq, param_f1_level, param_f2_level, param_f2_q, + param_sc_listen, param_count }; + PLUGIN_NAME_ID_LABEL("deesser", "deesser", "Deesser") +}; + +/// Markus's 5-band EQ - metadata +struct equalizer5band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_in, + param_meter_out, param_clip_in, param_clip_out, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer5band", "equalizer5band", "Equalizer 5 Band") +}; +/// Markus's 8-band EQ - metadata +struct equalizer8band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, + param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + param_hp_active, param_hp_freq, param_hp_mode, + param_lp_active, param_lp_freq, param_lp_mode, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_p4_active, param_p4_level, param_p4_freq, param_p4_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer8band", "equalizer8band", "Equalizer 8 Band") +}; +/// Markus's 12-band EQ - metadata +struct equalizer12band_metadata: public plugin_metadata +{ + enum { in_count = 2, out_count = 2, support_midi = false, require_midi = false, rt_capable = true }; + enum { param_bypass, param_level_in, param_level_out, param_meter_inL, param_meter_inR, + param_meter_outL, param_meter_outR, param_clip_inL, param_clip_inR, param_clip_outL, param_clip_outR, + param_hp_active, param_hp_freq, param_hp_mode, + param_lp_active, param_lp_freq, param_lp_mode, + param_ls_active, param_ls_level, param_ls_freq, + param_hs_active, param_hs_level, param_hs_freq, + param_p1_active, param_p1_level, param_p1_freq, param_p1_q, + param_p2_active, param_p2_level, param_p2_freq, param_p2_q, + param_p3_active, param_p3_level, param_p3_freq, param_p3_q, + param_p4_active, param_p4_level, param_p4_freq, param_p4_q, + param_p5_active, param_p5_level, param_p5_freq, param_p5_q, + param_p6_active, param_p6_level, param_p6_freq, param_p6_q, + param_p7_active, param_p7_level, param_p7_freq, param_p7_q, + param_p8_active, param_p8_level, param_p8_freq, param_p8_q, + param_count }; + PLUGIN_NAME_ID_LABEL("equalizer12band", "equalizer12band", "Equalizer 12 Band") +}; + /// Organ - enums for parameter IDs etc. (this mess is caused by organ split between plugin and generic class - which was /// a bad design decision and should be sorted out some day) XXXKF @todo struct organ_enums diff --git a/plugins/ladspa_effect/calf/calf/modulelist.h b/plugins/ladspa_effect/calf/calf/modulelist.h index ca990654b..83c123cad 100644 --- a/plugins/ladspa_effect/calf/calf/modulelist.h +++ b/plugins/ladspa_effect/calf/calf/modulelist.h @@ -10,7 +10,12 @@ PER_MODULE_ITEM(phaser, false, "phaser") PER_MODULE_ITEM(multichorus, false, "multichorus") PER_MODULE_ITEM(compressor, false, "compressor") + PER_MODULE_ITEM(sidechaincompressor, false, "sidechaincompressor") PER_MODULE_ITEM(multibandcompressor, false, "multibandcompressor") + PER_MODULE_ITEM(deesser, false, "deesser") + PER_MODULE_ITEM(equalizer5band, false, "equalizer5band") + PER_MODULE_ITEM(equalizer8band, false, "equalizer8band") + PER_MODULE_ITEM(equalizer12band, false, "equalizer12band") #ifdef ENABLE_EXPERIMENTAL PER_MODULE_ITEM(fluidsynth, true, "fluidsynth") PER_MODULE_ITEM(wavetable, true, "wavetable") diff --git a/plugins/ladspa_effect/calf/calf/modules.h b/plugins/ladspa_effect/calf/calf/modules.h index d1545eb87..e8c4a5e22 100644 --- a/plugins/ladspa_effect/calf/calf/modules.h +++ b/plugins/ladspa_effect/calf/calf/modules.h @@ -203,6 +203,8 @@ public: uint32_t srate; gain_smoothing amount, dryamount; int predelay_amt; + float meter_wet, meter_out; + uint32_t clip; float *ins[in_count]; float *outs[out_count]; float *params[param_count]; @@ -223,7 +225,7 @@ public: } uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) { numsamples += offset; - + clip -= std::min(clip, numsamples); for (uint32_t i = offset; i < numsamples; i++) { float dry = dryamount.get(); float wet = amount.get(); @@ -236,12 +238,26 @@ public: reverb.process(rl, rr); outs[0][i] = dry*s.left + wet*rl; outs[1][i] = dry*s.right + wet*rr; + meter_wet = std::max(fabs(wet*rl), fabs(wet*rr)); + meter_out = std::max(fabs(outs[0][i]), fabs(outs[1][i])); + if(outs[0][i] > 1.f or outs[1][i] > 1.f) { + clip = srate >> 3; + } } reverb.extra_sanitize(); left_lo.sanitize(); left_hi.sanitize(); right_lo.sanitize(); right_hi.sanitize(); + if(params[par_meter_wet] != NULL) { + *params[par_meter_wet] = meter_wet; + } + if(params[par_meter_out] != NULL) { + *params[par_meter_out] = meter_out; + } + if(params[par_clip] != NULL) { + *params[par_clip] = clip; + } return outputs_mask; } void activate(); @@ -416,7 +432,9 @@ public: float maspeed_l; /// Current rotation speed for treble rotor - manual mode float maspeed_h; - + + int meter_l, meter_h; + rotary_speaker_audio_module(); void set_sample_rate(uint32_t sr); void setup(); @@ -501,7 +519,8 @@ public: int xl = pseudo_sine_scl(phase_l), yl = pseudo_sine_scl(phase_l + 0x40000000); int xh = pseudo_sine_scl(phase_h), yh = pseudo_sine_scl(phase_h + 0x40000000); // printf("%d %d %d\n", shift, pdelta, shift + pdelta + 20 * xl); - + meter_l = xl; + meter_h = xh; // float out_hi_l = in_mono - delay.get_interp_1616(shift + md * xh) + delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) - delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh); // float out_hi_r = in_mono + delay.get_interp_1616(shift + md * 65536 - md * yh) - delay.get_interp_1616(shift + pdelta + md * xh) + delay.get_interp_1616(shift + pdelta + pdelta + md * yh); float out_hi_l = in_mono + delay.get_interp_1616(shift + md * xh) - mix2 * delay.get_interp_1616(shift + md * 65536 + pdelta - md * yh) + mix3 * delay.get_interp_1616(shift + md * 65536 + pdelta + pdelta - md * xh); @@ -541,6 +560,12 @@ public: if (u1 || u2) set_vibrato(); } + if(params[par_meter_l] != NULL) { + *params[par_meter_l] = (float)meter_l / 65536.0; + } + if(params[par_meter_h] != NULL) { + *params[par_meter_h] = (float)meter_h / 65536.0; + } return outputs_mask; } virtual void control_change(int ctl, int val); @@ -901,8 +926,8 @@ class gain_reduction_audio_module { private: float linSlope, detected, kneeSqrt, kneeStart, linKneeStart, kneeStop; float compressedKneeStop, adjKneeStart, thres; - float attack, release, threshold, ratio, knee, makeup, detection, bypass, mute, meter_out, meter_comp; - float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection; + float attack, release, threshold, ratio, knee, makeup, detection, stereo_link, bypass, mute, meter_out, meter_comp; + float old_threshold, old_ratio, old_knee, old_makeup, old_bypass, old_mute, old_detection, old_stereo_link; int last_generation; uint32_t srate; bool is_active; @@ -910,8 +935,8 @@ private: inline float output_gain(float linSlope, bool rms); public: gain_reduction_audio_module(); - void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float byp, float mu); - void process(float &left, float &right); + void set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu); + void process(float &left, float &right, float det_left = NULL, float det_right = NULL); void activate(); void deactivate(); int id; @@ -924,6 +949,81 @@ public: virtual int get_changed_offsets(int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); }; +/// Sidecain Compressor by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) +class sidechaincompressor_audio_module: public audio_module, public frequency_response_line_graph { +private: + enum CalfScModes { + WIDEBAND, + DEESSER_WIDE, + DEESSER_SPLIT, + DERUMBLER_WIDE, + DERUMBLER_SPLIT, + WEIGHTED_1, + WEIGHTED_2, + WEIGHTED_3, + BANDPASS_1, + BANDPASS_2 + }; + float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old; + float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1; + CalfScModes sc_mode, sc_mode_old, sc_mode_old1; + float f1_active, f2_active; + uint32_t clip_in, clip_out; + float meter_in, meter_out; + gain_reduction_audio_module compressor; + biquad_d2 f1L, f1R, f2L, f2R; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + sidechaincompressor_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + inline cfloat h_z(const cfloat &z) { + switch (sc_mode) { + default: + case WIDEBAND: + return false; + break; + case DEESSER_WIDE: + case DERUMBLER_WIDE: + case WEIGHTED_1: + case WEIGHTED_2: + case WEIGHTED_3: + case BANDPASS_2: + return f1L.h_z(z) * f2L.h_z(z); + break; + case DEESSER_SPLIT: + return f2L.h_z(z); + break; + case DERUMBLER_SPLIT: + case BANDPASS_1: + return f1L.h_z(z); + break; + } + + } + float freq_gain(int index, double freq, uint32_t sr) + { + typedef std::complex cfloat; + freq *= 2.0 * M_PI / sr; + cfloat z = 1.0 / exp(cfloat(0.0, freq)); + + return std::abs(h_z(z)); + } + void set_sample_rate(uint32_t sr); + uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + /// Multibandcompressor by Markus Schmidt class multibandcompressor_audio_module: public audio_module, public line_graph_iface { private: @@ -952,6 +1052,260 @@ public: virtual int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); }; +/// Deesser by Markus Schmidt (based on Thor's compressor and Krzysztof's filters) +class deesser_audio_module: public audio_module, public frequency_response_line_graph { +private: + enum CalfDeessModes { + WIDE, + SPLIT + }; + float f1_freq_old, f2_freq_old, f1_level_old, f2_level_old, f2_q_old; + float f1_freq_old1, f2_freq_old1, f1_level_old1, f2_level_old1, f2_q_old1; + uint32_t detected_led; + float detected, clip_out; + uint32_t clip_led; + gain_reduction_audio_module compressor; + biquad_d2 hpL, hpR, lpL, lpR, pL, pR; +public: + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + deesser_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + return hpL.freq_gain(freq, sr) * pL.freq_gain(freq, sr); + } + void set_sample_rate(uint32_t sr); + uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 12 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer12band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float hp_mode_old, hp_freq_old; + float lp_mode_old, lp_freq_old; + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[8], p_freq_old[8], p_q_old[8]; + float hp_mode_old1, hp_freq_old1, hp_active_old1; + float lp_mode_old1, lp_freq_old1, lp_active_old1; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[8], p_freq_old1[8], p_q_old1[8], p_active_old1[8]; + enum CalfEqModes { + MODE12DB, + MODE24DB, + MODE36DB + }; + CalfEqModes eq_mode, eq_mode_old1[2]; + uint32_t clip_inL, clip_outL, clip_inR, clip_outR; + float meter_inL, meter_outL, meter_inR, meter_outR; + biquad_d2 hpL[3], hpR[3], lpL[3], lpR[3]; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[8], pR[8]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer12band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + ret *= hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + ret *= lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + } + } + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1; + ret *= (*params[param_p5_active] > 0.f) ? pL[4].freq_gain(freq, sr) : 1; + ret *= (*params[param_p6_active] > 0.f) ? pL[5].freq_gain(freq, sr) : 1; + ret *= (*params[param_p7_active] > 0.f) ? pL[6].freq_gain(freq, sr) : 1; + ret *= (*params[param_p8_active] > 0.f) ? pL[7].freq_gain(freq, sr) : 1; + return ret; + } + void set_sample_rate(uint32_t sr); + uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 8 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer8band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float hp_mode_old, hp_freq_old; + float lp_mode_old, lp_freq_old; + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[4], p_freq_old[4], p_q_old[4]; + float hp_mode_old1, hp_freq_old1, hp_active_old1; + float lp_mode_old1, lp_freq_old1, lp_active_old1; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[4], p_freq_old1[4], p_q_old1[4], p_active_old1[4]; + enum CalfEqModes { + MODE12DB, + MODE24DB, + MODE36DB + }; + CalfEqModes eq_mode, eq_mode_old1[2]; + uint32_t clip_inL, clip_outL, clip_inR, clip_outR; + float meter_inL, meter_outL, meter_inR, meter_outR; + biquad_d2 hpL[3], hpR[3], lpL[3], lpR[3]; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[4], pR[4]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer8band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + ret *= hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr) * hpL[0].freq_gain(freq, sr); + ret *= hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr) * hpR[0].freq_gain(freq, sr); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + ret *= lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr); + break; + case MODE24DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + case MODE36DB: + ret *= lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr) * lpL[0].freq_gain(freq, sr); + ret *= lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr) * lpR[0].freq_gain(freq, sr); + break; + } + } + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + ret *= (*params[param_p4_active] > 0.f) ? pL[3].freq_gain(freq, sr) : 1; + return ret; + } + void set_sample_rate(uint32_t sr); + uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + +/// Equalizer 5 Band by Markus Schmidt (based on Krzysztof's filters) +class equalizer5band_audio_module: public audio_module, public frequency_response_line_graph { +private: + float ls_level_old, ls_freq_old; + float hs_level_old, hs_freq_old; + float p_level_old[3], p_freq_old[3], p_q_old[3]; + float ls_level_old1, ls_freq_old1, ls_active_old1; + float hs_level_old1, hs_freq_old1, hs_active_old1; + float p_level_old1[3], p_freq_old1[3], p_q_old1[3], p_active_old1[3]; + uint32_t clip_in, clip_out; + float meter_in, meter_out; + biquad_d2 lsL, lsR, hsL, hsR; + biquad_d2 pL[3], pR[3]; +public: + typedef std::complex cfloat; + float *ins[in_count]; + float *outs[out_count]; + float *params[param_count]; + uint32_t srate; + bool is_active; + volatile int last_generation, last_calculated_generation; + equalizer5band_audio_module(); + void activate(); + void deactivate(); + void params_changed(); + float freq_gain(int index, double freq, uint32_t sr) + { + float ret = 1.f; + ret *= (*params[param_ls_active] > 0.f) ? lsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_hs_active] > 0.f) ? hsL.freq_gain(freq, sr) : 1; + ret *= (*params[param_p1_active] > 0.f) ? pL[0].freq_gain(freq, sr) : 1; + ret *= (*params[param_p2_active] > 0.f) ? pL[1].freq_gain(freq, sr) : 1; + ret *= (*params[param_p3_active] > 0.f) ? pL[2].freq_gain(freq, sr) : 1; + return ret; + } + void set_sample_rate(uint32_t sr); + uint32_t process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask); + bool get_graph(int index, int subindex, float *data, int points, cairo_iface *context); + bool get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context); + int get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline); +}; + /// Filterclavier --- MIDI controlled filter by Hans Baier class filterclavier_audio_module: public audio_module, diff --git a/plugins/ladspa_effect/calf/calf/waveshaping.h b/plugins/ladspa_effect/calf/calf/waveshaping.h new file mode 100644 index 000000000..914637c0a --- /dev/null +++ b/plugins/ladspa_effect/calf/calf/waveshaping.h @@ -0,0 +1,37 @@ +/* Calf DSP Library + * Placeholder for waveshaping classes + * + * Copyright (C) 2001-2009 Krzysztof Foltman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111-1307, USA. + */ +#ifndef __CALF_WAVESHAPING_H +#define __CALF_WAVESHAPING_H + +/// This will be a waveshaper... when I'll code it (-: +/// (or get Tom Szlagyi's permission to use his own) +class waveshaper { +public: + waveshaper(); + void activate() {} + void deactivate() {} + void set_params(float blend, float drive) {} + void set_sample_rate(uint32_t sr) {} + float process(float in) { return in; } + float get_distortion_level() { return 1; } +}; + +#endif diff --git a/plugins/ladspa_effect/calf/src/modules.cpp b/plugins/ladspa_effect/calf/src/modules.cpp index 5dc413e6d..225e38712 100644 --- a/plugins/ladspa_effect/calf/src/modules.cpp +++ b/plugins/ladspa_effect/calf/src/modules.cpp @@ -37,9 +37,9 @@ const char *calf_plugins::calf_copyright_info = "(C) 2001-2008 Krzysztof Foltman CALF_PORT_NAMES(flanger) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(flanger) = { - { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Minimum delay" }, - { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Modulation depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" }, + { 0.1, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, + { 0.5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "mod_depth", "Mod depth" }, + { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, { 0.90, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, { 0, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, { 0, 0, 1, 2, PF_BOOL | PF_CTL_BUTTON , NULL, "reset", "Reset" }, @@ -55,8 +55,8 @@ CALF_PORT_NAMES(phaser) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(phaser) = { { 1000, 20, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "base_freq", "Center Freq" }, - { 4000, 0, 10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Modulation depth" }, - { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Modulation rate" }, + { 4000, 0, 10800, 0, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_CENTS, NULL, "mod_depth", "Mod depth" }, + { 0.25, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "mod_rate", "Mod rate" }, { 0.25, -0.99, 0.99, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "feedback", "Feedback" }, { 6, 1, 12, 12, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB, NULL, "stages", "# Stages" }, { 180, 0, 360, 9, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, @@ -74,6 +74,9 @@ CALF_PORT_NAMES(reverb) = {"In L", "In R", "Out L", "Out R"}; const char *reverb_room_sizes[] = { "Small", "Medium", "Large", "Tunnel-like", "Large/smooth", "Experimental" }; CALF_PORT_PROPS(reverb) = { + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_wet", "Wet amount" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, { 1.5, 0.4, 15.0, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL, "decay_time", "Decay time" }, { 5000, 2000,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hf_damp", "High Frq Damp" }, { 2, 0, 5, 0, PF_ENUM | PF_CTL_COMBO , reverb_room_sizes, "room_size", "Room size", }, @@ -151,7 +154,7 @@ const char *vintage_delay_fbmodes[] = { }; CALF_PORT_PROPS(vintage_delay) = { - { 120, 30, 300,2701, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" }, + { 120, 30, 300, 1, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_BPM, NULL, "bpm", "Tempo" }, { 4, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "subdiv", "Subdivide"}, { 3, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_l", "Time L"}, { 5, 1, 16, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "time_r", "Time R"}, @@ -171,14 +174,16 @@ CALF_PORT_NAMES(rotary_speaker) = {"In L", "In R", "Out L", "Out R"}; const char *rotary_speaker_speed_names[] = { "Off", "Chorale", "Tremolo", "HoldPedal", "ModWheel", "Manual" }; CALF_PORT_PROPS(rotary_speaker) = { - { 2, 0, 5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" }, + { 5, 0, 5, 1.01, PF_ENUM | PF_CTL_COMBO, rotary_speaker_speed_names, "vib_speed", "Speed Mode" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "spacing", "Tap Spacing" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "shift", "Tap Offset" }, { 0.10, 0, 1, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mod_depth", "Mod Depth" }, - { 390, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "treble_speed", "Treble Motor" }, - { 410, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "bass_speed", "Bass Motor" }, + { 36, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "treble_speed", "Treble Motor" }, + { 30, 10, 600, 0, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_LOG | PF_UNIT_RPM, NULL, "bass_speed", "Bass Motor" }, { 0.7, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "mic_distance", "Mic Distance" }, { 0.3, 0, 1, 101, PF_FLOAT | PF_CTL_KNOB | PF_SCALE_PERC, NULL, "reflection", "Reflection" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_l", "Low rotor" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_h", "High rotor" }, }; CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speaker", "Krzysztof Foltman", calf_plugins::calf_copyright_info, "SimulationPlugin" }; @@ -188,8 +193,8 @@ CALF_PLUGIN_INFO(rotary_speaker) = { 0x8483, "RotarySpeaker", "Calf Rotary Speak CALF_PORT_NAMES(multichorus) = {"In L", "In R", "Out L", "Out R"}; CALF_PORT_PROPS(multichorus) = { - { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Minimum delay" }, - { 6, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC| PF_PROP_GRAPH, NULL, "mod_depth", "Modulation depth" }, + { 5, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC | PF_PROP_GRAPH, NULL, "min_delay", "Min delay" }, + { 6, 0.1, 10, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC| PF_PROP_GRAPH, NULL, "mod_depth", "Mod depth" }, { 0.5, 0.01, 20, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ| PF_PROP_GRAPH, NULL, "mod_rate", "Modulation rate" }, { 180, 0, 360, 91, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_DEG, NULL, "stereo", "Stereo phase" }, { 4, 1, 8, 8, PF_INT | PF_SCALE_LINEAR | PF_CTL_FADER, NULL, "voices", "Voices"}, @@ -224,8 +229,9 @@ CALF_PORT_PROPS(compressor) = { { 0, 0, 4, 0, PF_ENUM | PF_CTL_COMBO, compressor_weighting_names, "aweighting", "Weighting" }, { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Compression" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "peak", "Peak Output" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip", "0dB" }, { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "input", "Input" }, // { 2000, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "deess_freq", "Frequency" }, // { 0.707, 0.707, 32, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "deess_res", "Q" }, }; @@ -234,6 +240,53 @@ CALF_PLUGIN_INFO(compressor) = { 0x8502, "Compressor", "Calf Compressor", "Thor //////////////////////////////////////////////////////////////////////////// +CALF_PORT_NAMES(sidechaincompressor) = {"In L", "In R", "Out L", "Out R"}; + +const char *sidechaincompressor_detection_names[] = { "RMS", "Peak" }; +const char *sidechaincompressor_stereo_link_names[] = { "Average", "Maximum" }; +const char *sidechaincompressor_mode_names[] = {"Wideband (F1:off / F2:off)", + "Deesser wide (F1:Bell / F2:HP)", + "Deesser split (F1:off / F2:HP)", + "Derumbler wide (F1:LP / F2:Bell)", + "Derumbler split (F1:LP / F2:off)", + "Weighted #1 (F1:Shelf / F2:Shelf)", + "Weighted #2 (F1:Shelf / F2:Bell)", + "Weighted #3 (F1:Bell / F2:Shelf)", + "Bandpass #1 (F1:BP / F2:off)", + "Bandpass #2 (F1:HP / F2:LP)"}; +const char *sidechaincompressor_filter_choices[] = { "12dB", "24dB", "36dB"}; + + +CALF_PORT_PROPS(sidechaincompressor) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, + { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, + { 2, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, + { 20, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "attack", "Attack" }, + { 250, 0.01, 2000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "release", "Release" }, + { 2, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup Gain" }, + { 2.828427125, 1, 8, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "knee", "Knee" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_detection_names, "detection", "Detection" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_stereo_link_names, "stereo_link", "Stereo Link" }, + { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, + { 0, 0, 9, 0, PF_ENUM | PF_CTL_COMBO, sidechaincompressor_mode_names, "sc_mode", "Sidechain Mode" }, + { 250, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Freq" }, + { 4500, 10,18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Freq" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Level" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f1_active", "active" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "f2_active", "active" }, +}; + +CALF_PLUGIN_INFO(sidechaincompressor) = { 0x8502, "Sidechaincompressor", "Calf Sidechain Compressor", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + CALF_PORT_NAMES(multibandcompressor) = {"In L", "In R", "Out L", "Out R"}; const char *multibandcompressor_detection_names[] = { "RMS", "Peak" }; @@ -246,10 +299,10 @@ CALF_PORT_PROPS(multibandcompressor) = { { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "Input R" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "Output L" }, { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "Output R" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, - { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, { 100, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq0", "Split 1/2" }, { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "freq1", "Split 2/3" }, @@ -320,6 +373,197 @@ CALF_PLUGIN_INFO(multibandcompressor) = { 0x8502, "Multibandcompressor", "Calf M //////////////////////////////////////////////////////////////////////////// +CALF_PORT_NAMES(deesser) = {"In L", "In R", "Out L", "Out R"}; + +const char *deesser_detection_names[] = { "RMS", "Peak" }; +const char *deesser_mode_names[] = { "Wide", "Split" }; + + +CALF_PORT_PROPS(deesser) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected", "Detected" }, + { 0, 0.03125, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_CTLO_REVERSE | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL| PF_PROP_GRAPH, NULL, "compression", "Gain Reduction" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "detected_led", "Active" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "Out" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_detection_names, "detection", "Detection" }, + { 0, 0, 1, 0, PF_ENUM | PF_CTL_COMBO, deesser_mode_names, "mode", "Mode" }, + { 0.125, 0.000976563, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "threshold", "Threshold" }, + { 3, 1, 20, 21, PF_FLOAT | PF_SCALE_LOG_INF | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "ratio", "Ratio" }, + { 15, 1, 100, 1, PF_INT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "laxity", "Laxity" }, + { 1, 1, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "makeup", "Makeup" }, + + { 6000, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "f1_freq", "Split" }, + { 4500, 10, 18000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "f2_freq", "Peak" }, + { 1, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f1_level", "Gain" }, + { 4, 0.0625, 16, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "f2_level", "Level" }, + { 1, 0.1, 100,1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "f2_q", "Peak Q" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "sc_listen", "S/C-Listen" }, +}; + +CALF_PLUGIN_INFO(deesser) = { 0x8502, "Deesser", "Calf Deesser", "Markus Schmidt / Thor Harald Johansen", calf_plugins::calf_copyright_info, "CompressorPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer5band) = {"In L", "In R", "Out L", "Out R"}; + +CALF_PORT_PROPS(equalizer5band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_in", "Input" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_in", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_out", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, +}; + +CALF_PLUGIN_INFO(equalizer5band) = { 0x8501, "Equalizer5Band", "Calf Equalizer 5 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +////////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer8band) = {"In L", "In R", "Out L", "Out R"}; +const char *rolloff_mode_names[] = {"12dB", "24dB", "36dB"}; + +CALF_PORT_PROPS(equalizer8band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "active" }, + { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "active" }, + { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p4_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p4_level", "Level 4" }, + { 5000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p4_freq", "Freq 4" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p4_q", "Q 4" }, +}; + +CALF_PLUGIN_INFO(equalizer8band) = { 0x8501, "Equalizer8Band", "Calf Equalizer 8 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + +CALF_PORT_NAMES(equalizer12band) = {"In L", "In R", "Out L", "Out R"}; + +CALF_PORT_PROPS(equalizer12band) = { + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "bypass", "Bypass" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_in", "Input" }, + { 1, 0, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF | PF_PROP_NOBOUNDS, NULL, "level_out", "Output" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_inR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outL", "L" }, + { 0, 0, 1, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_METER | PF_CTLO_LABEL | PF_UNIT_DB | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "meter_outR", "R" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_inR", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outL", "0dB" }, + { 0, 0, 1, 0, PF_FLOAT | PF_CTL_LED | PF_PROP_OUTPUT | PF_PROP_OPTIONAL, NULL, "clip_outR", "0dB" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hp_active", "active" }, + { 30, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "hp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "lp_active", "active" }, + { 18000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "lp_freq", "Freq" }, + { 1, 0, 2, 0, PF_ENUM | PF_CTL_COMBO, rolloff_mode_names, "lp_mode", "Mode" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "ls_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "ls_level", "Level" }, + { 200, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "ls_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "hs_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "hs_level", "Level" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "hs_freq", "Freq" }, + + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p1_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p1_level", "Level 1" }, + { 60, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ | PF_PROP_GRAPH, NULL, "p1_freq", "Freq 1" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p1_q", "Q 1" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p2_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p2_level", "Level 2" }, + { 120, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p2_freq", "Freq 2" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p2_q", "Q 2" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p3_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p3_level", "Level 3" }, + { 250, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p3_freq", "Freq 3" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p3_q", "Q 3" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p4_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p4_level", "Level 4" }, + { 500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p4_freq", "Freq 4" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p4_q", "Q 4" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p5_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p5_level", "Level 5" }, + { 1000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p5_freq", "Freq 5" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p5_q", "Q 5" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p6_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p6_level", "Level 6" }, + { 2500, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p6_freq", "Freq 6" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p6_q", "Q 6" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p7_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p7_level", "Level 7" }, + { 4000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p7_freq", "Freq 7" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p7_q", "Q 7" }, + { 0, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "p8_active", "active" }, + { 1, 0.015625, 64, 0, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL, "p8_level", "Level 8" }, + { 6000, 10, 20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL, "p8_freq", "Freq 8" }, + { 1, 0.1, 100, 1, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_COEF, NULL, "p8_q", "Q 8" }, +}; + +CALF_PLUGIN_INFO(equalizer12band) = { 0x8501, "Equalizer12Band", "Calf Equalizer 12 Band", "Markus Schmidt", calf_plugins::calf_copyright_info, "EqualizerPlugin" }; + +//////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////// CALF_PORT_NAMES(monosynth) = { @@ -363,11 +607,11 @@ CALF_PORT_PROPS(monosynth) = { { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2res", "Env->Res" }, { 1, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC | PF_CTL_KNOB, NULL, "env2amp", "Env->Amp" }, - { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_a", "Attack" }, - { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_d", "Decay" }, + { 1, 1,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_a", "Attack" }, + { 350, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_d", "Decay" }, { 0.5, 0, 1, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "adsr_s", "Sustain" }, - { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_f", "Fade" }, - { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL, "adsr_r", "Release" }, + { 0, -10000,10000, 21, PF_FLOAT | PF_SCALE_LINEAR | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_f", "Fade" }, + { 50, 10,20000, 0, PF_FLOAT | PF_SCALE_LOG | PF_CTL_FADER | PF_UNIT_MSEC, NULL, "adsr_r", "Release" }, { 0, 0, 2, 0, PF_FLOAT | PF_SCALE_PERC, NULL, "key_follow", "Key Follow" }, { 0, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, monosynth_legato_names, "legato", "Legato Mode" }, @@ -608,8 +852,8 @@ CALF_PORT_PROPS(fluidsynth) = { { 0.5, 0, 1, 100, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_PROP_OUTPUT_GAIN, NULL, "master", "Volume" }, { 0, 0, 0, 0, PF_STRING | PF_PROP_MSGCONTEXT, &fluidsynth_init_soundfont, "soundfont", "Soundfont" }, { 2, 0, 3, 0, PF_ENUM | PF_CTL_COMBO, fluidsynth_interpolation_names, "interpolation", "Interpolation" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Enable Reverb" }, - { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Enable Chorus" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "reverb", "Reverb" }, + { 1, 0, 1, 0, PF_BOOL | PF_CTL_TOGGLE, NULL, "chorus", "Chorus" }, }; //////////////////////////////////////////////////////////////////////////// diff --git a/plugins/ladspa_effect/calf/src/modules_dsp.cpp b/plugins/ladspa_effect/calf/src/modules_dsp.cpp index 3ef471b0b..5258c0475 100644 --- a/plugins/ladspa_effect/calf/src/modules_dsp.cpp +++ b/plugins/ladspa_effect/calf/src/modules_dsp.cpp @@ -574,14 +574,12 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, numsamples += offset; float compression = 1.f; - - peak -= peak * 5.f * numsamples / srate; - + peak = 0.f; clip -= std::min(clip, numsamples); while(offset < numsamples) { - float left = ins[0][offset]; - float right = ins[1][offset]; + float left = ins[0][offset] * *params[param_input]; + float right = ins[1][offset] * *params[param_input]; if(aweighting == 1) { left = awL.process(left); @@ -606,8 +604,8 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, compression = gain; gain *= makeup; - float outL = ins[0][offset] * gain; - float outR = ins[1][offset] * gain; + float outL = ins[0][offset] * gain * *params[param_input]; + float outR = ins[1][offset] * gain * *params[param_input]; outs[0][offset] = outL; outs[1][offset] = outR; @@ -615,12 +613,10 @@ uint32_t compressor_audio_module::process(uint32_t offset, uint32_t numsamples, ++offset; float maxLR = std::max(fabs(outL), fabs(outR)); - - if(maxLR > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */ - - if(maxLR > peak) { + if(maxLR > peak) peak = maxLR; - } + + if(peak > 1.f) clip = srate >> 3; /* blink clip LED for 125 ms */ } detected = linSlope; @@ -691,27 +687,27 @@ void multibandcompressor_audio_module::params_changed() // set the params of all filters if(*params[param_freq0] != freq_old[0] or *params[param_sep0] != sep_old[0] or *params[param_q0] != q_old[0]) { lpL0.set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); - lpR0.set_lp_rbj((float)(*params[param_freq0] * (1 - *params[param_sep0])), *params[param_q0], (float)srate); + lpR0.copy_coeffs(lpL0); hpL0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); - hpR0.set_hp_rbj((float)(*params[param_freq0] * (1 + *params[param_sep0])), *params[param_q0], (float)srate); + hpR0.copy_coeffs(hpL0); freq_old[0] = *params[param_freq0]; sep_old[0] = *params[param_sep2]; q_old[0] = *params[param_q2]; } if(*params[param_freq1] != freq_old[1] or *params[param_sep1] != sep_old[1] or *params[param_q1] != q_old[1]) { lpL1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); - lpR1.set_lp_rbj((float)(*params[param_freq1] * (1 - *params[param_sep1])), *params[param_q1], (float)srate); + lpR1.copy_coeffs(lpL1); hpL1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); - hpR1.set_hp_rbj((float)(*params[param_freq1] * (1 + *params[param_sep1])), *params[param_q1], (float)srate); + hpR1.copy_coeffs(hpL1); freq_old[1] = *params[param_freq1]; sep_old[1] = *params[param_sep2]; q_old[1] = *params[param_q2]; } if(*params[param_freq2] != freq_old[2] or *params[param_sep2] != sep_old[2] or *params[param_q2] != q_old[2]) { lpL2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); - lpR2.set_lp_rbj((float)(*params[param_freq2] * (1 - *params[param_sep2])), *params[param_q2], (float)srate); + lpR2.copy_coeffs(lpL2); hpL2.set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); - hpR2.set_hp_rbj((float)(*params[param_freq2] * (1 + *params[param_sep2])), *params[param_q2], (float)srate); + hpR2.copy_coeffs(hpL2); freq_old[2] = *params[param_freq2]; sep_old[2] = *params[param_sep2]; q_old[2] = *params[param_q2]; @@ -720,16 +716,16 @@ void multibandcompressor_audio_module::params_changed() for (int j = 0; j < strips; j ++) { switch (j) { case 0: - strip[j].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], *params[param_bypass0], *params[param_mute0]); + strip[j].set_params(*params[param_attack0], *params[param_release0], *params[param_threshold0], *params[param_ratio0], *params[param_knee0], *params[param_makeup0], *params[param_detection0], 1.f, *params[param_bypass0], *params[param_mute0]); break; case 1: - strip[j].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], *params[param_bypass1], *params[param_mute1]); + strip[j].set_params(*params[param_attack1], *params[param_release1], *params[param_threshold1], *params[param_ratio1], *params[param_knee1], *params[param_makeup1], *params[param_detection1], 1.f, *params[param_bypass1], *params[param_mute1]); break; case 2: - strip[j].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], *params[param_bypass2], *params[param_mute2]); + strip[j].set_params(*params[param_attack2], *params[param_release2], *params[param_threshold2], *params[param_ratio2], *params[param_knee2], *params[param_makeup2], *params[param_detection2], 1.f, *params[param_bypass2], *params[param_mute2]); break; case 3: - strip[j].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], *params[param_bypass3], *params[param_mute3]); + strip[j].set_params(*params[param_attack3], *params[param_release3], *params[param_threshold3], *params[param_ratio3], *params[param_knee3], *params[param_makeup3], *params[param_detection3], 1.f, *params[param_bypass3], *params[param_mute3]); break; } } @@ -778,11 +774,10 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num clip_inR -= std::min(clip_inR, numsamples); clip_outL -= std::min(clip_outL, numsamples); clip_outR -= std::min(clip_outR, numsamples); - meter_inL -= meter_inL * 2.5 * numsamples / srate; - meter_inR -= meter_inR * 2.5 * numsamples / srate; - meter_outL -= meter_outL * 2.5 * numsamples / srate; - meter_outR -= meter_outR * 2.5 * numsamples / srate; - + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; while(offset < numsamples) { // cycle through samples float inL = ins[0][offset]; @@ -873,7 +868,7 @@ uint32_t multibandcompressor_audio_module::process(uint32_t offset, uint32_t num if(outR > 1.f) { clip_outR = srate >> 3; } - // rise up in / out meters + // set up in / out meters if(inL > meter_inL) { meter_inL = inL; } @@ -1054,10 +1049,601 @@ int multibandcompressor_audio_module::get_changed_offsets(int index, int generat } return 0; } -/// Gain reduction module implemented by Markus Schmidt -/// Nearly all functions of this module are originally written + +/// Sidecain Compressor by Markus Schmidt +/// +/// This module splits the signal in a sidechain- and a process signal. +/// The sidechain is processed through Krzystofs filters and compresses +/// the process signal via Thor's compression routine afterwards. +/////////////////////////////////////////////////////////////////////////////////////////////// + +sidechaincompressor_audio_module::sidechaincompressor_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; +} + +void sidechaincompressor_audio_module::activate() +{ + is_active = true; + // set all filters and strips + compressor.activate(); + params_changed(); + meter_in = 0.f; + meter_out = 0.f; + clip_in = 0.f; + clip_out = 0.f; +} +void sidechaincompressor_audio_module::deactivate() +{ + is_active = false; + compressor.deactivate(); +} + +void sidechaincompressor_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old + or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old + or *params[param_sc_mode] != sc_mode) { + float q = 0.707; + switch ((int)*params[param_sc_mode]) { + default: + case WIDEBAND: + f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.f; + f2_active = 0.f; + break; + case DEESSER_WIDE: + f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 1.f; + break; + case DEESSER_SPLIT: + f1L.set_lp_rbj((float)*params[param_f2_freq] * (1 + 0.17), q, (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq] * (1 - 0.17), q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 0.f; + f2_active = 1.f; + break; + case DERUMBLER_WIDE: + f1L.set_lp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.5f; + break; + case DERUMBLER_SPLIT: + f1L.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.f; + break; + case WEIGHTED_1: + f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case WEIGHTED_2: + f1L.set_lowshelf_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_peakeq_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case WEIGHTED_3: + f1L.set_peakeq_rbj((float)*params[param_f1_freq], q, *params[param_f1_level], (float)srate); + f1R.copy_coeffs(f1L); + f2L.set_highshelf_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 0.5f; + f2_active = 0.5f; + break; + case BANDPASS_1: + f1L.set_bp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_hp_rbj((float)*params[param_f2_freq], q, *params[param_f2_level], (float)srate); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 0.f; + break; + case BANDPASS_2: + f1L.set_hp_rbj((float)*params[param_f1_freq], q, (float)srate, *params[param_f1_level]); + f1R.copy_coeffs(f1L); + f2L.set_lp_rbj((float)*params[param_f2_freq], q, (float)srate, *params[param_f2_level]); + f2R.copy_coeffs(f2L); + f1_active = 1.f; + f2_active = 1.f; + break; + } + f1_freq_old = *params[param_f1_freq]; + f1_level_old = *params[param_f1_level]; + f2_freq_old = *params[param_f2_freq]; + f2_level_old = *params[param_f2_level]; + sc_mode = (CalfScModes)*params[param_sc_mode]; + } + // light LED's + if(params[param_f1_active] != NULL) { + *params[param_f1_active] = f1_active; + } + if(params[param_f2_active] != NULL) { + *params[param_f2_active] = f2_active; + } + // and set the compressor module + compressor.set_params(*params[param_attack], *params[param_release], *params[param_threshold], *params[param_ratio], *params[param_knee], *params[param_makeup], *params[param_detection], *params[param_stereo_link], *params[param_bypass], 0.f); +} + +void sidechaincompressor_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; + compressor.set_sample_rate(srate); +} + +uint32_t sidechaincompressor_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; + } else { + // process + + clip_in -= std::min(clip_in, numsamples); + clip_out -= std::min(clip_out, numsamples); + + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + + float leftAC = inL; + float rightAC = inR; + float leftSC = inL; + float rightSC = inR; + float leftMC = inL; + float rightMC = inR; + + switch ((int)*params[param_sc_mode]) { + default: + case WIDEBAND: + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + case DEESSER_WIDE: + case DERUMBLER_WIDE: + case WEIGHTED_1: + case WEIGHTED_2: + case WEIGHTED_3: + case BANDPASS_2: + leftSC = f2L.process(f1L.process(leftSC)); + rightSC = f2R.process(f1R.process(rightSC)); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + case DEESSER_SPLIT: + leftSC = f2L.process(leftSC); + rightSC = f2R.process(rightSC); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftSC, rightSC, leftSC, rightSC); + leftAC = f1L.process(leftAC); + rightAC = f1R.process(rightAC); + leftAC += leftSC; + rightAC += rightSC; + break; + case DERUMBLER_SPLIT: + leftSC = f1L.process(leftSC); + rightSC = f1R.process(rightSC); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftSC, rightSC, leftSC, rightSC); + leftAC = f2L.process(leftAC); + rightAC = f2R.process(rightAC); + leftAC += leftSC; + rightAC += rightSC; + break; + case BANDPASS_1: + leftSC = f1L.process(leftSC); + rightSC = f1R.process(rightSC); + leftMC = leftSC; + rightMC = rightSC; + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + } + + if(*params[param_sc_listen] > 0.f) { + outL = leftMC; + outR = rightMC; + } else { + outL = leftAC; + outR = rightAC; + } + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(std::max(fabs(inL), fabs(inR)) > 1.f) { + clip_in = srate >> 3; + } + if(std::max(fabs(outL), fabs(outR)) > 1.f) { + clip_out = srate >> 3; + } + // rise up out meter + meter_in = std::max(fabs(inL), fabs(inR));; + meter_out = std::max(fabs(outL), fabs(outR));; + + // next sample + ++offset; + } // cycle trough samples + f1L.sanitize(); + f1R.sanitize(); + f2L.sanitize(); + f2R.sanitize(); + + } + // draw meters + if(params[param_clip_in] != NULL) { + *params[param_clip_in] = clip_in; + } + if(params[param_clip_out] != NULL) { + *params[param_clip_out] = clip_out; + } + if(params[param_meter_in] != NULL) { + *params[param_meter_in] = meter_in; + } + if(params[param_meter_out] != NULL) { + *params[param_meter_out] = meter_out; + } + // draw strip meter + if(bypass > 0.5f) { + if(params[param_compression] != NULL) { + *params[param_compression] = 1.0f; + } + } else { + if(params[param_compression] != NULL) { + *params[param_compression] = compressor.get_comp_level(); + } + } + // whatever has to be returned x) + return outputs_mask; +} +bool sidechaincompressor_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_f1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } else if(index == param_compression) { + return compressor.get_graph(subindex, data, points, context); + } + return false; +} + +bool sidechaincompressor_audio_module::get_dot(int index, int subindex, float &x, float &y, int &size, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_compression) { + return compressor.get_dot(subindex, x, y, size, context); + } + return false; +} + +bool sidechaincompressor_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_compression) { + return compressor.get_gridline(subindex, pos, vertical, legend, context); + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +// return false; +} + +int sidechaincompressor_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) + return false; + if(index == param_compression) { + return compressor.get_changed_offsets(generation, subindex_graph, subindex_dot, subindex_gridline); + } else { + // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) + if (*params[param_f1_freq] != f1_freq_old1 + or *params[param_f2_freq] != f2_freq_old1 + or *params[param_f1_level] != f1_level_old1 + or *params[param_f2_level] != f2_level_old1 + or *params[param_sc_mode] !=sc_mode_old1) + { + f1_freq_old1 = *params[param_f1_freq]; + f2_freq_old1 = *params[param_f2_freq]; + f1_level_old1 = *params[param_f1_level]; + f2_level_old1 = *params[param_f2_level]; + sc_mode_old1 = (CalfScModes)*params[param_sc_mode]; + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Deesser by Markus Schmidt +/// +/// This module splits the signal in a sidechain- and a process signal. +/// The sidechain is processed through Krzystofs filters and compresses +/// the process signal via Thor's compression routine afterwards. +/////////////////////////////////////////////////////////////////////////////////////////////// + +deesser_audio_module::deesser_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; +} + +void deesser_audio_module::activate() +{ + is_active = true; + // set all filters and strips + compressor.activate(); + params_changed(); + detected = 0.f; + detected_led = 0.f; + clip_out = 0.f; +} +void deesser_audio_module::deactivate() +{ + is_active = false; + compressor.deactivate(); +} + +void deesser_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_f1_freq] != f1_freq_old or *params[param_f1_level] != f1_level_old + or *params[param_f2_freq] != f2_freq_old or *params[param_f2_level] != f2_level_old + or *params[param_f2_q] != f2_q_old) { + float q = 0.707; + + hpL.set_hp_rbj((float)*params[param_f1_freq] * (1 - 0.17), q, (float)srate, *params[param_f1_level]); + hpR.copy_coeffs(hpL); + lpL.set_lp_rbj((float)*params[param_f1_freq] * (1 + 0.17), q, (float)srate); + lpR.copy_coeffs(lpL); + pL.set_peakeq_rbj((float)*params[param_f2_freq], *params[param_f2_q], *params[param_f2_level], (float)srate); + pR.copy_coeffs(pL); + f1_freq_old = *params[param_f1_freq]; + f1_level_old = *params[param_f1_level]; + f2_freq_old = *params[param_f2_freq]; + f2_level_old = *params[param_f2_level]; + f2_q_old = *params[param_f2_q]; + } + // and set the compressor module + compressor.set_params((float)*params[param_laxity], (float)*params[param_laxity] * 1.33, *params[param_threshold], *params[param_ratio], 2.8, *params[param_makeup], *params[param_detection], 0.f, *params[param_bypass], 0.f); +} + +void deesser_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; + compressor.set_sample_rate(srate); +} + +uint32_t deesser_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_out = 0.f; + detected = 0.f; + detected_led = 0.f; + } else { + // process + + detected_led -= std::min(detected_led, numsamples); + clip_led -= std::min(clip_led, numsamples); + + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + + + float leftAC = inL; + float rightAC = inR; + float leftSC = inL; + float rightSC = inR; + float leftRC = inL; + float rightRC = inR; + float leftMC = inL; + float rightMC = inR; + + leftSC = pL.process(hpL.process(leftSC)); + rightSC = pR.process(hpR.process(rightSC)); + leftMC = leftSC; + rightMC = rightSC; + + switch ((int)*params[param_mode]) { + default: + case WIDE: + compressor.process(leftAC, rightAC, leftSC, rightSC); + break; + case SPLIT: + hpL.sanitize(); + hpR.sanitize(); + leftRC = hpL.process(leftRC); + rightRC = hpR.process(rightRC); + compressor.process(leftRC, rightRC, leftSC, rightSC); + leftAC = lpL.process(leftAC); + rightAC = lpR.process(rightAC); + leftAC += leftRC; + rightAC += rightRC; + break; + } + + if(*params[param_sc_listen] > 0.f) { + outL = leftMC; + outR = rightMC; + } else { + outL = leftAC; + outR = rightAC; + } + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + if(std::max(fabs(leftSC), fabs(rightSC)) > *params[param_threshold]) { + detected_led = srate >> 3; + } + if(std::max(fabs(leftAC), fabs(rightAC)) > 1.f) { + clip_led = srate >> 3; + } + if(clip_led > 0) { + clip_out = 1.f; + } else { + clip_out = std::max(fabs(outL), fabs(outR)); + } + detected = std::max(fabs(leftMC), fabs(rightMC)); + + // next sample + ++offset; + } // cycle trough samples + hpL.sanitize(); + hpR.sanitize(); + lpL.sanitize(); + lpR.sanitize(); + pL.sanitize(); + pR.sanitize(); + } + // draw meters + if(params[param_detected_led] != NULL) { + *params[param_detected_led] = detected_led; + } + if(params[param_clip_out] != NULL) { + *params[param_clip_out] = clip_out; + } + if(params[param_detected] != NULL) { + *params[param_detected] = detected; + } + // draw strip meter + if(bypass > 0.5f) { + if(params[param_compression] != NULL) { + *params[param_compression] = 1.0f; + } + } else { + if(params[param_compression] != NULL) { + *params[param_compression] = compressor.get_comp_level(); + } + } + // whatever has to be returned x) + return outputs_mask; +} +bool deesser_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_f1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool deesser_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + return get_freq_gridline(subindex, pos, vertical, legend, context); + +// return false; +} + +int deesser_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + // (fabs(inertia_cutoff.get_last() - old_cutoff) + 100 * fabs(inertia_resonance.get_last() - old_resonance) + fabs(*params[par_mode] - old_mode) > 0.1f) + if (*params[param_f1_freq] != f1_freq_old1 + or *params[param_f2_freq] != f2_freq_old1 + or *params[param_f1_level] != f1_level_old1 + or *params[param_f2_level] != f2_level_old1 + or *params[param_f2_q] !=f2_q_old1) + { + f1_freq_old1 = *params[param_f1_freq]; + f2_freq_old1 = *params[param_f2_freq]; + f1_level_old1 = *params[param_f1_level]; + f2_level_old1 = *params[param_f2_level]; + f2_q_old1 = *params[param_f2_q]; + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Gain reduction module by Thor +/// All functions of this module are originally written /// by Thor, while some features have been stripped (mainly stereo linking -/// and frequency correction as implemented in his Compressor above) +/// and frequency correction as implemented in Sidechain Compressor above) /// To save some CPU. //////////////////////////////////////////////////////////////////////////////// gain_reduction_audio_module::gain_reduction_audio_module() @@ -1085,14 +1671,20 @@ void gain_reduction_audio_module::deactivate() is_active = false; } -void gain_reduction_audio_module::process(float &left, float &right) +void gain_reduction_audio_module::process(float &left, float &right, float det_left, float det_right) { - float compression = 1.f; - meter_out -= meter_out * 5.f * 1 / srate; + if(!det_left) { + det_left = left; + } + if(!det_right) { + det_right = right; + } + float gain = 1.f; if(bypass < 0.5f) { // this routine is mainly copied from thor's compressor module // greatest sounding compressor I've heard! bool rms = detection == 0; + bool average = stereo_link == 0; float linThreshold = threshold; float attack_coeff = std::min(1.f, 1.f / (attack * srate / 4000.f)); float release_coeff = std::min(1.f, 1.f / (release * srate / 4000.f)); @@ -1105,32 +1697,21 @@ void gain_reduction_audio_module::process(float &left, float &right) kneeStop = log(linKneeStop); compressedKneeStop = (kneeStop - thres) / ratio + thres; - float absample = (fabs(left) + fabs(right)) * 0.5f; + float absample = average ? (fabs(det_left) + fabs(det_right)) * 0.5f : std::max(fabs(det_left), fabs(det_right)); if(rms) absample *= absample; linSlope += (absample - linSlope) * (absample > linSlope ? attack_coeff : release_coeff); - float gain = 1.f; - if(linSlope > 0.f) { gain = output_gain(linSlope, rms); } - compression = gain; - gain *= makeup; - - left *= gain; - right *= gain; - + left *= gain * makeup; + right *= gain * makeup; + meter_out = std::max(fabs(left), fabs(right));; + meter_comp = gain; detected = rms ? sqrt(linSlope) : linSlope; } - - float maxLR = std::max(fabs(left), fabs(right)); - - if(maxLR > meter_out) { - meter_out = maxLR; - } - meter_comp = compression; } float gain_reduction_audio_module::output_level(float slope) { @@ -1167,7 +1748,7 @@ void gain_reduction_audio_module::set_sample_rate(uint32_t sr) { srate = sr; } -void gain_reduction_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float byp, float mu) +void gain_reduction_audio_module::set_params(float att, float rel, float thr, float rat, float kn, float mak, float det, float stl, float byp, float mu) { // set all params attack = att; @@ -1177,6 +1758,7 @@ void gain_reduction_audio_module::set_params(float att, float rel, float thr, fl knee = kn; makeup = mak; detection = det; + stereo_link = stl; bypass = byp; mute = mu; if(mute > 0.f) { @@ -1278,3 +1860,1092 @@ int gain_reduction_audio_module::get_changed_offsets(int generation, int &subind subindex_graph = 2; return last_generation; } + +/// Equalizer 12 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer12band_audio_module::equalizer12band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; +} + +void equalizer12band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer12band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer12band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_hp_freq] != hp_freq_old) { + hpL[0].set_hp_rbj(*params[param_hp_freq], 0.707, (float)srate, 1.0); + hpL[1].copy_coeffs(hpL[0]); + hpL[2].copy_coeffs(hpL[0]); + hpR[0].copy_coeffs(hpL[0]); + hpR[1].copy_coeffs(hpL[0]); + hpR[2].copy_coeffs(hpL[0]); + hp_freq_old = *params[param_hp_freq]; + } + if(*params[param_lp_freq] != lp_freq_old) { + lpL[0].set_lp_rbj(*params[param_lp_freq], 0.707, (float)srate, 1.0); + lpL[1].copy_coeffs(lpL[0]); + lpL[2].copy_coeffs(lpL[0]); + lpR[0].copy_coeffs(lpL[0]); + lpR[1].copy_coeffs(lpL[0]); + lpR[2].copy_coeffs(lpL[0]); + lp_freq_old = *params[param_lp_freq]; + } + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } + if(*params[param_p4_freq] != p_freq_old[3] or *params[param_p4_level] != p_level_old[3] or *params[param_p4_q] != p_q_old[3]) { + pL[3].set_peakeq_rbj((float)*params[param_p4_freq], *params[param_p4_q], *params[param_p4_level], (float)srate); + pR[3].copy_coeffs(pL[3]); + p_freq_old[3] = *params[param_p4_freq]; + p_level_old[3] = *params[param_p4_level]; + p_q_old[3] = *params[param_p4_q]; + } + if(*params[param_p5_freq] != p_freq_old[4] or *params[param_p5_level] != p_level_old[4] or *params[param_p5_q] != p_q_old[4]) { + pL[4].set_peakeq_rbj((float)*params[param_p5_freq], *params[param_p5_q], *params[param_p5_level], (float)srate); + pR[4].copy_coeffs(pL[4]); + p_freq_old[4] = *params[param_p5_freq]; + p_level_old[4] = *params[param_p5_level]; + p_q_old[4] = *params[param_p5_q]; + } + if(*params[param_p6_freq] != p_freq_old[5] or *params[param_p6_level] != p_level_old[5] or *params[param_p6_q] != p_q_old[5]) { + pL[5].set_peakeq_rbj((float)*params[param_p6_freq], *params[param_p6_q], *params[param_p6_level], (float)srate); + pR[5].copy_coeffs(pL[5]); + p_freq_old[5] = *params[param_p6_freq]; + p_level_old[5] = *params[param_p6_level]; + p_q_old[5] = *params[param_p6_q]; + } + if(*params[param_p7_freq] != p_freq_old[6] or *params[param_p7_level] != p_level_old[6] or *params[param_p7_q] != p_q_old[6]) { + pL[6].set_peakeq_rbj((float)*params[param_p7_freq], *params[param_p7_q], *params[param_p7_level], (float)srate); + pR[6].copy_coeffs(pL[6]); + p_freq_old[6] = *params[param_p7_freq]; + p_level_old[6] = *params[param_p7_level]; + p_q_old[6] = *params[param_p7_q]; + } + if(*params[param_p8_freq] != p_freq_old[7] or *params[param_p8_level] != p_level_old[7] or *params[param_p8_q] != p_q_old[7]) { + pL[7].set_peakeq_rbj((float)*params[param_p8_freq], *params[param_p8_q], *params[param_p8_level], (float)srate); + pR[7].copy_coeffs(pL[7]); + p_freq_old[7] = *params[param_p8_freq]; + p_level_old[7] = *params[param_p8_level]; + p_q_old[7] = *params[param_p8_q]; + } +} + +void equalizer12band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer12band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + } else { + + clip_inL -= std::min(clip_inL, numsamples); + clip_inR -= std::min(clip_inR, numsamples); + clip_outL -= std::min(clip_outL, numsamples); + clip_outR -= std::min(clip_outR, numsamples); + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + procL = hpL[0].process(procL); + procR = hpR[0].process(procR); + break; + case MODE24DB: + procL = hpL[1].process(hpL[0].process(procL)); + procR = hpR[1].process(hpR[0].process(procR)); + break; + case MODE36DB: + procL = hpL[2].process(hpL[1].process(hpL[0].process(procL))); + procR = hpR[2].process(hpR[1].process(hpR[0].process(procR))); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + procL = lpL[0].process(procL); + procR = lpR[0].process(procR); + break; + case MODE24DB: + procL = lpL[1].process(lpL[0].process(procL)); + procR = lpR[1].process(lpR[0].process(procR)); + break; + case MODE36DB: + procL = lpL[2].process(lpL[1].process(lpL[0].process(procL))); + procR = lpR[2].process(lpR[1].process(lpR[0].process(procR))); + break; + } + } + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + if(*params[param_p4_active] > 0.f) { + procL = pL[3].process(procL); + procR = pR[3].process(procR); + } + if(*params[param_p5_active] > 0.f) { + procL = pL[4].process(procL); + procR = pR[4].process(procR); + } + if(*params[param_p6_active] > 0.f) { + procL = pL[5].process(procL); + procR = pR[5].process(procR); + } + if(*params[param_p7_active] > 0.f) { + procL = pL[6].process(procL); + procR = pR[6].process(procR); + } + if(*params[param_p8_active] > 0.f) { + procL = pL[7].process(procL); + procR = pR[7].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(inL > 1.f) { + clip_inL = srate >> 3; + } + if(inR > 1.f) { + clip_inR = srate >> 3; + } + if(outL > 1.f) { + clip_outL = srate >> 3; + } + if(outR > 1.f) { + clip_outR = srate >> 3; + } + // set up in / out meters + if(inL > meter_inL) { + meter_inL = inL; + } + if(inR > meter_inR) { + meter_inR = inR; + } + if(outL > meter_outL) { + meter_outL = outL; + } + if(outR > meter_outR) { + meter_outR = outR; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + for(int i = 0; i < 3; ++i) { + hpL[i].sanitize(); + hpR[i].sanitize(); + lpL[i].sanitize(); + lpR[i].sanitize(); + } + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 8; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // draw meters + if(params[param_clip_inL] != NULL) { + *params[param_clip_inL] = clip_inL; + } + if(params[param_clip_inR] != NULL) { + *params[param_clip_inR] = clip_inR; + } + if(params[param_clip_outL] != NULL) { + *params[param_clip_outL] = clip_outL; + } + if(params[param_clip_outR] != NULL) { + *params[param_clip_outR] = clip_outR; + } + + if(params[param_meter_inL] != NULL) { + *params[param_meter_inL] = meter_inL; + } + if(params[param_meter_inR] != NULL) { + *params[param_meter_inR] = meter_inR; + } + if(params[param_meter_outL] != NULL) { + *params[param_meter_outL] = meter_outL; + } + if(params[param_meter_outR] != NULL) { + *params[param_meter_outR] = meter_outR; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer12band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer12band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer12band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_hp_freq] != hp_freq_old1 + or *params[param_hp_mode] != hp_mode_old1 + or *params[param_lp_freq] != lp_freq_old1 + or *params[param_lp_mode] != lp_mode_old1 + + or *params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2] + + or *params[param_p4_freq] != p_freq_old1[3] + or *params[param_p4_level] != p_level_old1[3] + or *params[param_p4_q] != p_q_old1[3] + + or *params[param_p5_freq] != p_freq_old1[4] + or *params[param_p5_level] != p_level_old1[4] + or *params[param_p5_q] != p_q_old1[4] + + or *params[param_p6_freq] != p_freq_old1[5] + or *params[param_p6_level] != p_level_old1[5] + or *params[param_p6_q] != p_q_old1[5] + + or *params[param_p7_freq] != p_freq_old1[6] + or *params[param_p7_level] != p_level_old1[6] + or *params[param_p7_q] != p_q_old1[6] + + or *params[param_p8_freq] != p_freq_old1[7] + or *params[param_p8_level] != p_level_old1[7] + or *params[param_p8_q] != p_q_old1[7]) + { + + hp_freq_old1 = *params[param_hp_freq]; + hp_mode_old1 = *params[param_hp_mode]; + lp_freq_old1 = *params[param_lp_freq]; + lp_mode_old1 = *params[param_lp_mode]; + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + p_freq_old1[3] = *params[param_p4_freq]; + p_level_old1[3] = *params[param_p4_level]; + p_q_old1[3] = *params[param_p4_q]; + + p_freq_old1[4] = *params[param_p5_freq]; + p_level_old1[4] = *params[param_p5_level]; + p_q_old1[4] = *params[param_p5_q]; + + p_freq_old1[5] = *params[param_p6_freq]; + p_level_old1[5] = *params[param_p6_level]; + p_q_old1[5] = *params[param_p6_q]; + + p_freq_old1[6] = *params[param_p7_freq]; + p_level_old1[6] = *params[param_p7_level]; + p_q_old1[6] = *params[param_p7_q]; + + p_freq_old1[7] = *params[param_p8_freq]; + p_level_old1[7] = *params[param_p8_level]; + p_q_old1[7] = *params[param_p8_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Equalizer 8 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer8band_audio_module::equalizer8band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; +} + +void equalizer8band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer8band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer8band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_hp_freq] != hp_freq_old) { + hpL[0].set_hp_rbj(*params[param_hp_freq], 0.707, (float)srate, 1.0); + hpL[1].copy_coeffs(hpL[0]); + hpL[2].copy_coeffs(hpL[0]); + hpR[0].copy_coeffs(hpL[0]); + hpR[1].copy_coeffs(hpL[0]); + hpR[2].copy_coeffs(hpL[0]); + hp_freq_old = *params[param_hp_freq]; + } + if(*params[param_lp_freq] != lp_freq_old) { + lpL[0].set_lp_rbj(*params[param_lp_freq], 0.707, (float)srate, 1.0); + lpL[1].copy_coeffs(lpL[0]); + lpL[2].copy_coeffs(lpL[0]); + lpR[0].copy_coeffs(lpL[0]); + lpR[1].copy_coeffs(lpL[0]); + lpR[2].copy_coeffs(lpL[0]); + lp_freq_old = *params[param_lp_freq]; + } + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } + if(*params[param_p4_freq] != p_freq_old[3] or *params[param_p4_level] != p_level_old[3] or *params[param_p4_q] != p_q_old[3]) { + pL[3].set_peakeq_rbj((float)*params[param_p4_freq], *params[param_p4_q], *params[param_p4_level], (float)srate); + pR[3].copy_coeffs(pL[3]); + p_freq_old[3] = *params[param_p4_freq]; + p_level_old[3] = *params[param_p4_level]; + p_q_old[3] = *params[param_p4_q]; + } +} + +void equalizer8band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer8band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_inL = 0.f; + clip_inR = 0.f; + clip_outL = 0.f; + clip_outR = 0.f; + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + } else { + + clip_inL -= std::min(clip_inL, numsamples); + clip_inR -= std::min(clip_inR, numsamples); + clip_outL -= std::min(clip_outL, numsamples); + clip_outR -= std::min(clip_outR, numsamples); + meter_inL = 0.f; + meter_inR = 0.f; + meter_outL = 0.f; + meter_outR = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_hp_active] > 0.f) { + switch((int)*params[param_hp_mode]) { + case MODE12DB: + procL = hpL[0].process(procL); + procR = hpR[0].process(procR); + break; + case MODE24DB: + procL = hpL[1].process(hpL[0].process(procL)); + procR = hpR[1].process(hpR[0].process(procR)); + break; + case MODE36DB: + procL = hpL[2].process(hpL[1].process(hpL[0].process(procL))); + procR = hpR[2].process(hpR[1].process(hpR[0].process(procR))); + break; + } + } + if(*params[param_lp_active] > 0.f) { + switch((int)*params[param_lp_mode]) { + case MODE12DB: + procL = lpL[0].process(procL); + procR = lpR[0].process(procR); + break; + case MODE24DB: + procL = lpL[1].process(lpL[0].process(procL)); + procR = lpR[1].process(lpR[0].process(procR)); + break; + case MODE36DB: + procL = lpL[2].process(lpL[1].process(lpL[0].process(procL))); + procR = lpR[2].process(lpR[1].process(lpR[0].process(procR))); + break; + } + } + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + if(*params[param_p4_active] > 0.f) { + procL = pL[3].process(procL); + procR = pR[3].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + if(inL > 1.f) { + clip_inL = srate >> 3; + } + if(inR > 1.f) { + clip_inR = srate >> 3; + } + if(outL > 1.f) { + clip_outL = srate >> 3; + } + if(outR > 1.f) { + clip_outR = srate >> 3; + } + // set up in / out meters + if(inL > meter_inL) { + meter_inL = inL; + } + if(inR > meter_inR) { + meter_inR = inR; + } + if(outL > meter_outL) { + meter_outL = outL; + } + if(outR > meter_outR) { + meter_outR = outR; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + for(int i = 0; i < 3; ++i) { + hpL[i].sanitize(); + hpR[i].sanitize(); + lpL[i].sanitize(); + lpR[i].sanitize(); + } + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 4; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // draw meters + if(params[param_clip_inL] != NULL) { + *params[param_clip_inL] = clip_inL; + } + if(params[param_clip_inR] != NULL) { + *params[param_clip_inR] = clip_inR; + } + if(params[param_clip_outL] != NULL) { + *params[param_clip_outL] = clip_outL; + } + if(params[param_clip_outR] != NULL) { + *params[param_clip_outR] = clip_outR; + } + + if(params[param_meter_inL] != NULL) { + *params[param_meter_inL] = meter_inL; + } + if(params[param_meter_inR] != NULL) { + *params[param_meter_inR] = meter_inR; + } + if(params[param_meter_outL] != NULL) { + *params[param_meter_outL] = meter_outL; + } + if(params[param_meter_outR] != NULL) { + *params[param_meter_outR] = meter_outR; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer8band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer8band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer8band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_hp_freq] != hp_freq_old1 + or *params[param_hp_mode] != hp_mode_old1 + or *params[param_lp_freq] != lp_freq_old1 + or *params[param_lp_mode] != lp_mode_old1 + + or *params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2] + + or *params[param_p4_freq] != p_freq_old1[3] + or *params[param_p4_level] != p_level_old1[3] + or *params[param_p4_q] != p_q_old1[3]) + { + + hp_freq_old1 = *params[param_hp_freq]; + hp_mode_old1 = *params[param_hp_mode]; + lp_freq_old1 = *params[param_lp_freq]; + lp_mode_old1 = *params[param_lp_mode]; + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + p_freq_old1[3] = *params[param_p4_freq]; + p_level_old1[3] = *params[param_p4_level]; + p_q_old1[3] = *params[param_p4_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} + +/// Equalizer 5 Band by Markus Schmidt +/// +/// This module is based on Krzysztof's filters. It provides a couple +/// of different chained filters. +/////////////////////////////////////////////////////////////////////////////////////////////// + +equalizer5band_audio_module::equalizer5band_audio_module() +{ + is_active = false; + srate = 0; + last_generation = 0; + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; +} + +void equalizer5band_audio_module::activate() +{ + is_active = true; + // set all filters + params_changed(); +} +void equalizer5band_audio_module::deactivate() +{ + is_active = false; +} + +void equalizer5band_audio_module::params_changed() +{ + // set the params of all filters + if(*params[param_ls_freq] != ls_freq_old or *params[param_ls_level] != ls_level_old) { + lsL.set_lowshelf_rbj(*params[param_ls_freq], 0.707, *params[param_ls_level], (float)srate); + lsR.copy_coeffs(lsL); + ls_level_old = *params[param_ls_level]; + ls_freq_old = *params[param_ls_freq]; + } + if(*params[param_hs_freq] != hs_freq_old or *params[param_hs_level] != hs_level_old) { + hsL.set_highshelf_rbj(*params[param_hs_freq], 0.707, *params[param_hs_level], (float)srate); + hsR.copy_coeffs(hsL); + hs_level_old = *params[param_hs_level]; + hs_freq_old = *params[param_hs_freq]; + } + if(*params[param_p1_freq] != p_freq_old[0] or *params[param_p1_level] != p_level_old[0] or *params[param_p1_q] != p_q_old[0]) { + pL[0].set_peakeq_rbj((float)*params[param_p1_freq], *params[param_p1_q], *params[param_p1_level], (float)srate); + pR[0].copy_coeffs(pL[0]); + p_freq_old[0] = *params[param_p1_freq]; + p_level_old[0] = *params[param_p1_level]; + p_q_old[0] = *params[param_p1_q]; + } + if(*params[param_p2_freq] != p_freq_old[1] or *params[param_p2_level] != p_level_old[1] or *params[param_p2_q] != p_q_old[1]) { + pL[1].set_peakeq_rbj((float)*params[param_p2_freq], *params[param_p2_q], *params[param_p2_level], (float)srate); + pR[1].copy_coeffs(pL[1]); + p_freq_old[1] = *params[param_p2_freq]; + p_level_old[1] = *params[param_p2_level]; + p_q_old[1] = *params[param_p2_q]; + } + if(*params[param_p3_freq] != p_freq_old[2] or *params[param_p3_level] != p_level_old[2] or *params[param_p3_q] != p_q_old[2]) { + pL[2].set_peakeq_rbj((float)*params[param_p3_freq], *params[param_p3_q], *params[param_p3_level], (float)srate); + pR[2].copy_coeffs(pL[2]); + p_freq_old[2] = *params[param_p3_freq]; + p_level_old[2] = *params[param_p3_level]; + p_q_old[2] = *params[param_p3_q]; + } +} + +void equalizer5band_audio_module::set_sample_rate(uint32_t sr) +{ + srate = sr; +} + +uint32_t equalizer5band_audio_module::process(uint32_t offset, uint32_t numsamples, uint32_t inputs_mask, uint32_t outputs_mask) +{ + bool bypass = *params[param_bypass] > 0.5f; + numsamples += offset; + if(bypass) { + // everything bypassed + while(offset < numsamples) { + outs[0][offset] = ins[0][offset]; + outs[1][offset] = ins[1][offset]; + ++offset; + } + // displays, too + clip_in = 0.f; + clip_out = 0.f; + meter_in = 0.f; + meter_out = 0.f; + } else { + + clip_in -= std::min(clip_in, numsamples); + clip_out -= std::min(clip_out, numsamples); + meter_in = 0.f; + meter_out = 0.f; + + // process + while(offset < numsamples) { + // cycle through samples + float outL = 0.f; + float outR = 0.f; + float inL = ins[0][offset]; + float inR = ins[1][offset]; + // in level + inR *= *params[param_level_in]; + inL *= *params[param_level_in]; + + float procL = inL; + float procR = inR; + + // all filters in chain + if(*params[param_ls_active] > 0.f) { + procL = lsL.process(procL); + procR = lsR.process(procR); + } + if(*params[param_hs_active] > 0.f) { + procL = hsL.process(procL); + procR = hsR.process(procR); + } + if(*params[param_p1_active] > 0.f) { + procL = pL[0].process(procL); + procR = pR[0].process(procR); + } + if(*params[param_p2_active] > 0.f) { + procL = pL[1].process(procL); + procR = pR[1].process(procR); + } + if(*params[param_p3_active] > 0.f) { + procL = pL[2].process(procL); + procR = pR[2].process(procR); + } + + outL = procL * *params[param_level_out]; + outR = procR * *params[param_level_out]; + + // send to output + outs[0][offset] = outL; + outs[1][offset] = outR; + + // clip LED's + float maxIn = std::max(fabs(inL), fabs(inR)); + float maxOut = std::max(fabs(outL), fabs(outR)); + + if(maxIn > 1.f) { + clip_in = srate >> 3; + } + if(maxOut > 1.f) { + clip_out = srate >> 3; + } + // set up in / out meters + if(maxIn > meter_in) { + meter_in = maxIn; + } + if(maxOut > meter_out) { + meter_out = maxOut; + } + + // next sample + ++offset; + } // cycle trough samples + // clean up + lsL.sanitize(); + hsR.sanitize(); + for(int i = 0; i < 3; ++i) { + pL[i].sanitize(); + pR[i].sanitize(); + } + } + // draw meters + if(params[param_clip_in] != NULL) { + *params[param_clip_in] = clip_in; + } + if(params[param_clip_out] != NULL) { + *params[param_clip_out] = clip_out; + } + + if(params[param_meter_in] != NULL) { + *params[param_meter_in] = meter_in; + } + if(params[param_meter_out] != NULL) { + *params[param_meter_out] = meter_out; + } + // whatever has to be returned x) + return outputs_mask; +} +bool equalizer5band_audio_module::get_graph(int index, int subindex, float *data, int points, cairo_iface *context) +{ + if (!is_active) + return false; + if (index == param_p1_freq && !subindex) { + context->set_line_width(1.5); + return ::get_graph(*this, subindex, data, points); + } + return false; +} + +bool equalizer5band_audio_module::get_gridline(int index, int subindex, float &pos, bool &vertical, std::string &legend, cairo_iface *context) +{ + if (!is_active) { + return false; + } else { + return get_freq_gridline(subindex, pos, vertical, legend, context); + } +} + +int equalizer5band_audio_module::get_changed_offsets(int index, int generation, int &subindex_graph, int &subindex_dot, int &subindex_gridline) +{ + if (!is_active) { + return false; + } else { + if (*params[param_ls_freq] != ls_freq_old1 + or *params[param_ls_level] != ls_level_old1 + or *params[param_hs_freq] != hs_freq_old1 + or *params[param_hs_level] != hs_level_old1 + + or *params[param_p1_freq] != p_freq_old1[0] + or *params[param_p1_level] != p_level_old1[0] + or *params[param_p1_q] != p_q_old1[0] + + or *params[param_p2_freq] != p_freq_old1[1] + or *params[param_p2_level] != p_level_old1[1] + or *params[param_p2_q] != p_q_old1[1] + + or *params[param_p3_freq] != p_freq_old1[2] + or *params[param_p3_level] != p_level_old1[2] + or *params[param_p3_q] != p_q_old1[2]) + { + + ls_freq_old1 = *params[param_ls_freq]; + ls_level_old1 = *params[param_ls_level]; + hs_freq_old1 = *params[param_hs_freq]; + hs_level_old1 = *params[param_hs_level]; + + p_freq_old1[0] = *params[param_p1_freq]; + p_level_old1[0] = *params[param_p1_level]; + p_q_old1[0] = *params[param_p1_q]; + + p_freq_old1[1] = *params[param_p2_freq]; + p_level_old1[1] = *params[param_p2_level]; + p_q_old1[1] = *params[param_p2_q]; + + p_freq_old1[2] = *params[param_p3_freq]; + p_level_old1[2] = *params[param_p3_level]; + p_q_old1[2] = *params[param_p3_q]; + + last_generation++; + subindex_graph = 0; + subindex_dot = INT_MAX; + subindex_gridline = INT_MAX; + } + else { + subindex_graph = 0; + subindex_dot = subindex_gridline = generation ? INT_MAX : 0; + } + if (generation == last_calculated_generation) + subindex_graph = INT_MAX; + return last_generation; + } + return false; +} diff --git a/plugins/midi_import/MidiImport.cpp b/plugins/midi_import/MidiImport.cpp index 15463c043..f2e62b058 100644 --- a/plugins/midi_import/MidiImport.cpp +++ b/plugins/midi_import/MidiImport.cpp @@ -572,12 +572,10 @@ extern "C" // neccessary for getting instance out of shared lib Plugin * PLUGIN_EXPORT lmms_plugin_main( Model *, void * _data ) { - return new MidiImport( static_cast( _data ) ); + return new MidiImport( QString::fromUtf8( + static_cast( _data ) ) ); } } - -#undef pos -#undef setValue diff --git a/plugins/patman/patman.cpp b/plugins/patman/patman.cpp index 3c16402d4..0bb8a887b 100644 --- a/plugins/patman/patman.cpp +++ b/plugins/patman/patman.cpp @@ -215,7 +215,7 @@ patmanInstrument::LoadErrors patmanInstrument::loadPatch( { unloadCurrentPatch(); - FILE * fd = fopen( _filename.toAscii().constData() , "rb" ); + FILE * fd = fopen( _filename.toUtf8().constData() , "rb" ); if( !fd ) { perror( "fopen" ); diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index 8d8c2ba1b..94374a8aa 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -419,6 +419,8 @@ void VstPlugin::loadChunk( const QByteArray & _chunk ) if( tf.open() ) { tf.write( _chunk ); + tf.flush(); + lock(); sendMessage( message( IdLoadSettingsFromFile ). addString( diff --git a/plugins/zynaddsubfx/src/AUTHORS.txt b/plugins/zynaddsubfx/AUTHORS.txt similarity index 70% rename from plugins/zynaddsubfx/src/AUTHORS.txt rename to plugins/zynaddsubfx/AUTHORS.txt index 83014b3d1..e2441c036 100644 --- a/plugins/zynaddsubfx/src/AUTHORS.txt +++ b/plugins/zynaddsubfx/AUTHORS.txt @@ -11,6 +11,8 @@ Contributors: Daniel Clemente (with a workaround of X11 repeated key bug) Emmanuel Saracco (fix for JACK output) Achim Settelmeier (QUERTZ keyboard layout for virtual keyboard) - Jérémie Andréi (AZERTY keyboard layout, Array index fix) + Jérémie Andréi (AZERTY keyboard layout, Array index fix, OSS failsafe) Alexis Ballier (const char* <-> string mismatch, NULLMidi prototype fix) + Tobias Doerffel (static-instance variables fix, missing include fix) + James Morris (Memory leaks in FLTK GUI) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt index 763112f58..4b835adc0 100644 --- a/plugins/zynaddsubfx/CMakeLists.txt +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -53,7 +53,7 @@ IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) # build ZynAddSubFX with full optimizations -SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wno-write-strings -Wno-deprecated-declarations") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -Wno-write-strings -Wno-deprecated-declarations") # link system-libraries when on win32 IF(LMMS_BUILD_WIN32) @@ -106,7 +106,8 @@ SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PLUGIN_DIR}") SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) ADD_EXECUTABLE(RemoteZynAddSubFx RemoteZynAddSubFx.cpp ${ZYN_SRC_GUI}) INSTALL(TARGETS RemoteZynAddSubFx RUNTIME DESTINATION ${PLUGIN_DIR}) -TARGET_LINK_LIBRARIES(RemoteZynAddSubFx ZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) +TARGET_LINK_LIBRARIES(RemoteZynAddSubFx -L${CMAKE_CURRENT_BINARY_DIR} -lZynAddSubFxCore ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) +ADD_DEPENDENCIES(RemoteZynAddSubFx ZynAddSubFxCore) # link system libraries when on win32 IF(LMMS_BUILD_WIN32) diff --git a/plugins/zynaddsubfx/src/COPYING b/plugins/zynaddsubfx/COPYING similarity index 100% rename from plugins/zynaddsubfx/src/COPYING rename to plugins/zynaddsubfx/COPYING diff --git a/plugins/zynaddsubfx/src/ChangeLog b/plugins/zynaddsubfx/ChangeLog similarity index 96% rename from plugins/zynaddsubfx/src/ChangeLog rename to plugins/zynaddsubfx/ChangeLog index f1922e210..fc73cf1c4 100644 --- a/plugins/zynaddsubfx/src/ChangeLog +++ b/plugins/zynaddsubfx/ChangeLog @@ -1,4 +1,4 @@ -6 Mar 2002 -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Rolirudnap +6 Mar 2002 -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Pandurilor 7/8 Mar 2002 - Started to do diagrams 10 Mar 2002 - Started to write "voice" 11 Mar 2002 - Heard first sound @@ -892,3 +892,68 @@ 07 Sep 2009 (Mark McCurry) - Fixed glitch in XMLwrapper, which would prevent file loading + +11 Sep 2009 (Mark McCurry) + - Moved PADsynth_used from public struct to has/set methods in + XMLwrapper + - Created wrapper functions, so that XMLwrapper can be somewhat + usable when const + - Removed multiple addparam methods and replaced it with one + variable argument function + - Replaced int2str, real2str, str2int, and str2real from XMLwrapper + with stringTo and stringFrom function templates in Util. + - Moved newFFTFREQS and deleteFFTFREQS from Util to FFTwrapper + - Removed unneeded stack from XMLwrapper + +18 Sep 2009 (Mark McCurry) + - Started to use versioning information in XMLwrapper + - Remove last of stack helper functions in XMLwrapper + - Added std::string retreval to XMLwrapper + +20 Sep 2009 (Paul Nasca) + - Started to implement the Unison effect for ADsynth + +22 Sep 2009 (Paul Nasca) + - Added vibratto and other features to Unison effect + +22 Sep 2009 (Mark McCurry) + - Changed temporary data for Oscilgen from static to instance + recommended by Tobias Doerffel + - Fixed Memory leaks in UI based upon James Morris' patch + +23 Sep 2009 (Paul Nasca) + - Added unison invert phase + - Made unison frequency spread to depend on Bandwidth controllers and parameters + - Added unison vibratto speed control and other improvements + - bugfixes: Voice Amplitude Envelope and FM + +24 Sep 2009 (Paul Nasca) + - Small enhancements and bugfixes to Unison + - Started to implement Bandwidth to the Reverb effect + +25 Sep 2009 (Mark McCurry) + - Allowed for XMLwrapper to retrieve strings stored in mxml TEXT + fields +29 Sep 2009 (Paul Nasca) + - Remove the old (FFT based) Bandwidth effect to Reverb and started rewrite it (based on multivoice chorus/unison effect) + +01 Oct 2009 (Paul Nasca) + - Corrected the ADsynth unison LFO rounding function + - Made Unison based on Bandwidth (in cents) parameter + +02 Oct 2009 (Mark McCurry) + - Added OSS failsafe by Jérémie Andréi + +04 Oct 2009 (Mark McCurry) + - fixed Ctest issues + +06 Oct 2009 (Mark McCurry) + - Added first simple profiling test + +08 Oct 2009 (Mark McCurry) + - Started to see if memset/memcpy offer performance benifits when + widely used + - Added basic SUBnote test + +09 Oct 2009 (Mark McCurry) + - Restylized codebase with uncrustify diff --git a/plugins/zynaddsubfx/src/FAQ.txt b/plugins/zynaddsubfx/FAQ.txt similarity index 100% rename from plugins/zynaddsubfx/src/FAQ.txt rename to plugins/zynaddsubfx/FAQ.txt diff --git a/plugins/zynaddsubfx/src/HISTORY.txt b/plugins/zynaddsubfx/HISTORY.txt similarity index 100% rename from plugins/zynaddsubfx/src/HISTORY.txt rename to plugins/zynaddsubfx/HISTORY.txt diff --git a/plugins/zynaddsubfx/src/README.txt b/plugins/zynaddsubfx/README.txt similarity index 100% rename from plugins/zynaddsubfx/src/README.txt rename to plugins/zynaddsubfx/README.txt diff --git a/plugins/zynaddsubfx/ZynAddSubFx.cpp b/plugins/zynaddsubfx/ZynAddSubFx.cpp index 774f58047..b8a2e5906 100644 --- a/plugins/zynaddsubfx/ZynAddSubFx.cpp +++ b/plugins/zynaddsubfx/ZynAddSubFx.cpp @@ -157,6 +157,7 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this ) QByteArray a = doc.toString( 0 ).toUtf8(); a.prepend( "\n" ); tf.write( a ); + tf.flush(); const std::string fn = QSTR_TO_STDSTR( QDir::toNativeSeparators( tf.fileName() ) ); diff --git a/plugins/zynaddsubfx/src/bugs.txt b/plugins/zynaddsubfx/bugs.txt similarity index 100% rename from plugins/zynaddsubfx/src/bugs.txt rename to plugins/zynaddsubfx/bugs.txt diff --git a/plugins/zynaddsubfx/fltk/CHANGES b/plugins/zynaddsubfx/fltk/CHANGES index d483336ff..9d9ba3427 100644 --- a/plugins/zynaddsubfx/fltk/CHANGES +++ b/plugins/zynaddsubfx/fltk/CHANGES @@ -1,5 +1,22 @@ CHANGES IN FLTK 1.3.0 + - Managing all Widget flags in a single location now (STR #2161) + - Fixed all color related call to Fl_Color type (STR #2208) + - File chooser preview now recognizes utf8 encoded + text files (STR #2218) + - Empty functions in Fluid no longer create an + implementation (STR #2259) + - Fixed Fluid dependency on X11 (STR #2261) + - Updated the bundled libpng to v1.2.40 (released Sep. 10, 2009) + - Fixed Fl_Choice contrast with light-on-dark settings (STR #2219) + - Fixed X server "lock", if a modal dialog window is opened + while a menu is active (STR #1986) + - Updated mirror sites in documentation (STR #2220) + - Setting a default font for Xft (STR #2216) + - Temporarily limited builds to 32-bit on OX S to stay + compatible to Snow Leopard + - Fixed Windows compile bug with "#define USE_COLORMAP 0" + (STR #2241) - Fixed glibc 2.10 compiler problems (Fedora 11 and others) with scandir() and strchr() (STR #2222) - Corrected const methods of Fl_Text_{Buffer|Display|Selection} @@ -27,7 +44,6 @@ CHANGES IN FLTK 1.3.0 - Added drop box to utf8 test that will show the utf8 encoding for the first dropped character - Restructured the unittest application - - Updated the bundled libpng to v1.2.35 (released 18 Feb. 2009) - Fl_Preferences.H now doesn't include windows.h any more (Windows only, STR #2173). - Fl_Window::draw() now doesn't reset its x/y-coordinates to 0 diff --git a/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx b/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx index 9e92850a7..bfe97ac95 100644 --- a/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx +++ b/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx @@ -29,7 +29,7 @@ int main() { struct jpeg_decompress_struct cinfo; jpeg_create_decompress(&cinfo); - jpeg_read_header(&cinfo, true); + jpeg_read_header(&cinfo, TRUE); return 1; } diff --git a/plugins/zynaddsubfx/fltk/CMakeLists.txt b/plugins/zynaddsubfx/fltk/CMakeLists.txt index 70892eb5e..d877e6c18 100644 --- a/plugins/zynaddsubfx/fltk/CMakeLists.txt +++ b/plugins/zynaddsubfx/fltk/CMakeLists.txt @@ -67,6 +67,7 @@ IF(UNIX) ENDIF(UNIX) +# OS X with X11 is not currently supported! SET(FLTK_X11 1) SET(FLTK_APPLE 0) IF(APPLE) @@ -92,7 +93,7 @@ ENDIF(CYGWIN) IF(MINGW) ADD_DEFINITIONS(-DWIN32) - SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid wsock32 gdi32 comdlg32) + SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid comctl32 gdi32 comdlg32) ENDIF(MINGW) INCLUDE(CheckIncludeFiles) diff --git a/plugins/zynaddsubfx/fltk/FL/Enumerations.H b/plugins/zynaddsubfx/fltk/FL/Enumerations.H index a9b71b463..ba92ec2b0 100644 --- a/plugins/zynaddsubfx/fltk/FL/Enumerations.H +++ b/plugins/zynaddsubfx/fltk/FL/Enumerations.H @@ -1,5 +1,5 @@ // -// "$Id: Enumerations.H 6735 2009-04-01 22:11:57Z engelsman $" +// "$Id: Enumerations.H 6902 2009-09-27 11:06:56Z matt $" // // Enumerations for the Fast Light Tool Kit (FLTK). // @@ -330,6 +330,8 @@ enum Fl_When { // Fl_Widget::when(): /*@{*/ +// FIXME: These codes collide with valid Unicode keys + #define FL_Button 0xfee8 ///< A mouse button; use Fl_Button + n for mouse button n. #define FL_BackSpace 0xff08 ///< The backspace key. #define FL_Tab 0xff09 ///< The tab key. @@ -391,6 +393,9 @@ enum Fl_When { // Fl_Widget::when(): /*@{*/ // group: Event States +// FIXME: it would be nice to have the modifiers in the upper 8 bit so that +// a unicode ke (24bit) can be sent as an unsigned with the modifiers. + #define FL_SHIFT 0x00010000 ///< One of the shift keys is down #define FL_CAPS_LOCK 0x00020000 ///< The caps lock is on #define FL_CTRL 0x00040000 ///< One of the ctrl keys is down @@ -407,10 +412,15 @@ enum Fl_When { // Fl_Widget::when(): #define FL_BUTTONS 0x7f000000 ///< Any mouse button is pushed #define FL_BUTTON(n) (0x00800000<<(n)) ///< Mouse button n (n > 0) is pushed +#define FL_KEY_MASK 0x0000ffff ///< All keys are 16 bit for now + // FIXME: Unicode needs 24 bits! + #ifdef __APPLE__ -# define FL_COMMAND FL_META ///< An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X +# define FL_COMMAND FL_META ///< An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X +# define FL_CONTROL FL_CTRL ///< An alias for FL_META on WIN32 and X11, or FL_META on MacOS X #else # define FL_COMMAND FL_CTRL ///< An alias for FL_CTRL on WIN32 and X11, or FL_META on MacOS X +# define FL_CONTROL FL_META ///< An alias for FL_META on WIN32 and X11, or FL_META on MacOS X #endif // __APPLE__ /*@}*/ // group: Event States @@ -689,7 +699,7 @@ extern FL_EXPORT Fl_Fontsize FL_NORMAL_SIZE; ///< normal font size /** \name Colors */ /*@{*/ -/** The Fl_Color enumeration type holds a FLTK color value. +/** The Fl_Color type holds an FLTK color value. Colors are either 8-bit indexes into a virtual colormap or 24-bit RGB color values. @@ -697,75 +707,94 @@ extern FL_EXPORT Fl_Fontsize FL_NORMAL_SIZE; ///< normal font size Color indices occupy the lower 8 bits of the value, while RGB colors occupy the upper 24 bits, for a byte organization of RGBI. - \todo enum Fl_Color needs some more comments for values, - see Fl/Enumerations.H +
+ Fl_Color => 0xrrggbbii
+                | | | |
+                | | | +--- index between 0 and 255
+                | | +----- blue color component (8 bit)
+                | +------- green component (8 bit)
+                +--------- red component (8 bit)
+ 
+ + A color can have either an index or an rgb value. Colors with rgb set + and an index >0 are reserved for special use. + */ -enum Fl_Color { // standard colors - // These are used as default colors in widgets and altered as necessary - FL_FOREGROUND_COLOR = 0, ///< the default foreground color (0) used for labels and text - FL_BACKGROUND2_COLOR = 7, ///< the default background color for text, list, and valuator widgets - FL_INACTIVE_COLOR = 8, ///< the inactive foreground color - FL_SELECTION_COLOR = 15, ///< the default selection/highlight color +typedef unsigned int Fl_Color; + +// Standard colors. These are used as default colors in widgets and altered as necessary +const Fl_Color FL_FOREGROUND_COLOR = 0; ///< the default foreground color (0) used for labels and text +const Fl_Color FL_BACKGROUND2_COLOR = 7; ///< the default background color for text, list, and valuator widgets +const Fl_Color FL_INACTIVE_COLOR = 8; ///< the inactive foreground color +const Fl_Color FL_SELECTION_COLOR = 15; ///< the default selection/highlight color // boxtypes generally limit themselves to these colors so // the whole ramp is not allocated: - FL_GRAY0 = 32, // 'A' - FL_DARK3 = 39, // 'H' - FL_DARK2 = 45, // 'N' - FL_DARK1 = 47, // 'P' - FL_BACKGROUND_COLOR = 49, // 'R' default background color - FL_LIGHT1 = 50, // 'S' - FL_LIGHT2 = 52, // 'U' - FL_LIGHT3 = 54, // 'W' +const Fl_Color FL_GRAY0 = 32; // 'A' +const Fl_Color FL_DARK3 = 39; // 'H' +const Fl_Color FL_DARK2 = 45; // 'N' +const Fl_Color FL_DARK1 = 47; // 'P' +const Fl_Color FL_BACKGROUND_COLOR = 49; // 'R' default background color +const Fl_Color FL_LIGHT1 = 50; // 'S' +const Fl_Color FL_LIGHT2 = 52; // 'U' +const Fl_Color FL_LIGHT3 = 54; // 'W' // FLTK provides a 5x8x5 color cube that is used with colormap visuals - FL_BLACK = 56, - FL_RED = 88, - FL_GREEN = 63, - FL_YELLOW = 95, - FL_BLUE = 216, - FL_MAGENTA = 248, - FL_CYAN = 223, - FL_DARK_RED = 72, +const Fl_Color FL_BLACK = 56; +const Fl_Color FL_RED = 88; +const Fl_Color FL_GREEN = 63; +const Fl_Color FL_YELLOW = 95; +const Fl_Color FL_BLUE = 216; +const Fl_Color FL_MAGENTA = 248; +const Fl_Color FL_CYAN = 223; +const Fl_Color FL_DARK_RED = 72; - FL_DARK_GREEN = 60, - FL_DARK_YELLOW = 76, - FL_DARK_BLUE = 136, - FL_DARK_MAGENTA = 152, - FL_DARK_CYAN = 140, +const Fl_Color FL_DARK_GREEN = 60; +const Fl_Color FL_DARK_YELLOW = 76; +const Fl_Color FL_DARK_BLUE = 136; +const Fl_Color FL_DARK_MAGENTA = 152; +const Fl_Color FL_DARK_CYAN = 140; - FL_WHITE = 255 -}; +const Fl_Color FL_WHITE = 255; -#define FL_FREE_COLOR (Fl_Color)16 -#define FL_NUM_FREE_COLOR 16 -#define FL_GRAY_RAMP (Fl_Color)32 -#define FL_NUM_GRAY 24 -#define FL_GRAY FL_BACKGROUND_COLOR -#define FL_COLOR_CUBE (Fl_Color)56 -#define FL_NUM_RED 5 -#define FL_NUM_GREEN 8 -#define FL_NUM_BLUE 5 + +#define FL_FREE_COLOR (Fl_Color)16 +#define FL_NUM_FREE_COLOR 16 +#define FL_GRAY_RAMP (Fl_Color)32 +#define FL_NUM_GRAY 24 +#define FL_GRAY FL_BACKGROUND_COLOR +#define FL_COLOR_CUBE (Fl_Color)56 +#define FL_NUM_RED 5 +#define FL_NUM_GREEN 8 +#define FL_NUM_BLUE 5 FL_EXPORT Fl_Color fl_inactive(Fl_Color c); + FL_EXPORT Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg); + FL_EXPORT Fl_Color fl_color_average(Fl_Color c1, Fl_Color c2, float weight); + inline Fl_Color fl_lighter(Fl_Color c) { return fl_color_average(c, FL_WHITE, .67f); } + inline Fl_Color fl_darker(Fl_Color c) { return fl_color_average(c, FL_BLACK, .67f); } + /** return 24-bit color value closest to \p r, \p g, \p b. */ inline Fl_Color fl_rgb_color(uchar r, uchar g, uchar b) { if (!r && !g && !b) return FL_BLACK; else return (Fl_Color)(((((r << 8) | g) << 8) | b) << 8); } + /** return 24-bit color value closest to \p grayscale */ inline Fl_Color fl_rgb_color(uchar g) { if (!g) return FL_BLACK; else return (Fl_Color)(((((g << 8) | g) << 8) | g) << 8); } + inline Fl_Color fl_gray_ramp(int i) {return (Fl_Color)(i+FL_GRAY_RAMP);} + inline Fl_Color fl_color_cube(int r, int g, int b) { return (Fl_Color)((b*FL_NUM_RED + r) * FL_NUM_GREEN + g + FL_COLOR_CUBE);} @@ -857,5 +886,5 @@ enum Fl_Damage { #endif // -// End of "$Id: Enumerations.H 6735 2009-04-01 22:11:57Z engelsman $". +// End of "$Id: Enumerations.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl.H b/plugins/zynaddsubfx/fltk/FL/Fl.H index d9f8e77e1..700f51936 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl.H @@ -1,5 +1,5 @@ // -// "$Id: Fl.H 6771 2009-04-19 12:47:36Z matt $" +// "$Id: Fl.H 6903 2009-09-27 11:09:03Z matt $" // // Main header file for the Fast Light Tool Kit (FLTK). // @@ -489,18 +489,25 @@ public: static int event_state() {return e_state;} /** See int event_state() */ static int event_state(int i) {return e_state&i;} - /** Gets which key on the keyboard was last pushed. - \retval 0 if the last event was not a key press or release. - \see int event_key(int) */ + /** + Gets which key on the keyboard was last pushed. + + The returned integer 'key code' is not necessarily a text + equivalent for the keystroke. For instance: if someone presses '5' on the + numeric keypad with numlock on, Fl::event_key() may return the 'key code' + for this key, and NOT the character '5'. To always get the '5', use Fl::event_text() instead. + + \returns an integer 'key code', or 0 if the last event was not a key press or release. + \see int event_key(int), event_text(), compose(int&). + */ static int event_key() {return e_keysym;} /** Returns the keycode of the last key event, regardless of the NumLock state. - + If NumLock is deactivated, FLTK translates events from the numeric keypad into the corresponding arrow key events. event_key() returns the translated key code, whereas - event_original_key() returns the keycode before - NumLock translation. + event_original_key() returns the keycode before NumLock translation. */ static int event_original_key(){return e_original_keysym;} /** @@ -548,7 +555,20 @@ public: slower than Fl::event_key(int). \see event_key(int) */ static int get_key(int key); // platform dependent - /** Returns the text associated with the current FL_PASTE or FL_DND_RELEASE event. */ + /** + Returns the text associated with the current event, including FL_PASTE or FL_DND_RELEASE events. + This can be used in response to FL_KEYUP, FL_KEYDOWN, FL_PASTE, FL_DND_RELEASE. + + When responding to FL_KEYUP/FL_KEYDOWN, use this function instead of Fl::event_key() + to get the text equivalent of keystrokes suitable for inserting into strings + and text widgets. + + The returned string is guaranteed to be be NULL terminated. + However, see Fl::event_length() for the actual length of the string, + in case the string itself contains NULLs that are part of the text data. + + \returns A NULL terminated text string equivalent of the last keystroke. + */ static const char* event_text() {return e_text;} /** Returns the length of the text in Fl::event_text(). There @@ -568,7 +588,7 @@ public: static void compose_reset() {compose_state = 0;} static int event_inside(int,int,int,int); static int event_inside(const Fl_Widget*); - static int test_shortcut(int); + static int test_shortcut(Fl_Shortcut); // event destinations: static int handle(int, Fl_Window*); @@ -660,7 +680,7 @@ public: 8-bit RGB color. The color is not allocated until fl_color(i) is used. */ static void set_color(Fl_Color, unsigned); // platform dependent - static unsigned get_color(Fl_Color); + static Fl_Color get_color(Fl_Color); static void get_color(Fl_Color, uchar&, uchar&, uchar&); /** Frees the specified color from the colormap, if applicable. @@ -1022,5 +1042,5 @@ public: #endif // !Fl_H // -// End of "$Id: Fl.H 6771 2009-04-19 12:47:36Z matt $". +// End of "$Id: Fl.H 6903 2009-09-27 11:09:03Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Browser.H index d8f920d4e..a2f8b00ce 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Browser.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Browser.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Browser.H 6726 2009-03-27 16:52:31Z greg.ercolano $" +// "$Id: Fl_Browser.H 6850 2009-09-07 02:25:51Z greg.ercolano $" // // Browser header file for the Fast Light Tool Kit (FLTK). // @@ -36,6 +36,7 @@ #define Fl_Browser_H #include "Fl_Browser_.H" +#include "Fl_Image.H" struct FL_BLINE; @@ -306,6 +307,11 @@ public: else Fl_Browser_::display(find_line(line)); } + // icon support + void icon(int line, Fl_Image* icon); + Fl_Image* icon(int line) const; + void remove_icon(int line); + /** For back compatibility only. */ void replace(int a, const char* b) { text(a, b); } void display(int line, int val=1); @@ -314,5 +320,5 @@ public: #endif // -// End of "$Id: Fl_Browser.H 6726 2009-03-27 16:52:31Z greg.ercolano $". +// End of "$Id: Fl_Browser.H 6850 2009-09-07 02:25:51Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H index 3d89a8ec9..4068ae48b 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Browser_.H 6737 2009-04-02 06:44:34Z greg.ercolano $" +// "$Id: Fl_Browser_.H 6902 2009-09-27 11:06:56Z matt $" // // Common browser header file for the Fast Light Tool Kit (FLTK). // @@ -74,7 +74,7 @@ class FL_EXPORT Fl_Browser_ : public Fl_Group { uchar has_scrollbar_; // which scrollbars are enabled Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; void* top_; // which item scrolling position is in void* selection_; // which is selected (except for FL_MULTI_BROWSER) void *redraw1,*redraw2; // minimal update pointers @@ -297,11 +297,11 @@ public: /** Gets the default text color for the lines in the browser. */ - Fl_Color textcolor() const { return (Fl_Color)textcolor_; } + Fl_Color textcolor() const { return textcolor_; } /** Sets the default text color for the lines in the browser to color \p col. */ - void textcolor(unsigned col) { textcolor_ = col; } + void textcolor(Fl_Color col) { textcolor_ = col; } /** Gets the current size of the scrollbars' troughs, in pixels. @@ -374,5 +374,5 @@ public: #endif // -// End of "$Id: Fl_Browser_.H 6737 2009-04-02 06:44:34Z greg.ercolano $". +// End of "$Id: Fl_Browser_.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H index d71c06672..73d6e4b0d 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Button.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Button.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Button.H 6878 2009-09-17 22:12:24Z matt $" // // Button header file for the Fast Light Tool Kit (FLTK). // @@ -45,7 +45,7 @@ #define FL_HIDDEN_BUTTON 3 ///< for Forms compatibility #ifndef FL_DOXYGEN -extern FL_EXPORT int fl_old_shortcut(const char*); +extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); #endif /** @@ -172,5 +172,5 @@ public: #endif // -// End of "$Id: Fl_Button.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Button.H 6878 2009-09-17 22:12:24Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H b/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H index 29b68ed44..e94c1a02a 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Chart.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Chart.H 6902 2009-09-27 11:06:56Z matt $" // // Forms chart header file for the Fast Light Tool Kit (FLTK). // @@ -87,7 +87,7 @@ class FL_EXPORT Fl_Chart : public Fl_Widget { uchar autosize_; Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; protected: void draw(); public: @@ -136,9 +136,9 @@ public: void textsize(Fl_Fontsize s) {textsize_ = s;} /** Gets the chart's text color */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** gets the chart's text color to \p n. */ - void textcolor(unsigned n) {textcolor_ = n;} + void textcolor(Fl_Color n) {textcolor_ = n;} /** Get whether the chart will automatically adjust the bounds of the chart. @@ -156,5 +156,5 @@ public: #endif // -// End of "$Id: Fl_Chart.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Chart.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H b/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H index afaa2f446..c4cf6c21b 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Clock.H 6754 2009-04-12 11:32:22Z AlbrechtS $" +// "$Id: Fl_Clock.H 6812 2009-07-01 07:27:25Z AlbrechtS $" // // Clock header file for the Fast Light Tool Kit (FLTK). // @@ -133,5 +133,5 @@ public: #endif // -// End of "$Id: Fl_Clock.H 6754 2009-04-12 11:32:22Z AlbrechtS $". +// End of "$Id: Fl_Clock.H 6812 2009-07-01 07:27:25Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H index e52c092c5..24930779a 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Counter.H 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: Fl_Counter.H 6902 2009-09-27 11:06:56Z matt $" // // Counter header file for the Fast Light Tool Kit (FLTK). // @@ -58,7 +58,7 @@ class FL_EXPORT Fl_Counter : public Fl_Valuator { Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; double lstep_; uchar mouseobj; static void repeat_callback(void *); @@ -111,14 +111,14 @@ public: void textsize(Fl_Fontsize s) {textsize_ = s;} /** Gets the font color */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** Sets the font color to \p s */ - void textcolor(unsigned s) {textcolor_ = s;} + void textcolor(Fl_Color s) {textcolor_ = s;} }; #endif // -// End of "$Id: Fl_Counter.H 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: Fl_Counter.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Group.H b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H index 2db9d7992..5ba61ad25 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Group.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Group.H 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: Fl_Group.H 6907 2009-09-28 14:34:52Z matt $" // // Group header file for the Fast Light Tool Kit (FLTK). // @@ -58,8 +58,6 @@ class FL_EXPORT Fl_Group : public Fl_Widget { Fl_Group& operator=(const Fl_Group&); protected: - enum { CLIP_CHILDREN = 2048 }; - void draw(); void draw_child(Fl_Widget& widget) const; void draw_children(); @@ -176,7 +174,7 @@ public: \see void Fl_Group::clip_children(int c) */ - int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } + unsigned int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } // back compatibility functions: @@ -224,5 +222,5 @@ public: #endif // -// End of "$Id: Fl_Group.H 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: Fl_Group.H 6907 2009-09-28 14:34:52Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H index 7217bb660..26dab7d1a 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input_.H 6777 2009-04-23 15:32:19Z matt $" +// "$Id: Fl_Input_.H 6902 2009-09-27 11:06:56Z matt $" // // Input base class header file for the Fast Light Tool Kit (FLTK). // @@ -120,7 +120,7 @@ class FL_EXPORT Fl_Input_ : public Fl_Widget { \p mark_, no text is selected */ int mark_; - /** \internal Offset to text origin within wdget bounds */ + /** \internal Offset to text origin within widget bounds */ int xscroll_, yscroll_; /** \internal Minimal update pointer. Display requirs redraw from here to the end @@ -143,10 +143,10 @@ class FL_EXPORT Fl_Input_ : public Fl_Widget { Fl_Fontsize textsize_; /** \internal color of the entire text */ - unsigned textcolor_; + Fl_Color textcolor_; /** \internal color of the text cursor */ - unsigned cursor_color_; + Fl_Color cursor_color_; /** \internal Horizontal cursor position in pixels while movin up or down. */ static double up_down_pos; @@ -206,6 +206,7 @@ protected: /** \internal Vertical offset of text to top edge of widget. */ int yscroll() const {return yscroll_;} + void yscroll(int y) { yscroll_ = y; damage(FL_DAMAGE_EXPOSE);} /* Return the number of lines displayed on a single page. */ int linesPerPage(); @@ -396,23 +397,23 @@ public: /** Gets the color of the text in the input field. \return the text color - \see textcolor(unsigned) */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + \see textcolor(Fl_Color) */ + Fl_Color textcolor() const {return textcolor_;} /** Sets the color of the text in the input field. The text color defaults to \c FL_FOREGROUND_COLOR. \param [in] n new text color \see textcolor() */ - void textcolor(unsigned n) {textcolor_ = n;} + void textcolor(Fl_Color n) {textcolor_ = n;} /** Gets the color of the cursor. \return the current cursor color */ - Fl_Color cursor_color() const {return (Fl_Color)cursor_color_;} + Fl_Color cursor_color() const {return cursor_color_;} /** Sets the color of the cursor. The default color for the cursor is \c FL_BLACK. \param [in] n the new cursor color */ - void cursor_color(unsigned n) {cursor_color_ = n;} + void cursor_color(Fl_Color n) {cursor_color_ = n;} /** Gets the input field type. \return the current input type */ @@ -450,5 +451,5 @@ public: #endif // -// End of "$Id: Fl_Input_.H 6777 2009-04-23 15:32:19Z matt $". +// End of "$Id: Fl_Input_.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H index 41bcd5c14..89ced65f6 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Menu_.H 6902 2009-09-27 11:06:56Z matt $" // // Menu base class header file for the Fast Light Tool Kit (FLTK). // @@ -56,7 +56,7 @@ protected: uchar down_box_; Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; public: Fl_Menu_(int,int,int,int,const char * =0); @@ -119,9 +119,9 @@ public: /** Sets the font size of menu item labels. */ void textsize(Fl_Fontsize c) {textsize_=c;} /** Get the current color of menu item labels. */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** Sets the current color of menu item labels. */ - void textcolor(unsigned c) {textcolor_=c;} + void textcolor(Fl_Color c) {textcolor_=c;} /** This box type is used to surround the currently-selected items in the @@ -142,5 +142,5 @@ public: #endif // -// End of "$Id: Fl_Menu_.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Menu_.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H index b4052b8c8..be81b8cc0 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_Item.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Menu_Item.H 6902 2009-09-27 11:06:56Z matt $" // // Menu item header file for the Fast Light Tool Kit (FLTK). // @@ -36,18 +36,18 @@ # endif enum { // values for flags: - FL_MENU_INACTIVE = 1, - FL_MENU_TOGGLE= 2, - FL_MENU_VALUE = 4, - FL_MENU_RADIO = 8, - FL_MENU_INVISIBLE = 0x10, - FL_SUBMENU_POINTER = 0x20, - FL_SUBMENU = 0x40, - FL_MENU_DIVIDER = 0x80, - FL_MENU_HORIZONTAL = 0x100 + FL_MENU_INACTIVE = 1, ///< Deactivate menu item (gray out) + FL_MENU_TOGGLE= 2, ///< Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, ///< The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, ///< Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, ///< Item will not show up (shortcut will work) + FL_SUBMENU_POINTER = 0x20, ///< Indicates user_data() is a pointer to another menu array + FL_SUBMENU = 0x40, ///< This item is a submenu to other items + FL_MENU_DIVIDER = 0x80, ///< Creates divider line below this item. Also ends a group of radio buttons. + FL_MENU_HORIZONTAL = 0x100 ///< ??? -- reserved }; -extern FL_EXPORT int fl_old_shortcut(const char*); +extern FL_EXPORT Fl_Shortcut fl_old_shortcut(const char*); class Fl_Menu_; @@ -68,15 +68,15 @@ class Fl_Menu_; }; enum { // values for flags: - FL_MENU_INACTIVE = 1, - FL_MENU_TOGGLE = 2, - FL_MENU_VALUE = 4, - FL_MENU_RADIO = 8, - FL_MENU_INVISIBLE = 0x10, - FL_SUBMENU_POINTER = 0x20, - FL_SUBMENU = 0x40, - FL_MENU_DIVIDER = 0x80, - FL_MENU_HORIZONTAL = 0x100 + FL_MENU_INACTIVE = 1, // Deactivate menu item (gray out) + FL_MENU_TOGGLE = 2, // Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE = 4, // The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO = 8, // Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE = 0x10, // Item will not show up (shortcut will work) + FL_SUBMENU_POINTER = 0x20, // Indicates user_data() is a pointer to another menu array + FL_SUBMENU = 0x40, // This item is a submenu to other items + FL_MENU_DIVIDER = 0x80, // Creates divider line below this item. Also ends a group of radio buttons. + FL_MENU_HORIZONTAL = 0x100 // ??? -- reserved }; \endcode Typically menu items are statically defined; for example: @@ -124,7 +124,7 @@ struct FL_EXPORT Fl_Menu_Item { uchar labeltype_; ///< how the menu item text looks like Fl_Font labelfont_; ///< which font for this menu item text Fl_Fontsize labelsize_; ///< size of menu item text - unsigned labelcolor_; ///< menu item text color + Fl_Color labelcolor_; ///< menu item text color // advance N items, skipping submenus: const Fl_Menu_Item *next(int=1) const; @@ -181,10 +181,10 @@ struct FL_EXPORT Fl_Menu_Item { color is not black fltk will not use overlay bitplanes to draw the menu - this is so that images put in the menu draw correctly. */ - Fl_Color labelcolor() const {return (Fl_Color)labelcolor_;} + Fl_Color labelcolor() const {return labelcolor_;} /** See Fl_Color Fl_Menu_Item::labelcolor() const */ - void labelcolor(unsigned a) {labelcolor_ = a;} + void labelcolor(Fl_Color a) {labelcolor_ = a;} /** Fonts are identified by small 8-bit indexes into a table. See the enumeration list for predefined fonts. The default value is a @@ -414,5 +414,5 @@ enum { // back-compatibility enum: #endif // -// End of "$Id: Fl_Menu_Item.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Menu_Item.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H index e2e77f1ea..217e224af 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_Window.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Menu_Window.H 6909 2009-09-28 14:41:43Z matt $" // // Menu window header file for the Fast Light Tool Kit (FLTK). // @@ -40,14 +40,13 @@ redraw. */ class FL_EXPORT Fl_Menu_Window : public Fl_Single_Window { - enum {NO_OVERLAY = 128}; public: void show(); void erase(); void flush(); void hide(); /** Tells if hardware overlay mode is set */ - int overlay() {return !(flags()&NO_OVERLAY);} + unsigned int overlay() {return !(flags()&NO_OVERLAY);} /** Tells FLTK to use hardware overlay planes if they are available. */ void set_overlay() {clear_flag(NO_OVERLAY);} /** Tells FLTK to use normal drawing planes instead of overlay planes. @@ -65,5 +64,5 @@ public: #endif // -// End of "$Id: Fl_Menu_Window.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Menu_Window.H 6909 2009-09-28 14:41:43Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H index feec46498..5f46624be 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Multiline_Input.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Multiline_Input.H 6889 2009-09-19 22:09:00Z greg.ercolano $" // // Multiline input header file for the Fast Light Tool Kit (FLTK). // @@ -38,11 +38,15 @@ This input field displays '\n' characters as new lines rather than ^J, and accepts the Return, Tab, and up and down arrow keys. This is for editing multiline text. -

This is far from the nirvana of text editors, and is probably only - good for small bits of text, 10 lines at most. I think FLTK can be - used to write a powerful text editor, but it is not going to be a - built-in feature. Powerful text editors in a toolkit are a big source - of bloat. +

+ This is far from the nirvana of text editors, and is probably only + good for small bits of text, 10 lines at most. Note that this widget + does not support scrollbars or per-character color control. +

+ If you are presenting large amounts of text and need scrollbars + or full color control of characters, you probably want Fl_Text_Editor + instead. +

*/ class Fl_Multiline_Input : public Fl_Input { public: @@ -58,5 +62,5 @@ public: #endif // -// End of "$Id: Fl_Multiline_Input.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Multiline_Input.H 6889 2009-09-19 22:09:00Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H index 0dbcb06dc..f0edf63d0 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Multiline_Output.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Multiline_Output.H 6889 2009-09-19 22:09:00Z greg.ercolano $" // // Multi line output header file for the Fast Light Tool Kit (FLTK). // @@ -37,6 +37,14 @@ This widget is a subclass of Fl_Output that displays multiple lines of text. It also displays tab characters as whitespace to the next column. +

+ Note that this widget does not support scrollbars, or per-character + color control. +

+ If you are presenting large amounts of read-only text + and need scrollbars, or full color control of characters, + then use Fl_Text_Display. If you want to display HTML text, + use Fl_Help_View. */ class Fl_Multiline_Output : public Fl_Output { public: @@ -52,5 +60,5 @@ public: #endif // -// End of "$Id: Fl_Multiline_Output.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Multiline_Output.H 6889 2009-09-19 22:09:00Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Output.H index 0d02d82d5..58b33378f 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Output.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Output.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Output.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Output.H 6898 2009-09-23 20:43:27Z matt $" // // Output header file for the Fast Light Tool Kit (FLTK). // @@ -42,7 +42,8 @@ \image latex text.eps "Fl_Output" width=8cm

There is a single subclass, Fl_Multiline_Output, which allows you to display multiple lines of - text.

+ text. Fl_Multiline_Output does not provide scroll bars. If a more + complete text editing widget is needed, use Fl_Text_Display instead.

The text may contain any characters except \\0, and will correctly display anything, using ^X notation for unprintable control characters and \\nnn notation for unprintable characters with the high bit set. It @@ -63,5 +64,5 @@ public: #endif // -// End of "$Id: Fl_Output.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Output.H 6898 2009-09-23 20:43:27Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H index e36be6d23..a8bbdb480 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scroll.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Scroll.H 6828 2009-07-12 00:15:06Z greg.ercolano $" // // Scroll header file for the Fast Light Tool Kit (FLTK). // @@ -193,5 +193,5 @@ public: #endif // -// End of "$Id: Fl_Scroll.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Scroll.H 6828 2009-07-12 00:15:06Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H index 7efca467c..a4d85139c 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Buffer.H 6618 2009-01-01 21:54:10Z matt $" +// "$Id: Fl_Text_Buffer.H 6822 2009-07-04 00:24:26Z fabien $" // // Header file for Fl_Text_Buffer class. // @@ -322,5 +322,5 @@ class FL_EXPORT Fl_Text_Buffer { #endif // -// End of "$Id: Fl_Text_Buffer.H 6618 2009-01-01 21:54:10Z matt $". +// End of "$Id: Fl_Text_Buffer.H 6822 2009-07-04 00:24:26Z fabien $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H index 2986b1cd7..495737718 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Display.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Text_Display.H 6902 2009-09-27 11:06:56Z matt $" // // Header file for Fl_Text_Display class. // @@ -165,9 +165,9 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { /** Sets the default size of text in the widget. */ void textsize(Fl_Fontsize s) {textsize_ = s;} /** Gets the default color of text in the widget. */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** Sets the default color of text in the widget. */ - void textcolor(unsigned n) {textcolor_ = n;} + void textcolor(Fl_Color n) {textcolor_ = n;} int wrapped_column(int row, int column) const; int wrapped_row(int row) const; @@ -327,7 +327,7 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; // The following are not presently used from the original NEdit code, // but are being put here so that future versions of Fl_Text_Display @@ -340,5 +340,5 @@ class FL_EXPORT Fl_Text_Display: public Fl_Group { #endif // -// End of "$Id: Fl_Text_Display.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Text_Display.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H index 85f3611db..be3b718a3 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Editor.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Text_Editor.H 6893 2009-09-20 19:24:24Z greg.ercolano $" // // Header file for Fl_Text_Editor class. // @@ -103,6 +103,8 @@ class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display { static int kf_shift_move(int c, Fl_Text_Editor* e); static int kf_ctrl_move(int c, Fl_Text_Editor* e); static int kf_c_s_move(int c, Fl_Text_Editor* e); + static int kf_meta_move(int c, Fl_Text_Editor* e); + static int kf_m_s_move(int c, Fl_Text_Editor* e); static int kf_home(int, Fl_Text_Editor* e); static int kf_end(int c, Fl_Text_Editor* e); static int kf_left(int c, Fl_Text_Editor* e); @@ -134,6 +136,6 @@ class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display { #endif // -// End of "$Id: Fl_Text_Editor.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Text_Editor.H 6893 2009-09-20 19:24:24Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H index 033e83f2b..c5ec20641 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Tooltip.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Tooltip.H 6902 2009-09-27 11:06:56Z matt $" // // Tooltip header file for the Fast Light Tool Kit (FLTK). // @@ -76,13 +76,13 @@ public: /** Sets the size of the tooltip text. */ static void size(Fl_Fontsize s) { size_ = s; } /** Gets the background color for tooltips. The default background color is a pale yellow. */ - static Fl_Color color() { return (Fl_Color)color_; } + static Fl_Color color() { return color_; } /** Sets the background color for tooltips. The default background color is a pale yellow. */ - static void color(unsigned c) { color_ = c; } + static void color(Fl_Color c) { color_ = c; } /** Gets the color of the text in the tooltip. The default is black. */ - static Fl_Color textcolor() { return (Fl_Color)textcolor_; } + static Fl_Color textcolor() { return textcolor_; } /** Sets the color of the text in the tooltip. The default is black. */ - static void textcolor(unsigned c) { textcolor_ = c; } + static void textcolor(Fl_Color c) { textcolor_ = c; } // These should not be public, but Fl_Widget::tooltip() needs them... // fabien: made it private with only a friend function access @@ -95,8 +95,8 @@ private: static float delay_; //!< delay before a tooltip is shown static float hoverdelay_; //!< delay between tooltips static int enabled_; - static unsigned color_; - static unsigned textcolor_; + static Fl_Color color_; + static Fl_Color textcolor_; static Fl_Font font_; static Fl_Fontsize size_; static Fl_Widget* widget_; //!< Keeps track of the current target widget @@ -105,5 +105,5 @@ private: #endif // -// End of "$Id: Fl_Tooltip.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Tooltip.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H index 52d9f31d1..4ed1b1011 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Value_Input.H 6664 2009-02-18 09:27:54Z AlbrechtS $" +// "$Id: Fl_Value_Input.H 6902 2009-09-27 11:06:56Z matt $" // // Value input header file for the Fast Light Tool Kit (FLTK). // @@ -120,16 +120,16 @@ public: /** Gets the color of the text in the value box. */ Fl_Color textcolor() const {return input.textcolor();} /** Sets the color of the text in the value box.*/ - void textcolor(unsigned n) {input.textcolor(n);} + void textcolor(Fl_Color n) {input.textcolor(n);} /** Gets the color of the text cursor. The text cursor is black by default. */ Fl_Color cursor_color() const {return input.cursor_color();} /** Sets the color of the text cursor. The text cursor is black by default. */ - void cursor_color(unsigned n) {input.cursor_color(n);} + void cursor_color(Fl_Color n) {input.cursor_color(n);} }; #endif // -// End of "$Id: Fl_Value_Input.H 6664 2009-02-18 09:27:54Z AlbrechtS $". +// End of "$Id: Fl_Value_Input.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H index 1654219c6..5dda0ca89 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Value_Output.H 6664 2009-02-18 09:27:54Z AlbrechtS $" +// "$Id: Fl_Value_Output.H 6902 2009-09-27 11:06:56Z matt $" // // Value output header file for the Fast Light Tool Kit (FLTK). // @@ -51,7 +51,7 @@ class FL_EXPORT Fl_Value_Output : public Fl_Valuator { Fl_Font textfont_; Fl_Fontsize textsize_; uchar soft_; - unsigned textcolor_; + Fl_Color textcolor_; protected: void draw(); @@ -83,13 +83,13 @@ public: Fl_Fontsize textsize() const {return textsize_;} void textsize(Fl_Fontsize s) {textsize_ = s;} /** Sets the color of the text in the value box. */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** Gets the color of the text in the value box. */ - void textcolor(unsigned s) {textcolor_ = s;} + void textcolor(Fl_Color s) {textcolor_ = s;} }; #endif // -// End of "$Id: Fl_Value_Output.H 6664 2009-02-18 09:27:54Z AlbrechtS $". +// End of "$Id: Fl_Value_Output.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H index c2b5afe50..ec886428a 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Value_Slider.H 6664 2009-02-18 09:27:54Z AlbrechtS $" +// "$Id: Fl_Value_Slider.H 6902 2009-09-27 11:06:56Z matt $" // // Value slider header file for the Fast Light Tool Kit (FLTK). // @@ -42,7 +42,7 @@ class FL_EXPORT Fl_Value_Slider : public Fl_Slider { Fl_Font textfont_; Fl_Fontsize textsize_; - unsigned textcolor_; + Fl_Color textcolor_; protected: void draw(); public: @@ -57,13 +57,13 @@ public: /** Sets the size of the text in the value box. */ void textsize(Fl_Fontsize s) {textsize_ = s;} /** Gets the color of the text in the value box. */ - Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + Fl_Color textcolor() const {return textcolor_;} /** Sets the color of the text in the value box. */ - void textcolor(unsigned s) {textcolor_ = s;} + void textcolor(Fl_Color s) {textcolor_ = s;} }; #endif // -// End of "$Id: Fl_Value_Slider.H 6664 2009-02-18 09:27:54Z AlbrechtS $". +// End of "$Id: Fl_Value_Slider.H 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H b/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H index 426156137..f36ca38c7 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Widget.H 6753 2009-04-12 09:40:59Z AlbrechtS $" +// "$Id: Fl_Widget.H 6912 2009-10-02 19:08:55Z matt $" // // Widget header file for the Fast Light Tool Kit (FLTK). // @@ -69,7 +69,7 @@ struct FL_EXPORT Fl_Label { /** size of label font */ Fl_Fontsize size; /** text color */ - unsigned color; + Fl_Color color; /** Draws the label aligned to the given box */ void draw(int,int,int,int, Fl_Align) const ; void measure(int &w, int &h) const ; @@ -96,9 +96,9 @@ class FL_EXPORT Fl_Widget { void* user_data_; int x_,y_,w_,h_; Fl_Label label_; - int flags_; - unsigned color_; - unsigned color2_; + unsigned int flags_; + Fl_Color color_; + Fl_Color color2_; uchar type_; uchar damage_; uchar box_; @@ -135,23 +135,37 @@ protected: /** Internal use only. Use position(int,int), size(int,int) or resize(int,int,int,int) instead. */ void h(int v) {h_ = v;} /** Gets the widget flags mask */ - int flags() const {return flags_;} + unsigned int flags() const {return flags_;} /** Sets a flag in the flags mask */ - void set_flag(int c) {flags_ |= c;} + void set_flag(unsigned int c) {flags_ |= c;} /** Clears a flag in the flags mask */ - void clear_flag(int c) {flags_ &= ~c;} + void clear_flag(unsigned int c) {flags_ &= ~c;} /** flags possible values enumeration. See activate(), output(), visible(), changed(), set_visible_focus() */ enum { - INACTIVE=1, ///< the widget can't receive focus, and is disabled but potentially visible - INVISIBLE=2, ///< the widget is not drawn but can receive events - OUTPUT=4, ///< for output only - SHORTCUT_LABEL=64, ///< the label contains a shortcut we need to draw - CHANGED=128, ///< the widget value changed - VISIBLE_FOCUS=512, ///< accepts keyboard focus navigation if the widget can have the focus - COPIED_LABEL=1024 ///< the widget label is internally copied, its destruction is handled by the widget - }; + INACTIVE = 1<<0, ///< the widget can't receive focus, and is disabled but potentially visible + INVISIBLE = 1<<1, ///< the widget is not drawn but can receive events + OUTPUT = 1<<2, ///< for output only + NOBORDER = 1<<3, ///< don't draw a decoration (Fl_Window) + FORCE_POSITION = 1<<4, ///< don't let the window manager position the window (Fl_Window) + NON_MODAL = 1<<5, ///< thisis a hovering toolbar window (Fl_Window) + SHORTCUT_LABEL = 1<<6, ///< the label contains a shortcut we need to draw + CHANGED = 1<<7, ///< the widget value changed + OVERRIDE = 1<<8, ///< position window on top (Fl_Window) + VISIBLE_FOCUS = 1<<9, ///< accepts keyboard focus navigation if the widget can have the focus + COPIED_LABEL = 1<<10, ///< the widget label is internally copied, its destruction is handled by the widget + CLIP_CHILDREN = 1<<11, ///< all drawing within this widget will be clipped (Fl_Group) + MENU_WINDOW = 1<<12, ///< a temporary popup window, dismissed by clicking outside (Fl_Window) + TOOLTIP_WINDOW = 1<<13, ///< a temporary popup, transparent to events, and dismissed easily (Fl_Window) + MODAL = 1<<14, ///< a window blocking input to all other winows (Fl_Window) + NO_OVERLAY = 1<<15, ///< window not using a hardware overlay plane (Fl_Menu_Window) + GROUP_RELATIVE = 1<<16, ///< position this idget relative to the parent group, not to the window + // (space for more flags) + USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions + USERFLAG2 = 1<<30, ///< reserved for 3rd party extensions + USERFLAG1 = 1<<31 ///< reserved for 3rd party extensions + }; void draw_box() const; void draw_box(Fl_Boxtype t, Fl_Color c) const; void draw_box(Fl_Boxtype t, int x,int y,int w,int h, Fl_Color c) const; @@ -343,9 +357,9 @@ public: /** Gets the background color of the widget. \return current background color - \see color(unsigned), color(unsigned, unsigned) + \see color(Fl_Color), color(Fl_Color, Fl_Color) */ - Fl_Color color() const {return (Fl_Color)color_;} + Fl_Color color() const {return color_;} /** Sets the background color of the widget. The color is passed to the box routine. The color is either an index into @@ -355,25 +369,25 @@ public: The default for most widgets is FL_BACKGROUND_COLOR. Use Fl::set_color() to redefine colors in the color map. \param[in] bg background color - \see color(), color(unsigned, unsigned), selection_color(unsigned) + \see color(), color(Fl_Color, Fl_Color), selection_color(Fl_Color) */ - void color(unsigned bg) {color_ = bg;} + void color(Fl_Color bg) {color_ = bg;} /** Gets the selection color. \return the current selection color - \see selection_color(unsigned), color(unsigned, unsigned) + \see selection_color(Fl_Color), color(Fl_Color, Fl_Color) */ - Fl_Color selection_color() const {return (Fl_Color)color2_;} + Fl_Color selection_color() const {return color2_;} /** Sets the selection color. The selection color is defined for Forms compatibility and is usually used to color the widget when it is selected, although some widgets use this color for other purposes. You can set both colors at once - with color(unsigned bg, unsigned sel). + with color(Fl_Color bg, Fl_Color sel). \param[in] a the new selection color - \see selection_color(), color(unsigned, unsigned) + \see selection_color(), color(Fl_Color, Fl_Color) */ - void selection_color(unsigned a) {color2_ = a;} + void selection_color(Fl_Color a) {color2_ = a;} /** Sets the background and selection color of the widget. @@ -382,7 +396,7 @@ public: \param[in] sel selection color \see color(unsigned), selection_color(unsigned) */ - void color(unsigned bg, unsigned sel) {color_=bg; color2_=sel;} + void color(Fl_Color bg, Fl_Color sel) {color_=bg; color2_=sel;} /** Gets the current label text. \return a pointer to the current label text @@ -439,13 +453,13 @@ public: The default color is FL_FOREGROUND_COLOR. \return the current label color */ - Fl_Color labelcolor() const {return (Fl_Color)label_.color;} + Fl_Color labelcolor() const {return label_.color;} /** Sets the label color. The default color is FL_FOREGROUND_COLOR. \param[in] c the new label color */ - void labelcolor(unsigned c) {label_.color=c;} + void labelcolor(Fl_Color c) {label_.color=c;} /** Gets the font to use. Fonts are identified by indexes into a table. The default value @@ -633,7 +647,7 @@ public: \retval 0 if the widget is not drawn and hence invisible. \see show(), hide(), visible_r() */ - int visible() const {return !(flags_&INVISIBLE);} + unsigned int visible() const {return !(flags_&INVISIBLE);} /** Returns whether a widget and all its parents are visible. \retval 0 if the widget or any of its parents are invisible. @@ -678,7 +692,7 @@ public: \retval 0 if the widget is inactive \see active_r(), activate(), deactivate() */ - int active() const {return !(flags_&INACTIVE);} + unsigned int active() const {return !(flags_&INACTIVE);} /** Returns whether the widget and all of its parents are active. \retval 0 if this or any of the parent widgets are inactive @@ -717,7 +731,7 @@ public: \retval 0 if the widget is used for input and output \see set_output(), clear_output() */ - int output() const {return (flags_&OUTPUT);} + unsigned int output() const {return (flags_&OUTPUT);} /** Sets a widget to output only. \see output(), clear_output() @@ -734,7 +748,7 @@ public: && visible()) but is faster. \retval 0 if the widget takes no events */ - int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));} + unsigned int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));} /** Checks if the widget value changed since the last callback. @@ -751,7 +765,7 @@ public: \retval 0 if the value did not change \see set_changed(), clear_changed() */ - int changed() const {return flags_&CHANGED;} + unsigned int changed() const {return flags_&CHANGED;} /** Marks the value of the widget as changed. \see changed(), clear_changed() @@ -796,7 +810,7 @@ public: \retval 0 if this widget has no visible focus. \see visible_focus(int), set_visible_focus(), clear_visible_focus() */ - int visible_focus() { return flags_ & VISIBLE_FOCUS; } + unsigned int visible_focus() { return flags_ & VISIBLE_FOCUS; } /** Sets the default callback for all widgets. Sets the default callback, which puts a pointer to the widget on the queue @@ -828,7 +842,7 @@ public: /** Internal use only. */ int test_shortcut(); /** Internal use only. */ - static char label_shortcut(const char *t); + static Fl_Shortcut label_shortcut(const char *t); /** Internal use only. */ static int test_shortcut(const char*); @@ -866,9 +880,16 @@ public: */ uchar damage() const {return damage_;} - /** Clears the damage flags. + /** Clears or sets the damage flags. Damage flags are cleared when parts of the widget drawing is repaired. - \param[in] c bitmask of flags to clear + + The optional argument \p c specifies the bits that are set + after the call (default: 0) and \b not the bits that are cleared! + + \note Therefore it is possible to set damage bits with this method, but + this should be avoided. Use damage(uchar) instead. + + \param[in] c new bitmask of damage flags (default: 0) \see damage(uchar), damage() */ void clear_damage(uchar c = 0) {damage_ = c;} @@ -923,5 +944,5 @@ public: #endif // -// End of "$Id: Fl_Widget.H 6753 2009-04-12 09:40:59Z AlbrechtS $". +// End of "$Id: Fl_Widget.H 6912 2009-10-02 19:08:55Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Window.H index a55521db5..952a52793 100644 --- a/plugins/zynaddsubfx/fltk/FL/Fl_Window.H +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Window.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window.H 6614 2009-01-01 16:11:32Z matt $" +// "$Id: Fl_Window.H 6907 2009-09-28 14:34:52Z matt $" // // Window header file for the Fast Light Tool Kit (FLTK). // @@ -69,16 +69,6 @@ class FL_EXPORT Fl_Window : public Fl_Group { Fl_Cursor cursor_default; Fl_Color cursor_fg, cursor_bg; void size_range_(); - // values for flags(): - enum { - FL_MODAL = 64, - FL_NOBORDER = 8, - FL_FORCE_POSITION = 16, - FL_NON_MODAL = 32, - FL_OVERRIDE = 256, - FL_MENU_WINDOW = 4096, - FL_TOOLTIP_WINDOW = 8192 - }; void _Fl_Window(); // constructor innards // unimplemented copy ctor and assignment operator @@ -167,13 +157,13 @@ public: Fast inline function to turn the border off. It only works before show() is called. */ - void clear_border() {set_flag(FL_NOBORDER);} + void clear_border() {set_flag(NOBORDER);} /** See int Fl_Window::border(int) */ - int border() const {return !(flags() & FL_NOBORDER);} - /** Activate the flags FL_NOBORDER|FL_OVERRIDE */ - void set_override() {set_flag(FL_NOBORDER|FL_OVERRIDE);} + unsigned int border() const {return !(flags() & NOBORDER);} + /** Activate the flags NOBORDER|FL_OVERRIDE */ + void set_override() {set_flag(NOBORDER|OVERRIDE);} /** Returns non zero if FL_OVERRIDE flag is set, 0 otherwise. */ - int override() const { return flags()&FL_OVERRIDE; } + unsigned int override() const { return flags()&OVERRIDE; } /** A "modal" window, when shown(), will prevent any events from being delivered to other windows in the same program, and will also @@ -183,18 +173,18 @@ public: which window (if any) is modal by calling Fl::modal(). */ - void set_modal() {set_flag(FL_MODAL);} + void set_modal() {set_flag(MODAL);} /** Returns true if this window is modal. */ - int modal() const {return flags() & FL_MODAL;} + unsigned int modal() const {return flags() & MODAL;} /** A "non-modal" window (terminology borrowed from Microsoft Windows) acts like a modal() one in that it remains on top, but it has no effect on event delivery. There are three states for a window: modal, non-modal, and normal. */ - void set_non_modal() {set_flag(FL_NON_MODAL);} + void set_non_modal() {set_flag(NON_MODAL);} /** Returns true if this window is modal or non-modal. */ - int non_modal() const {return flags() & (FL_NON_MODAL|FL_MODAL);} + unsigned int non_modal() const {return flags() & (NON_MODAL|MODAL);} /** Marks the window as a menu window. @@ -209,10 +199,10 @@ public: This must be called before the window is shown and cannot be changed later. */ - void set_menu_window() {set_flag(FL_MENU_WINDOW);} + void set_menu_window() {set_flag(MENU_WINDOW);} /** Returns true if this window is a menu window. */ - int menu_window() const {return flags() & FL_MENU_WINDOW;} + unsigned int menu_window() const {return flags() & MENU_WINDOW;} /** Marks the window as a tooltip window. @@ -230,10 +220,10 @@ public: \note Since Fl_Tooltip_Window is derived from Fl_Menu_Window, this also \b clears the menu_window() state. */ - void set_tooltip_window() { set_flag(FL_TOOLTIP_WINDOW); - clear_flag(FL_MENU_WINDOW); } + void set_tooltip_window() { set_flag(TOOLTIP_WINDOW); + clear_flag(MENU_WINDOW); } /** Returns true if this window is a tooltip window. */ - int tooltip_window() const {return flags() & FL_TOOLTIP_WINDOW;} + unsigned int tooltip_window() const {return flags() & TOOLTIP_WINDOW;} /** Position the window so that the mouse is pointing at the @@ -252,7 +242,7 @@ public: so that the next time show() is called the window manager is free to position the window. */ - void free_position() {clear_flag(FL_FORCE_POSITION);} + void free_position() {clear_flag(FORCE_POSITION);} /** Set the allowable range the user can resize this window to. This only works for top-level windows. @@ -410,5 +400,5 @@ public: #endif // -// End of "$Id: Fl_Window.H 6614 2009-01-01 16:11:32Z matt $". +// End of "$Id: Fl_Window.H 6907 2009-09-28 14:34:52Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/fl_draw.H b/plugins/zynaddsubfx/fltk/FL/fl_draw.H index fab90b477..69ecaf49c 100644 --- a/plugins/zynaddsubfx/fltk/FL/fl_draw.H +++ b/plugins/zynaddsubfx/fltk/FL/fl_draw.H @@ -1,5 +1,5 @@ // -// "$Id: fl_draw.H 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: fl_draw.H 6878 2009-09-17 22:12:24Z matt $" // // Portable drawing function header file for the Fast Light Tool Kit (FLTK). // @@ -203,14 +203,7 @@ inline Fl_Fontsize fl_size() {return fl_size_;} You can also use the value of \p size passed to fl_font() */ FL_EXPORT int fl_height(); // using "size" should work ok -/** - Dummy passthru function called only in Fl_Text_Display that simply returns - the font height as given by the \p size parameter in the same call! - - \todo Is fl_height(int, int size) required for Fl_Text_Dispay? - Why not use \p size parameter directly? -*/ -inline int fl_height(int, int size) {return size;} +FL_EXPORT int fl_height(int font, int size); /** Returns the recommended distance above the bottom of a fl_height() tall box to draw the text at so it looks centered vertically in that box. @@ -448,8 +441,8 @@ FL_EXPORT int fl_measure_pixmap(const char* const* cdata, int &w, int &h); // other: FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy, void (*draw_area)(void*, int,int,int,int), void* data); -FL_EXPORT const char* fl_shortcut_label(int shortcut); -FL_EXPORT const char* fl_shortcut_label(int shortcuti, const char **eom); +FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut); +FL_EXPORT const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom); FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h); FL_EXPORT void fl_overlay_clear(); FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE); @@ -475,5 +468,5 @@ FL_EXPORT int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scal #endif // -// End of "$Id: fl_draw.H 6779 2009-04-24 09:28:30Z yuri $". +// End of "$Id: fl_draw.H 6878 2009-09-17 22:12:24Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/FL/fl_types.h b/plugins/zynaddsubfx/fltk/FL/fl_types.h index e676a621e..d87cd7387 100644 --- a/plugins/zynaddsubfx/fltk/FL/fl_types.h +++ b/plugins/zynaddsubfx/fltk/FL/fl_types.h @@ -52,6 +52,9 @@ typedef char *Fl_String; typedef const char *Fl_CString; /** 24-bit Unicode character + 8-bit indicator for keyboard flags */ +typedef unsigned int Fl_Shortcut; + +/** 24-bit Unicode character - upper 8-bits are unused */ typedef unsigned int Fl_Char; /*@}*/ /* group: Miscellaneous */ diff --git a/plugins/zynaddsubfx/fltk/README.123 b/plugins/zynaddsubfx/fltk/README.123 new file mode 100644 index 000000000..1ab0c4f47 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/README.123 @@ -0,0 +1,686 @@ + + R E A D M E . 1 2 3 + ===================== + +This file listst the differences between FLTK 1 and FLTK 2 with annotations +for a possible implementation of FLTK 3. The all new and improved FLTK 3 +needs to be compatible with 1 and 2. It must have a moder API, plenty of +widgets, lots of options, customization at run-time, but still be easily +portable, fast, and of course light. + +FLTK 1 has become a nice starting point for the first steps in GUI +programming. It runs on al major platform (and on many minor ones +as well), is small, compact, and easy to use. FLTK 2 was the +attempt to continue the success of FLTK 1 with a much cleaber API +and many important details improved. Unfortunately many users never +made the jump to FLTK 2 and so it not only ended in a crawling slow +branch, it also became instable and at last unmaintainable. + +FLTK 3 sets out to surprise FLTK 1 users and satisfy FLTK 2 junkies. +It will basically be the improved FLTK 2 API combined with the quite +stable innards of FLTK 1. As an extra bonus, FLTK 3 will be compatible +to 1 and 2. Just prepend your code with the "coding_style" instruction +and FLTK 3 will do the rest. It is even possible to intermix F1 and +F2 coding styles at any place. + +Nice challange, eh? So let's get going: + + + The Big Differences +--------------------- + +FLTK 2 is based on FLTK 1 in many ways, and while the FLTK 1 API was based +on the Forms Library, FLTK 2 is Bill's take on how FLTK 1 should have been. +This chapter outlines the biggest differences between version. + +(1) Coordinate System: FLTK 1 child coordinates are always relative to the +window, not as most would expect to the parent. FLTK 2 does the logical +thing and uses group-relative origins. This is somewhat difficult to port +if we want to stay downward compatible. Fl_Widget will need an additional +flag indicating absolute or relative coordinates. + +(2) Pulldown Menus: The developers of the Forms Library did not implement +the idea of hierarchies all the way through. Pulldown menus, which are +hierarchical by nature, were instead implemented as a list with lots of +tricks and cludges to make them usable. FLTK 2 went half way by using the +existing Windget/Group relation to create menus, however, menu items are +still specialized widgets. For FLTK 3, I would like to allow any widget +inside a pulldown menu. + +(3) Browsers and Tree Views: Browsers in FLTK1 are implemented even worse +than Pulldown Menus. FLTK 2 solved the issues in a similar way, and here +again, I prefer the FLTK 2 way very mch, but also would like to extend +functionality to allow arbitrary widgets as list items. A Tree-like +widget comes free with the FLTK 2 concept. FLTK 1 has no such thing and +even Fluid had to hack the library badly to generate a tree view. + +(4) Namespaces: this is a minr issue that I include for completeness. FLTK 2 +introduces the ftk namespace, renaming all widgets. FLTK 3 will use the +FLTK 2 naming scheme and map FLTK 1 class names using typedefs. This is, as +most things in programming are, a compromise. The "coding_style" function +must be used to switch between FLTK 1 and FLTK 2 code. No worries though, +it's easy and straight forward. + +(5) Layout: FLTK 1 uses a top-down approach for widget layout in which the +parent widget decides about the childs size "resize(x, y, w, h)". In FLTK 2 +any widget can call "layout()" which will query children for their preffered +size and propagate the information up. This is a great concept that FLTK 3 +should adapt, plus it is compatible. + +(6) Ractangle: FLTK 2's base class is fltk::Rectangle. This is nice and +easy to implement. The API is pretty much the same in both versions. + +(7) Styles: FLTK 2 uses a minimal number of styles to define the basic +(and often repeated) parameters of every widget. API's are similar though, +so this is luckily another pretty straight-forward upgrade. + + + Comparison Chart by Class +--------------------------- + +This chart contains a list of all classes in FLTK 1 and 2, how they +correspond, and how they could be implemented in FLTK 3. + +1: class Fl +2: namespace fltk +*: this is a pretty straight-forward mapping of functions. The actual work + lies in finding and listing all global functions and adapting those. + +1: class Fl_Adjuster +2: class Adjuster +*: should map easily + +1: +2: class AlignGroup +*: undocumented in FLTK 2. Minimal code. Can be transfered easily. + +1: +2: class AnsiWidget +*: There is no equvalet in FLTK 1, but the widget may be easily ported. + +1: +2: class AssociationFunctor +*: Associations are a new and rarly used concept in FLTK 2. We need to + decide if these should be moved into FLTK 3 + +1: +2: class AssociationType +*: Associations are a new and rarly used concept in FLTK 2. We need to + decide if these should be moved into FLTK 3 + +1: +2: class BarGroup +*: undocumented in FLTK 2. Minimal code. Can be transfered easily. + +1: class Fl_BMP_Image +2: class bmpImage +*: should map easily + +1: class Fl_Bitmap +2: + +1: class Fl_Box +2: class Widget +*: This actually maps pretty much exactly to fltk::Widget. FLTK 2 provides + a bunch of other box-like classes which have some predefined properties, + however this is the best match for FLTK 1. fltk::InvisibleBox can be used + as well. + +1: class Fl_Browser +2: class Browser + +1: class Fl_Browser_ +2: + +1: class Fl_Button +2: class Button +*: should map easily + +1: class Fl_Cairo_State +2: + +1: class Fl_Cairo_Window +2: + +1: class Fl_Chart +2: + +1: class Fl_Check_Browser +2: + +1: class Fl_Check_Button +2: class CheckButton +*: should map easily + +1: class Fl_Choice +2: class Choice +*: should map easily + +1: class Fl_Clock +2: class Clock +*: should map easily + +1: class Fl_Clock_Output +2: class ClockOutput +*: should map easily + +1: class Fl_Color_Chooser +2: class ColorChooser +*: should map easily + +1: +2: class ComboBrowser + +1: +2: class ComboWindow + +1: +2: class CycleButton + +1: class Fl_Counter +2: + +1: class Fl_Dial +2: class Dial +*: should map easily + +1: +2: class Divider + +1: class Fl_Double_Window +2: class DoubleBufferWindow +*: should map easily + +1: class Fl_End +2: + +1: +2: class EngravedLabel + +1: class Fl_File_Browser +2: class FileBrowser +*: should map easily + +1: class Fl_File_Chooser +2: class FileChooser +*: should map easily + +1: class Fl_File_Icon +2: class FileIcon +*: should map easily + +1: class Fl_File_Input +2: class FileInput +*: should map easily + +1: class Fl_Fill_Dial +2: class FillDial +*: should map easily + +1: class Fl_Fill_Slider +2: class FillSlider +*: should map easily + +1: +2: class FlatBox + +1: class Fl_Float_Input +2: class FloatInput +*: should map easily + +1: class Fl_FormsBitmap +2: + +1: class Fl_FormsPixmap +2: + +1: class Fl_FormsText +2: class Fl_FormsText +*: should map easily + +1: +2: class FrameBox + +1: class Fl_Free +2: + +1: class Fl_GIF_Image +2: class gifImage +*: should map easily + +1: class Fl_Gl_Choice +2: class GlChoice +*: should map easily + +1: class Fl_Gl_Window +2: class GlWindow +*: should map easily + +1: +2: class GlOverlay + +1: class Fl_Glut_Window +2: class GlutWindow + +1: class Fl_Group +2: class Group +*: should map easily, must manage coordinate systems + +1: +2: class GSave + +1: +2: class Guard + +1: class Fl_Help_Dialog +2: class HelpDialog +*: should map easily + +1: class Fl_Help_View +2: class HelpView +*: should map easily + +1: +2: class HighlightBox + +1: +2: class HighlightButton + +1: class Fl_Hold_Browser +2: + +1: class Fl_Hor_Fill_Slider +2: + +1: class Fl_Hor_Nice_Slider +2: + +1: class Fl_Hor_Slider +2: + +1: class Fl_Hor_Value_Slider +2: + +1: class Fl_Image +2: class Image +*: should map easily + +1: class Fl_Input +2: class Input +*: should map easily + +1: class Fl_Input_ +2: + +1: +2: class InputBrowser + +1: class Fl_Input_Choice +2: class ComboBox +*: should map easily + +1: class Fl_Int_Input +2: class IntInput +*: should map easily + +1: +2: class InvisibleBox + +1: +2: class Item + +1: +2: class ItemGroup + +1: class Fl_JPEG_Image +2: class jpegImage +*: should map easily + +1: +2: class LabelType + +1: class Fl_Light_Button +2: class LightButton +*: should map easily + +1: class Fl_Line_Dial +2: class LineDial +*: should map easily + +1: +2: class List + +1: class Fl_Menu_ +2: class Menu + +1: class Fl_Menu_Bar +2: class MenuBar + +1: class Fl_Menu_Button +2: class PopupMenu + +1: +2: class MenuSection + +1: class Fl_Menu_Window +2: class MenuWindow + +1: +2: class Monitor + +1: class Fl_Multi_Browser +2: class MultiBrowser + +1: +2: class MultiImage + +1: class Fl_Multiline_Input +2: class MultiLineInput +*: should map easily + +1: class Fl_Multiline_Output +2: class MultiLineOutput +*: should map easily + +1: +2: class Mutex + +1: class Fl_Nice_Slider +2: + +1: +2: class NumericInput + +1: class Fl_Output +2: class Output +*: should map easily + +1: class Fl_Overlay_Window +2: + +1: class Fl_PNG_Image +2: class pngImage +*: should map easily + +1: class Fl_PNM_Image +2: class pnmImage +*: should map easily + +1: class Fl_Pack +2: class PackedGroup +*: should map easily, FLTK 2 has soem additional functionaity + +1: class Fl_Pixmap +2: + +1: class Fl_Positioner +2: + +1: class Fl_Preferences +2: class Preferences +*: should map easily + +1: class Fl_Progress +2: class ProgressBar +*: should map easily + +1: class Fl_RGB_Image +2: class rgbImage +*: should map easily + +1: class Fl_Radio_Button +2: class RadioButton +*: should map easily + +1: +2: class RadioItem + +1: class Fl_Radio_Light_Button +2: class RadioLightButton +*: should map easily + +1: class Fl_Radio_Round_Button +2: + +1: +2: class Rectangle + +1: +2: class RecursiveMutex + +1: class Fl_Repeat_Button +2: class RepeatButton +*: should map easily + +1: class Fl_Return_Button +2: class ReturnButton +*: should map easily + +1: class Fl_Roller +2: class ThumbWheel +*: should map easily + +1: class Fl_Round_Button +2: + +1: class Fl_Round_Clock +2: + +1: class Fl_Scroll +2: class ScrollGroup +*: should map easily + +1: class Fl_Scrollbar +2: class Scrollbar +*: should map easily + +1: class Fl_Secret_Input +2: class SecretInput +*: should map easily + +1: class Fl_Select_Browser +2: + +1: +2: class ShapedWindow + +1: class Fl_Shared_Image +2: class SharedImage +*: should map easily + +1: +2: class ShortcutFunctor + +1: class Fl_Simple_Counter +2: + +1: class Fl_Single_Window +2: + +1: +2: class SignalMutex + +1: class Fl_Slider +2: class Slider +*: should map easily + +1: class Fl_Spinner +2: + +1: +2: class StatusBarGroup + +1: +2: class StringArray + +1: +2: class StringHierarchy + +1: +2: class StringList + +1: +2: class Style + +1: +2: class StyleSet + +1: +2: class Symbol + +1: class Fl_Sys_Menu_Bar +2: class SystemMenuBar +*: should map easily + +1: class Fl_Tabs +2: class TabGroup +*: should map easily + +1: +2: class TabGroupPager + +1: class Fl_Text_Buffer +2: class TextBuffer +*: should map easily + +1: class Fl_Text_Display +2: class TextDisplay +*: should map easily + +1: class Fl_Text_Editor +2: class TextEditor +*: should map easily + +1: class Fl_Text_Selection +2: class TextSelection +*: should map easily + +1: class Fl_Tile +2: class TiledGroup +*: should map easily + +1: class Fl_Tiled_Image +2: class TiledImage +*: should map easily + +1: class Fl_Timer +2: + +1: class Fl_Toggle_Button +2: class ToggleButton +*: should map easily + +1: +2: class ToggleItem + +1: class Fl_Tooltip +2: class Tooltip +*: should map easily + +1: +2: class WordwrapInput + +1: +2: class WordwrapOutput + +1: class Fl_Valuator +2: class Valuator +*: should map easily + +1: class Fl_Value_Input +2: class ValueInput +*: should map easily + +1: class Fl_Value_Output +2: class ValueOutput +*: should map easily + +1: class Fl_Value_Slider +2: class ValueSlider +*: should map easily + +1: class Fl_Widget +2: class Widget +*: should map easily for the most part + +1: class Fl_Widget_Tracker +2: + +1: class Fl_Window +2: class Window +*: should map easily + +1: class Fl_Wizard +2: class WizardGroup +*: should map easily + +1: class Fl_X +2: class CreatedWindow +*: should map easily + +1: class Fl_XBM_Image +2: class xbmImage +*: should map easily + +1: class Fl_XPM_Image +2: class xpmImage +*: should map easily + +1: +2: class xpmFileImage + +1: +2: struct Cursor + +1: +2: struct Font + +1: struct Fl_Glut_Bitmap_Font +2: + +1: struct Fl_Glut_StrokeChar +2: + +1: struct Fl_Glut_StrokeFont +2: + +1: struct Fl_Glut_StrokeStrip +2: + +1: struct Fl_Glut_StrokeVertex +2: + +1: struct Fl_Help_Block +2: struct HelpBlock +*: should map easily + +1: struct Fl_Help_Font_Stack +2: + +1: struct Fl_Help_Font_Style +2: + +1: struct Fl_Help_Link +2: struct HelpLink +*: should map easily + +1: struct Fl_Help_Target +2: struct HelpTarget +*: should map easily + +1: +2: struct ImageType + +1: struct Fl_Label +2: + +1: struct Fl_Menu_Item +2: + +1: struct Fl_Multi_Label +2: + +1: +2: struct NamedStyle + + diff --git a/plugins/zynaddsubfx/fltk/src/CMakeLists.txt b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt index 7b628bd01..d12f04db2 100644 --- a/plugins/zynaddsubfx/fltk/src/CMakeLists.txt +++ b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt @@ -34,7 +34,7 @@ SET(CPPFILES Fl_Menu.cxx Fl_Menu_.cxx Fl_Menu_Bar.cxx - Fl_Sys_Menu_Bar.cxx + Fl_Sys_Menu_Bar.cxx Fl_Menu_Button.cxx Fl_Menu_Window.cxx Fl_Menu_add.cxx @@ -130,6 +130,8 @@ SET(CPPFILES fl_vertex.cxx screen_xywh.cxx fl_utf8.cxx + fl_encoding_latin1.cxx + fl_encoding_mac_roman.cxx ) SET(FLCPPFILES forms_compatability.cxx @@ -165,18 +167,18 @@ SET(IMGCPPFILES SET(CFILES fl_call_main.c - fl_utf.c flstring.c scandir.c numericsort.c vsnprintf.c - xutf8/case.c xutf8/is_right2left.c xutf8/is_spacing.c - xutf8/keysym2Ucs.c + xutf8/case.c xutf8/utf8Input.c xutf8/utf8Utils.c xutf8/utf8Wrap.c + xutf8/keysym2Ucs.c + fl_utf.c ) ADD_LIBRARY(fltk ${CPPFILES} ${CFILES}) diff --git a/plugins/zynaddsubfx/fltk/src/Fl.cxx b/plugins/zynaddsubfx/fltk/src/Fl.cxx index d621d2318..2d6e03fe3 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl.cxx 6787 2009-05-14 20:16:09Z engelsman $" +// "$Id: Fl.cxx 6836 2009-07-25 12:56:16Z AlbrechtS $" // // Main event handling code for the Fast Light Tool Kit (FLTK). // @@ -1699,5 +1699,5 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker() { } // -// End of "$Id: Fl.cxx 6787 2009-05-14 20:16:09Z engelsman $". +// End of "$Id: Fl.cxx 6836 2009-07-25 12:56:16Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx index 14a2db47c..0db009245 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Browser.cxx 6726 2009-03-27 16:52:31Z greg.ercolano $" +// "$Id: Fl_Browser.cxx 6895 2009-09-21 06:35:08Z greg.ercolano $" // // Browser widget for the Fast Light Tool Kit (FLTK). // @@ -44,10 +44,16 @@ #define SELECTED 1 #define NOTDISPLAYED 2 +// WARNING: +// Fl_File_Chooser.cxx also has a definition of this structure (FL_BLINE). +// Changes to FL_BLINE *must* be reflected in Fl_File_Chooser.cxx as well. +// This hack in Fl_File_Chooser should be solved. +// struct FL_BLINE { // data is in a linked list of these FL_BLINE* prev; FL_BLINE* next; void* data; + Fl_Image* icon; short length; // sizeof(txt)-1, may be longer than string char flags; // selected, displayed char txt[1]; // start of allocated array @@ -138,7 +144,8 @@ const char *Fl_Browser::item_text(void *item) const { item_next(), etc. to access the internal linked list more efficiently. \param[in] line The line number of the item to return. (1 based) - \returns The returned item. + \retval item that was found. + \retval NULL if line is out of range. \see item_at(), find_line(), lineno() */ FL_BLINE* Fl_Browser::find_line(int line) const { @@ -287,6 +294,7 @@ void Fl_Browser::insert(int line, const char* newtext, void* d) { t->flags = 0; strcpy(t->txt, newtext); t->data = d; + t->icon = 0; insert(line, t); } @@ -321,6 +329,7 @@ void Fl_Browser::text(int line, const char* newtext) { replacing(t, n); cache = n; n->data = t->data; + n->icon = t->icon; n->length = (short)l; n->flags = t->flags; n->prev = t->prev; @@ -364,8 +373,7 @@ int Fl_Browser::item_height(void *item) const { fl_font(textfont(), textsize()); int hh = fl_height(); if (hh > hmax) hmax = hh; - } - else { + } else { const int* i = column_widths(); // do each column separately as they may all set different fonts: for (char* str = l->txt; str && *str; str++) { @@ -400,6 +408,9 @@ int Fl_Browser::item_height(void *item) const { } } + if (l->icon && (l->icon->h()+2)>hmax) { + hmax = l->icon->h() + 2; // leave 2px above/below + } return hmax; // previous version returned hmax+2! } @@ -412,7 +423,8 @@ int Fl_Browser::item_height(void *item) const { incr_height(), full_height() */ int Fl_Browser::item_width(void *item) const { - char* str = ((FL_BLINE*)item)->txt; + FL_BLINE* l=(FL_BLINE*)item; + char* str = l->txt; const int* i = column_widths(); int ww = 0; @@ -457,6 +469,8 @@ int Fl_Browser::item_width(void *item) const { if (*str == format_char_ && str[1]) str ++; + if (ww==0 && l->icon) ww = l->icon->w(); + fl_font(font, tsize); return ww + int(fl_width(str)) + 6; } @@ -492,9 +506,11 @@ int Fl_Browser::incr_height() const { \param[in] X,Y,W,H position and size. */ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { - char* str = ((FL_BLINE*)item)->txt; + FL_BLINE* l = (FL_BLINE*)item; + char* str = l->txt; const int* i = column_widths(); + bool first = true; // for icon while (W > 6) { // do each tab-separated field int w1 = W; // width for this field char* e = 0; // pointer to end of field or null if none @@ -502,6 +518,15 @@ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { e = strchr(str, column_char()); if (e) {*e = 0; w1 = *i++;} } + // Icon drawing code + if (first) { + first = false; + if (l->icon) { + l->icon->draw(X+2,Y+1); // leave 2px left, 1px above + int iconw = l->icon->w()+2; + X += iconw; W -= iconw; w1 -= iconw; + } + } int tsize = textsize(); Fl_Font font = textfont(); Fl_Color lcol = textcolor(); @@ -521,7 +546,7 @@ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { case 'c': talign = FL_ALIGN_CENTER; break; case 'r': talign = FL_ALIGN_RIGHT; break; case 'B': - if (!(((FL_BLINE*)item)->flags & SELECTED)) { + if (!(l->flags & SELECTED)) { fl_color((Fl_Color)strtol(str, &str, 10)); fl_rectf(X, Y, w1, H); } else strtol(str, &str, 10); @@ -557,7 +582,7 @@ void Fl_Browser::item_draw(void* item, int X, int Y, int W, int H) const { } BREAK: fl_font(font, tsize); - if (((FL_BLINE*)item)->flags & SELECTED) + if (l->flags & SELECTED) lcol = fl_contrast(lcol, selection_color()); if (!active_r()) lcol = fl_inactive(lcol); fl_color(lcol); @@ -592,8 +617,7 @@ Fl_Browser::Fl_Browser(int X, int Y, int W, int H, const char *L) Updates the browser so that \p line is shown at position \p pos. \param[in] line line number. (1 based) \param[in] pos position. - \see topline(), middleline(), bottomline(), \n -+: Command not found. + \see topline(), middleline(), bottomline() */ void Fl_Browser::lineposition(int line, Fl_Line_Position pos) { if (line<1) line = 1; @@ -835,6 +859,58 @@ void Fl_Browser::swap(int a, int b) { swap(ai,bi); } +/** + Set the image icon for \p line to the value \p icon. + Caller is responsible for keeping the icon allocated. + The \p line is automatically redrawn. + \param[in] line The line to be modified. If out of range, nothing is done. + \param[in] icon The image icon to be assigned to the \p line. + If NULL, any previous icon is removed. +*/ +void Fl_Browser::icon(int line, Fl_Image* icon) { + + if (line<1 || line > lines) return; + + FL_BLINE* bl = find_line(line); + + int old_h = bl->icon ? bl->icon->h()+2 : 0; // init with *old* icon height + bl->icon = 0; // remove icon, if any + int th = item_height(bl); // height of text only + int new_h = icon ? icon->h()+2 : 0; // init with *new* icon height + if (th > old_h) old_h = th; + if (th > new_h) new_h = th; + int dh = new_h - old_h; + full_height_ += dh; // do this *always* + + bl->icon = icon; // set new icon + if (dh>0) { + redraw(); // icon larger than item? must redraw widget + } else { + redraw_line(bl); // icon same or smaller? can redraw just this line + } + replacing(bl,bl); // recalc Fl_Browser_::max_width et al +} + +/** + Returns the icon currently defined for \p line. + If no icon is defined, NULL is returned. + \param[in] line The line whose icon is returned. + \returns The icon defined, or NULL if none. +*/ +Fl_Image* Fl_Browser::icon(int line) const { + FL_BLINE* l = find_line(line); + return(l ? l->icon : NULL); +} + +/** + Removes the icon for \p line. + It's ok to remove an icon if none has been defined. + \param[in] line The line whose icon is to be removed. +*/ +void Fl_Browser::remove_icon(int line) { + icon(line,0); +} + // -// End of "$Id: Fl_Browser.cxx 6726 2009-03-27 16:52:31Z greg.ercolano $". +// End of "$Id: Fl_Browser.cxx 6895 2009-09-21 06:35:08Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx index 22054e821..a31bdc873 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Choice.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Choice.cxx 6873 2009-09-16 07:06:41Z AlbrechtS $" // // Choice widget for the Fast Light Tool Kit (FLTK). // @@ -209,5 +209,5 @@ int Fl_Choice::handle(int e) { } // -// End of "$Id: Fl_Choice.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Choice.cxx 6873 2009-09-16 07:06:41Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx index 8e31149c3..f26951e4d 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx @@ -128,7 +128,7 @@ HDC fl_makeDC(HBITMAP bitmap) { SetTextAlign(new_gc, TA_BASELINE|TA_LEFT); SetBkMode(new_gc, TRANSPARENT); #if USE_COLORMAP - if (fl_palette) SelectPalette(new_gc, fl_palette, false); + if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE); #endif SelectObject(new_gc, bitmap); return new_gc; diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx index 1834185a4..00b182ccf 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Browser.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_File_Browser.cxx 6853 2009-09-09 05:16:41Z greg.ercolano $" // // Fl_File_Browser routines. // @@ -42,6 +42,7 @@ #include #include #include +#include // icon #include #include #include "flstring.h" @@ -80,11 +81,17 @@ #define SELECTED 1 #define NOTDISPLAYED 2 +// TODO -- Warning: The definition of FL_BLINE here is a hack. +// Fl_File_Browser should not do this. PLEASE FIX. +// FL_BLINE should be private to Fl_Browser, and not re-defined here. +// For now, make sure this struct is precisely consistent with Fl_Browser.cxx. +// struct FL_BLINE // data is in a linked list of these { FL_BLINE *prev; // Previous item in list FL_BLINE *next; // Next item in list void *data; // Pointer to data (function) + Fl_Image *icon; // Pointer to optional icon short length; // sizeof(txt)-1, may be longer than string char flags; // selected, displayed char txt[1]; // start of allocated array @@ -635,5 +642,5 @@ Fl_File_Browser::filter(const char *pattern) // I - Pattern string // -// End of "$Id: Fl_File_Browser.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_File_Browser.cxx 6853 2009-09-09 05:16:41Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx index 03e070e16..58df478be 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_File_Chooser2.cxx 6678 2009-03-13 23:36:09Z AlbrechtS $" +// "$Id: Fl_File_Chooser2.cxx 6899 2009-09-23 21:32:23Z matt $" // // More Fl_File_Chooser routines. // @@ -858,7 +858,7 @@ Fl_File_Chooser::fileNameCB() } } else { // File doesn't exist, so beep at and alert the user... - fl_alert("%s", existing_file_label); + fl_alert(existing_file_label); } } else if (Fl::event_key() != FL_Delete && @@ -1046,7 +1046,7 @@ Fl_File_Chooser::newdir() // Get a directory name from the user - if ((dir = fl_input("%s", new_directory_label, (char *)NULL)) == NULL) + if ((dir = fl_input(new_directory_label, NULL)) == NULL) return; // Make it relative to the current directory as needed... @@ -1213,7 +1213,7 @@ Fl_File_Chooser::showChoiceCB() item = showChoice->text(showChoice->value()); if (strcmp(item, custom_filter_label) == 0) { - if ((item = fl_input("%s",custom_filter_label, pattern_)) != NULL) { + if ((item = fl_input(custom_filter_label, pattern_)) != NULL) { strlcpy(pattern_, item, sizeof(pattern_)); quote_pathname(temp, item, sizeof(temp)); @@ -1332,10 +1332,37 @@ Fl_File_Chooser::update_preview() window->cursor(FL_CURSOR_DEFAULT); Fl::check(); - // Scan the buffer for printable chars... - for (ptr = preview_text_; + // Scan the buffer for printable UTF8 chars... + for (ptr = preview_text_; *ptr; ptr++) { + uchar c = uchar(*ptr); + if ( (c&0x80)==0 ) { + if (!isprint(c&255) && !isspace(c&255)) break; + } else if ( (c&0xe0)==0xc0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } else if ( (c&0xf0)==0xe0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } else if ( (c&0xf8)==0xf0 ) { + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + if (ptr[1] && (ptr[1]&0xc0)!=0x80) break; + ptr++; + } + } +// *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255)); +// ptr ++); + + // Scan the buffer for printable characters in 8 bit + if (*ptr || ptr == preview_text_) { + for (ptr = preview_text_; *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255)); ptr ++); + } if (*ptr || ptr == preview_text_) { // Non-printable file, just show a big ?... @@ -1589,5 +1616,5 @@ unquote_pathname(char *dst, // O - Destination string // -// End of "$Id: Fl_File_Chooser2.cxx 6678 2009-03-13 23:36:09Z AlbrechtS $". +// End of "$Id: Fl_File_Chooser2.cxx 6899 2009-09-23 21:32:23Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx index 6ed5a0759..d46c98452 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx @@ -144,7 +144,7 @@ void Fl_File_Input::update_buttons() { \param[in] str new string value \param[in] len lengh of value */ -int // O - true on success +int // O - TRUE on success Fl_File_Input::value(const char *str, // I - New string value int len) { // I - Length of value damage(FL_DAMAGE_BAR); @@ -157,7 +157,7 @@ Fl_File_Input::value(const char *str, // I - New string value Returns non 0 on success. \param[in] str new string value */ -int // O - true on success +int // O - TRUE on success Fl_File_Input::value(const char *str) { // I - New string value damage(FL_DAMAGE_BAR); return Fl_Input::value(str); @@ -187,7 +187,7 @@ void Fl_File_Input::draw() { Return non zero if event is handled. \param[in] event */ -int // O - true if we handled event +int // O - TRUE if we handled event Fl_File_Input::handle(int event) // I - Event { // printf("handle(event = %d)\n", event); @@ -230,7 +230,7 @@ Fl_File_Input::handle(int event) // I - Event Return non zero if event is handled. \param[in] event */ -int // O - true if we handled event +int // O - TRUE if we handled event Fl_File_Input::handle_button(int event) // I - Event { int i, // Looping var diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx index 79c8762b1..e0ffc14fe 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.cxx 6773 2009-04-21 09:25:22Z AlbrechtS $" +// "$Id: Fl_Image.cxx 6804 2009-06-29 07:44:25Z AlbrechtS $" // // Image drawing code for the Fast Light Tool Kit (FLTK). // @@ -551,5 +551,5 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) { // -// End of "$Id: Fl_Image.cxx 6773 2009-04-21 09:25:22Z AlbrechtS $". +// End of "$Id: Fl_Image.cxx 6804 2009-06-29 07:44:25Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx index 1b25a6898..7be68aafa 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input.cxx 6765 2009-04-15 08:35:28Z matt $" +// "$Id: Fl_Input.cxx 6888 2009-09-19 21:16:21Z matt $" // // Input widget for the Fast Light Tool Kit (FLTK). // @@ -621,6 +621,18 @@ int Fl_Input::handle(int event) { take_focus(); return 1; +/* TODO: this will scroll the area, but stop if the cursor would become invisible. + That clipping happens in drawtext(). Do we change the clipping or should + we move the cursor (ouch)? + case FL_MOUSEWHEEL: + if (Fl::e_dy > 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } else if (Fl::e_dy < 0) { + yscroll( yscroll() - Fl::e_dy*15 ); + } + return 1; +*/ + } Fl_Boxtype b = box(); return Fl_Input_::handletext(event, @@ -637,5 +649,5 @@ Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l) } // -// End of "$Id: Fl_Input.cxx 6765 2009-04-15 08:35:28Z matt $". +// End of "$Id: Fl_Input.cxx 6888 2009-09-19 21:16:21Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx index 3868255b1..ca6638c60 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Input_.cxx 6777 2009-04-23 15:32:19Z matt $" +// "$Id: Fl_Input_.cxx 6887 2009-09-19 20:57:48Z matt $" // // Common input widget routines for the Fast Light Tool Kit (FLTK). // @@ -134,7 +134,7 @@ double Fl_Input_::expandpos( if (c < ' ' || c == 127) { if (c == '\t' && input_type()==FL_MULTILINE_INPUT) { n += 8-(chr%8); - chr += 8-(chr%8); + chr += 7-(chr%8); } else n += 2; } else { n++; @@ -239,6 +239,7 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) { // count how many lines and put the last one into the buffer: // And figure out where the cursor is: int height = fl_height(); + int threshold = height/2; int lines; int curx, cury; for (p=value(), curx=cury=lines=0; ;) { @@ -248,15 +249,15 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) { if (Fl::focus()==this && !was_up_down) up_down_pos = curx; cury = lines*height; int newscroll = xscroll_; - if (curx > newscroll+W-20) { + if (curx > newscroll+W-threshold) { // figure out scrolling so there is space after the cursor: - newscroll = curx+20-W; + newscroll = curx+threshold-W; // figure out the furthest left we ever want to scroll: int ex = int(expandpos(p, e, buf, 0))+2-W; // use minimum of both amounts: if (ex < newscroll) newscroll = ex; - } else if (curx < newscroll+20) { - newscroll = curx-20; + } else if (curx < newscroll+threshold) { + newscroll = curx-threshold; } if (newscroll < 0) newscroll = 0; if (newscroll != xscroll_) { @@ -1253,5 +1254,5 @@ Fl_Char Fl_Input_::index(int i) const } // -// End of "$Id: Fl_Input_.cxx 6777 2009-04-23 15:32:19Z matt $". +// End of "$Id: Fl_Input_.cxx 6887 2009-09-19 20:57:48Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx index 4e71f0775..f49d89668 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu.cxx 6757 2009-04-12 20:00:45Z matt $" +// "$Id: Fl_Menu.cxx 6841 2009-08-03 06:26:32Z AlbrechtS $" // // Menu code for the Fast Light Tool Kit (FLTK). // @@ -1014,5 +1014,5 @@ const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const { } // -// End of "$Id: Fl_Menu.cxx 6757 2009-04-12 20:00:45Z matt $". +// End of "$Id: Fl_Menu.cxx 6841 2009-08-03 06:26:32Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx index ce7c89e10..3c83ae7b9 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_.cxx 6660 2009-02-15 18:58:03Z AlbrechtS $" +// "$Id: Fl_Menu_.cxx 6904 2009-09-27 11:39:02Z matt $" // // Common menu code for the Fast Light Tool Kit (FLTK). // @@ -172,11 +172,11 @@ void Fl_Menu_Item::setonly() { } } -Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l) /** - Creates a new Fl_Menu_ widget using the given position, size, - and label string. menu() is initialized to null. -*/ + Creates a new Fl_Menu_ widget using the given position, size, + and label string. menu() is initialized to null. + */ +Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l) : Fl_Widget(X,Y,W,H,l) { set_flag(SHORTCUT_LABEL); box(FL_UP_BOX); @@ -262,5 +262,5 @@ void Fl_Menu_::clear() { } // -// End of "$Id: Fl_Menu_.cxx 6660 2009-02-15 18:58:03Z AlbrechtS $". +// End of "$Id: Fl_Menu_.cxx 6904 2009-09-27 11:39:02Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx index 9a3d4be08..cbeeb631a 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Menu_add.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: Fl_Menu_add.cxx 6878 2009-09-17 22:12:24Z matt $" // // Menu utilities for the Fast Light Tool Kit (FLTK). // @@ -177,56 +177,95 @@ int Fl_Menu_Item::add( } /** - Adds a new menu item, with a title string, shortcut int (or string), - callback, argument to the callback, and flags. + Adds a new menu item. + + \param[in] label The text label for the menu item. + \param[in] shortcut Optional keyboard shortcut that can be an int or string; (FL_CTRL+'a') or "^a". Default 0 if none. + \param[in] callback Optional callback invoked when user clicks the item. Default 0 if none. + \param[in] userdata Optional user data passed as an argument to the callback. Default 0 if none. + \param[in] flags Optional flags that control the type of menu item; see below. Default is 0 for none. + \returns The index into the menu() array, where the entry was added. + + \par Description If the menu array was directly set with menu(x), then copy() is done to make a private array. - - The characters "&", "/", "\", and "_" are treated as - special characters in the label string. The "&" character - specifies that the following character is an accelerator and - will be underlined. The "\" character is used to escape the next - character in the string. Labels starting with the "_" character - cause a divider to be placed after that menu item. - - A label of the form "foo/bar/baz" will create submenus called - "foo" and "bar" with an entry called "baz". The "/" character is - ignored if it appears as the first character of the label string, e.g. - "/foo/bar/baz". - + \par + A menu item's callback must not add() items to its parent menu during the callback. + + Detailed Description of Parameters + \par label + The menu item's label. This option is required. + \par + The characters "&", "/", "\", and "_" are treated as special characters in the label string. + The "&" character specifies that the following character is an accelerator and will be underlined. + The "\" character is used to escape the next character in the string. + Labels starting with the "_" character cause a divider to be placed after that menu item. + \par + A label of the form "File/Quit" will create the submenu "File" + with a menu item called "Quit". The "/" character is ignored if it appears + as the first character of the label string, e.g. "/File/Quit". + \par The label string is copied to new memory and can be freed. The other arguments (including the shortcut) are copied into the menu item unchanged. - + \par If an item exists already with that name then it is replaced with this new one. Otherwise this new one is added to the end of the correct menu or submenu. The return value is the offset into the array that the new entry was placed at. + \par shortcut + The keyboard shortcut for this menu item. + \par + This parameter is optional, and defaults to 0 to indicate no shortcut. + \par Shortcut can be 0L, or either a modifier/key combination (for example FL_CTRL+'A') or a string describing the shortcut in one of two ways: - - \code + \verbatim [#+^] e.g. "97", "^97", "+97", "#97" [#+^] e.g. "a", "^a", "+a", "#a" - \endcode + \endverbatim ..where \ is a decimal value representing an ascii character (eg. 97 is the ascii for 'a'), and the optional prefixes enhance the value that follows. Multiple prefixes must appear in the above order. - \code + \verbatim # - Alt + - Shift ^ - Control - \endcode + \endverbatim Text shortcuts are converted to integer shortcut by calling - int fl_old_shortcut(const char*). - - The return value is the index into the array that the entry was put. - - No items must be added to a menu during a callback to the same menu. + Fl_Shortcut fl_old_shortcut(const char*). + + \par callback + The callback to invoke when this menu item is selected. + \par + This parameter is optional, and defaults to 0 for no callback. + + \par userdata + The callback's 'user data' that is passed to the callback. + \par + This parameter is optional, and defaults to 0. + + \par flags + These are bit flags to define what kind of menu item this is. + \par + This parameter is optional, and defaults to 0 to define a 'regular' menu item. + \par + These flags can be 'OR'ed together: + \code + FL_MENU_INACTIVE // Deactivate menu item (gray out) + FL_MENU_TOGGLE // Item is a checkbox toggle (shows checkbox for on/off state) + FL_MENU_VALUE // The on/off state for checkbox/radio buttons (if set, state is 'on') + FL_MENU_RADIO // Item is a radio button (one checkbox of many can be on) + FL_MENU_INVISIBLE // Item will not show up (shortcut will work) + FL_SUBMENU_POINTER // Indicates user_data() is a pointer to another menu array + FL_SUBMENU // This item is a submenu to other items + FL_MENU_DIVIDER // Creates divider line below this item. Also ends a group of radio buttons. + \endcode + */ -int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) { +int Fl_Menu_::add(const char *label,int shortcut,Fl_Callback *callback,void *userdata,int flags) { // make this widget own the local array: if (this != fl_menu_array_owner) { if (fl_menu_array_owner) { @@ -260,7 +299,7 @@ int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) { } fl_menu_array_owner = this; } - int r = menu_->add(t,s,c,v,f); + int r = menu_->add(label,shortcut,callback,userdata,flags); // if it rellocated array we must fix the pointer: int value_offset = value_-menu_; menu_ = local_array; // in case it reallocated it @@ -335,5 +374,5 @@ void Fl_Menu_::remove(int i) { } // -// End of "$Id: Fl_Menu_add.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: Fl_Menu_add.cxx 6878 2009-09-17 22:12:24Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx index 227c90f57..d7dee6885 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Progress.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: Fl_Progress.cxx 6794 2009-06-27 09:29:36Z AlbrechtS $" // // Progress bar widget routines. // @@ -119,5 +119,5 @@ Fl_Progress::Fl_Progress(int X, int Y, int W, int H, const char* L) // -// End of "$Id: Fl_Progress.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: Fl_Progress.cxx 6794 2009-06-27 09:29:36Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx index 07ebcc28f..f9a03027a 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Scroll.cxx 6654 2009-02-08 18:47:37Z AlbrechtS $" +// "$Id: Fl_Scroll.cxx 6828 2009-07-12 00:15:06Z greg.ercolano $" // // Scroll widget for the Fast Light Tool Kit (FLTK). // @@ -413,5 +413,5 @@ int Fl_Scroll::handle(int event) { } // -// End of "$Id: Fl_Scroll.cxx 6654 2009-02-08 18:47:37Z AlbrechtS $". +// End of "$Id: Fl_Scroll.cxx 6828 2009-07-12 00:15:06Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx index 91c33f4bc..73f72f121 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Buffer.cxx 6765 2009-04-15 08:35:28Z matt $" +// "$Id: Fl_Text_Buffer.cxx 6825 2009-07-04 05:18:29Z fabien $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -2502,5 +2502,5 @@ Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) { // -// End of "$Id: Fl_Text_Buffer.cxx 6765 2009-04-15 08:35:28Z matt $". +// End of "$Id: Fl_Text_Buffer.cxx 6825 2009-07-04 05:18:29Z fabien $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx index 5a01f7462..3e09584e8 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Display.cxx 6765 2009-04-15 08:35:28Z matt $" +// "$Id: Fl_Text_Display.cxx 6909 2009-09-28 14:41:43Z matt $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -387,8 +387,8 @@ void Fl_Text_Display::resize(int X, int Y, int W, int H) { mMaxsize = max(mMaxsize, fl_height(mStyleTable[i].font, mStyleTable[i].size)); // did we have scrollbars initially? - int hscrollbarvisible = mHScrollBar->visible(); - int vscrollbarvisible = mVScrollBar->visible(); + unsigned int hscrollbarvisible = mHScrollBar->visible(); + unsigned int vscrollbarvisible = mVScrollBar->visible(); // try without scrollbars first mVScrollBar->clear_visible(); @@ -3439,5 +3439,5 @@ int Fl_Text_Display::handle(int event) { // -// End of "$Id: Fl_Text_Display.cxx 6765 2009-04-15 08:35:28Z matt $". +// End of "$Id: Fl_Text_Display.cxx 6909 2009-09-28 14:41:43Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx index 5e5ea41af..dc471cafe 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Text_Editor.cxx 6765 2009-04-15 08:35:28Z matt $" +// "$Id: Fl_Text_Editor.cxx 6894 2009-09-20 21:55:21Z greg.ercolano $" // // Copyright 2001-2009 by Bill Spitzak and others. // Original code Copyright Mark Edel. Permission to distribute under @@ -156,6 +156,14 @@ static struct { { 'c', FL_COMMAND, Fl_Text_Editor::kf_copy }, { 'v', FL_COMMAND, Fl_Text_Editor::kf_paste }, { 'a', FL_COMMAND, Fl_Text_Editor::kf_select_all }, + { FL_Left, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Right, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Up, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Down, FL_COMMAND, Fl_Text_Editor::kf_meta_move }, + { FL_Left, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Right, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Up, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, + { FL_Down, FL_COMMAND|FL_SHIFT, Fl_Text_Editor::kf_m_s_move }, #endif // __APPLE__ { 0, 0, 0 } @@ -352,6 +360,40 @@ int Fl_Text_Editor::kf_ctrl_move(int c, Fl_Text_Editor* e) { return 1; } +/** Moves the current text cursor in the direction indicated by meta key */ +int Fl_Text_Editor::kf_meta_move(int c, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) + e->dragPos = e->insert_position(); + if (c != FL_Up && c != FL_Down) { + e->buffer()->unselect(); + e->show_insert_position(); + } + switch (c) { + case FL_Up: // top of buffer + e->insert_position(0); + e->scroll(0, 0); + break; + case FL_Down: // end of buffer + e->insert_position(e->buffer()->length()); + e->scroll(e->count_lines(0, e->buffer()->length(), 1), 0); + break; + case FL_Left: // beginning of line + kf_move(FL_Home, e); + break; + case FL_Right: // end of line + kf_move(FL_End, e); + break; + } + return 1; +} + +/** Extends the current selection in the direction indicated by meta key c. */ +int Fl_Text_Editor::kf_m_s_move(int c, Fl_Text_Editor* e) { + kf_meta_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} + /** Extends the current selection in the direction indicated by control key c. */ int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) { kf_ctrl_move(c, e); @@ -572,5 +614,5 @@ int Fl_Text_Editor::handle(int event) { } // -// End of "$Id: Fl_Text_Editor.cxx 6765 2009-04-15 08:35:28Z matt $". +// End of "$Id: Fl_Text_Editor.cxx 6894 2009-09-20 21:55:21Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx index ef533a0dc..ee02ac88d 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Tooltip.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $" +// "$Id: Fl_Tooltip.cxx 6902 2009-09-27 11:06:56Z matt $" // // Tooltip source file for the Fast Light Tool Kit (FLTK). // @@ -34,10 +34,10 @@ float Fl_Tooltip::delay_ = 1.0f; float Fl_Tooltip::hoverdelay_ = 0.2f; int Fl_Tooltip::enabled_ = 1; -unsigned Fl_Tooltip::color_ = fl_color_cube(FL_NUM_RED - 1, +Fl_Color Fl_Tooltip::color_ = fl_color_cube(FL_NUM_RED - 1, FL_NUM_GREEN - 1, FL_NUM_BLUE - 2); -unsigned Fl_Tooltip::textcolor_ = FL_BLACK; +Fl_Color Fl_Tooltip::textcolor_ = FL_BLACK; Fl_Font Fl_Tooltip::font_ = FL_HELVETICA; Fl_Fontsize Fl_Tooltip::size_ = FL_NORMAL_SIZE; @@ -278,5 +278,5 @@ void Fl_Widget::tooltip(const char *tt) { } // -// End of "$Id: Fl_Tooltip.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $". +// End of "$Id: Fl_Tooltip.cxx 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx index c0fa1a945..558a8d2e1 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window.cxx 6669 2009-02-25 08:44:54Z AlbrechtS $" +// "$Id: Fl_Window.cxx 6905 2009-09-27 12:06:35Z matt $" // // Window widget class for the Fast Light Tool Kit (FLTK). // @@ -66,7 +66,7 @@ Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l) cursor_bg = FL_WHITE; _Fl_Window(); - set_flag(FL_FORCE_POSITION); + set_flag(FORCE_POSITION); } Fl_Window::Fl_Window(int W, int H, const char *l) @@ -151,8 +151,7 @@ void Fl_Window::copy_label(const char *a) { void Fl_Window::iconlabel(const char *iname) { - // FIXME: 'flags' is 32 bit large! - uchar saveflags = flags(); + unsigned saveflags = flags(); label(label(), iname); set_flag(saveflags); } @@ -179,5 +178,5 @@ Fl_Window *Fl_Window::current() { // -// End of "$Id: Fl_Window.cxx 6669 2009-02-25 08:44:54Z AlbrechtS $". +// End of "$Id: Fl_Window.cxx 6905 2009-09-27 12:06:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx index 67f9877c8..6635133fd 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Window_fullscreen.cxx 6660 2009-02-15 18:58:03Z AlbrechtS $" +// "$Id: Fl_Window_fullscreen.cxx 6905 2009-09-27 12:06:35Z matt $" // // Fullscreen window support for the Fast Light Tool Kit (FLTK). // @@ -43,10 +43,10 @@ void Fl_Window::border(int b) { if (b) { if (border()) return; - clear_flag(FL_NOBORDER); + clear_flag(NOBORDER); } else { if (!border()) return; - set_flag(FL_NOBORDER); + set_flag(NOBORDER); } #if defined(USE_X11) if (shown()) Fl_X::i(this)->sendxjunk(); @@ -91,5 +91,5 @@ void Fl_Window::fullscreen_off(int X,int Y,int W,int H) { } // -// End of "$Id: Fl_Window_fullscreen.cxx 6660 2009-02-15 18:58:03Z AlbrechtS $". +// End of "$Id: Fl_Window_fullscreen.cxx 6905 2009-09-27 12:06:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx index d0d1b6f45..b2ed5b36c 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_arg.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $" +// "$Id: Fl_arg.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $" // // Optional argument initialization code for the Fast Light Tool Kit (FLTK). // @@ -538,5 +538,5 @@ int XParseGeometry(const char* string, int* x, int* y, #endif // ifdef WIN32 // -// End of "$Id: Fl_arg.cxx 6712 2009-03-22 19:21:34Z AlbrechtS $". +// End of "$Id: Fl_arg.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx index 5e181fc6c..28541652c 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_mac.cxx 6758 2009-04-13 07:32:01Z matt $" +// "$Id: Fl_mac.cxx 6905 2009-09-27 12:06:35Z matt $" // // MacOS specific code for the Fast Light Tool Kit (FLTK). // @@ -1496,10 +1496,10 @@ void fl_open_display() { beenHereDoneThat = 1; FlushEvents(everyEvent,0); - + MoreMasters(); // \todo Carbon suggests MoreMasterPointers() AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false ); - + // create the Mac Handle for the default cursor (a pointer to a pointer) GetQDGlobalsArrow(&default_cursor); default_cursor_ptr = &default_cursor; @@ -1508,12 +1508,12 @@ void fl_open_display() { ClearMenuBar(); AppendResMenu( GetMenuHandle( 1 ), 'DRVR' ); DrawMenuBar(); - + // bring the application into foreground without a 'CARB' resource Boolean same_psn; ProcessSerialNumber cur_psn, front_psn; if( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) && - !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) + !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) { // only transform the application type for unbundled apps CFBundleRef bundle = CFBundleGetMainBundle(); @@ -1522,35 +1522,16 @@ void fl_open_display() { FSRef execFs; CFURLRef execUrl = CFBundleCopyExecutableURL( bundle ); CFURLGetFSRef( execUrl, &execFs ); - + FSRef bundleFs; GetProcessBundleLocation( &cur_psn, &bundleFs ); - + if( !FSCompareFSRefs( &execFs, &bundleFs ) ) bundle = NULL; - + CFRelease(execUrl); } - - // imm: keycode handler stub setting - use Gestalt to determine the running system version, - // then set the keycode_function pointer accordingly - SInt32 MacVersion; - if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr) - { -// SInt32 maj, min, fix; -// Gestalt(gestaltSystemVersionMajor, &maj); // e.g. 10 -// Gestalt(gestaltSystemVersionMinor, &min); // e.g. 4 -// Gestalt(gestaltSystemVersionBugFix, &fix); // e.g. 11 - if(MacVersion >= 0x1050) { // 10.5.0 or later - keycode_function = keycodeToUnicode; - } - else { - keycode_function = keycode_wrap_old; // pre-10.5 mechanism - } - } - // else our default handler will be used (keycode_wrap_old) - - + if( !bundle ) { // Earlier versions of this code tried to use weak linking, however it @@ -1558,19 +1539,30 @@ void fl_open_display() { // both TransformProcessType and CPSEnableForegroundOperation, the following // conditional code compiled on 10.2 will still work on newer releases... OSErr err; - + #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 if (TransformProcessType != NULL) { - err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); - } else + err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); + } else #endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 - err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103); - + err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103); + if (err == noErr) { - SetFrontProcess( &cur_psn ); + SetFrontProcess( &cur_psn ); } } } + + // imm: keycode handler stub setting - use Gestalt to determine the running system version, + // then set the keycode_function pointer accordingly + keycode_function = keycode_wrap_old; // default to pre-10.5 mechanism + SInt32 MacVersion; + if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr) + { + if(MacVersion >= 0x1050) { // 10.5.0 or later + keycode_function = keycodeToUnicode; + } + } } } @@ -2185,7 +2177,7 @@ void Fl_X::make(Fl_Window* w) wp += 2*bx; hp += 2*by+bt; } - if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { + if (!(w->flags() & Fl_Widget::FORCE_POSITION)) { // use the Carbon functions below for default window positioning w->x(xyPos+Fl::x()); w->y(xyPos+Fl::y()); @@ -2232,7 +2224,7 @@ void Fl_X::make(Fl_Window* w) SetWindowClass(x->xid, kFloatingWindowClass); SetWindowActivationScope(x->xid, kWindowActivationScopeAll); } - if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) + if (!(w->flags() & Fl_Widget::FORCE_POSITION)) { WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ; if (w->modal()) { @@ -2412,7 +2404,7 @@ void Fl_Window::resize(int X,int Y,int W,int H) { int is_a_resize = (W != w() || H != h()); // printf("Fl_Winodw::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n", // X, Y, W, H, is_a_resize, resize_from_system, this); - if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION); + if (X != x() || Y != y()) set_flag(FORCE_POSITION); else if (!is_a_resize) return; if ( (resize_from_system!=this) && (!parent()) && shown()) { if (is_a_resize) { @@ -2881,5 +2873,5 @@ void MacUnmapWindow(Fl_Window *w, WindowPtr p) { #endif // FL_DOXYGEN // -// End of "$Id: Fl_mac.cxx 6758 2009-04-13 07:32:01Z matt $". +// End of "$Id: Fl_mac.cxx 6905 2009-09-27 12:06:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx index be96d311f..a97a082da 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_win32.cxx 6668 2009-02-21 10:18:47Z AlbrechtS $" +// "$Id: Fl_win32.cxx 6905 2009-09-27 12:06:35Z matt $" // // WIN32-specific code for the Fast Light Tool Kit (FLTK). // @@ -398,7 +398,7 @@ int fl_wait(double time_to_wait) { time_to_wait = (time_to_wait > 10000 ? 10000 : time_to_wait); int t_msec = (int) (time_to_wait * 1000.0 + 0.5); - MsgWaitForMultipleObjects(0, NULL, false, t_msec, QS_ALLINPUT); + MsgWaitForMultipleObjects(0, NULL, FALSE, t_msec, QS_ALLINPUT); fl_lock_function(); @@ -1127,7 +1127,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar #if USE_COLORMAP case WM_QUERYNEWPALETTE : fl_GetDC(hWnd); - if (fl_select_palette()) InvalidateRect(hWnd, NULL, false); + if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE); break; case WM_PALETTECHANGED: @@ -1215,7 +1215,7 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) r.right = w->x()+w->w(); r.bottom = w->y()+w->h(); // get the decoration rectangle for the desired client rectangle - BOOL ok = AdjustWindowRectEx(&r, style, false, exstyle); + BOOL ok = AdjustWindowRectEx(&r, style, FALSE, exstyle); if (ok) { X = r.left; Y = r.top; @@ -1292,7 +1292,7 @@ void Fl_Window::resize(int X,int Y,int W,int H) { int resize_from_program = (this != resize_bug_fix); if (!resize_from_program) resize_bug_fix = 0; if (X != x() || Y != y()) { - set_flag(FL_FORCE_POSITION); + set_flag(FORCE_POSITION); } else { if (!is_a_resize) return; flags |= SWP_NOMOVE; @@ -1474,7 +1474,7 @@ Fl_X* Fl_X::make(Fl_Window* w) { wp += 2*bx; hp += 2*by+bt; } - if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { + if (!(w->flags() & Fl_Widget::FORCE_POSITION)) { xp = yp = CW_USEDEFAULT; } else { if (!Fl::grab()) { @@ -1557,7 +1557,7 @@ Fl_X* Fl_X::make(Fl_Window* w) { CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER, IID_IActiveIMMApp, (void**) &fl_aimm); if (fl_aimm) { - fl_aimm->Activate(true); + fl_aimm->Activate(TRUE); } } #endif // !__GNUC__ || __GNUC__ >= 3 @@ -1916,5 +1916,5 @@ void fl_cleanup_dc_list(void) { // clean up the list #endif // FL_DOXYGEN // -// End of "$Id: Fl_win32.cxx 6668 2009-02-21 10:18:47Z AlbrechtS $". +// End of "$Id: Fl_win32.cxx 6905 2009-09-27 12:06:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/Fl_x.cxx b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx index 9cb834a4b..468333831 100644 --- a/plugins/zynaddsubfx/fltk/src/Fl_x.cxx +++ b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_x.cxx 6767 2009-04-16 22:23:36Z AlbrechtS $" +// "$Id: Fl_x.cxx 6905 2009-09-27 12:06:35Z matt $" // // X specific code for the Fast Light Tool Kit (FLTK). // @@ -1352,7 +1352,7 @@ void Fl_Window::resize(int X,int Y,int W,int H) { int is_a_resize = (W != w() || H != h()); int resize_from_program = (this != resize_bug_fix); if (!resize_from_program) resize_bug_fix = 0; - if (is_a_move && resize_from_program) set_flag(FL_FORCE_POSITION); + if (is_a_move && resize_from_program) set_flag(FORCE_POSITION); else if (!is_a_resize && !is_a_move) return; if (is_a_resize) { Fl_Group::resize(X,Y,W,H); @@ -1430,7 +1430,7 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap) if (!win->parent() && !Fl::grab()) { // center windows in case window manager does not do anything: #ifdef FL_CENTER_WINDOWS - if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) { + if (!(win->flags() & Fl_Widget::FORCE_POSITION)) { win->x(X = scr_x+(scr_w-W)/2); win->y(Y = scr_y+(scr_h-H)/2); } @@ -1636,7 +1636,7 @@ void Fl_X::sendxjunk() { prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE } - if (w->flags() & Fl_Window::FL_FORCE_POSITION) { + if (w->flags() & Fl_Widget::FORCE_POSITION) { hints->flags |= USPosition; hints->x = w->x(); hints->y = w->y(); @@ -1741,5 +1741,5 @@ void Fl_Window::make_current() { #endif // -// End of "$Id: Fl_x.cxx 6767 2009-04-16 22:23:36Z AlbrechtS $". +// End of "$Id: Fl_x.cxx 6905 2009-09-27 12:06:35Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_ask.cxx b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx index 897f6d8f8..0abb379ad 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_ask.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_ask.cxx 6763 2009-04-13 22:47:21Z AlbrechtS $" +// "$Id: fl_ask.cxx 6869 2009-09-13 21:57:46Z AlbrechtS $" // // Standard dialog functions for the Fast Light Tool Kit (FLTK). // @@ -215,8 +215,7 @@ static int innards(const char* fmt, va_list ap, message_form->show(); // deactivate Fl::grab(), because it is incompatible with Fl::readqueue() Fl_Window* g = Fl::grab(); - if (g) // do an alternative grab to avoid floating menus, if possible - Fl::grab(message_form); + if (g) Fl::grab(0); int r = 0; for (;;) { Fl_Widget *o = Fl::readqueue(); @@ -461,5 +460,5 @@ const char *fl_password(const char *fmt, const char *defstr, ...) { /** @} */ // -// End of "$Id: fl_ask.cxx 6763 2009-04-13 22:47:21Z AlbrechtS $". +// End of "$Id: fl_ask.cxx 6869 2009-09-13 21:57:46Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx index 32d597cbe..6f8222ee0 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_boxtype.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_boxtype.cxx 6902 2009-09-27 11:06:56Z matt $" // // Box drawing code for the Fast Light Tool Kit (FLTK). // @@ -406,7 +406,7 @@ void Fl_Widget::draw_box() const { // if (t == FL_FLAT_BOX) return; // t += 2; // convert box to frame // } - draw_box((Fl_Boxtype)t, x_, y_, w_, h_, (Fl_Color)color_); + draw_box((Fl_Boxtype)t, x_, y_, w_, h_, color_); } /** Draws a box of type t, of color c at the widget's position and size. */ void Fl_Widget::draw_box(Fl_Boxtype t, Fl_Color c) const { @@ -420,5 +420,5 @@ void Fl_Widget::draw_box(Fl_Boxtype t, int X, int Y, int W, int H, Fl_Color c) c } // -// End of "$Id: fl_boxtype.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_boxtype.cxx 6902 2009-09-27 11:06:56Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_color.cxx b/plugins/zynaddsubfx/fltk/src/fl_color.cxx index f611d31ff..c1d182227 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_color.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_color.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_color.cxx 6716 2009-03-24 01:40:44Z fabien $" +// "$Id: fl_color.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $" // // Color functions for the Fast Light Tool Kit (FLTK). // @@ -484,5 +484,5 @@ Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { @} */ // -// End of "$Id: fl_color.cxx 6716 2009-03-24 01:40:44Z fabien $". +// End of "$Id: fl_color.cxx 6813 2009-07-01 07:32:14Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx index a1564628c..48ce3a9fe 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx @@ -241,7 +241,7 @@ fl_select_palette(void) fl_palette = CreatePalette(pPal); } if (fl_palette) { - SelectPalette(fl_gc, fl_palette, false); + SelectPalette(fl_gc, fl_palette, FALSE); RealizePalette(fl_gc); } return fl_palette; diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx index c65cec389..133bb7ae6 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx @@ -434,14 +434,14 @@ public: // df->pFiles = sizeof(DROPFILES); // df->pt.x = 0; // df->pt.y = 0; -// df->fNC = false; +// df->fNC = FALSE; // for (int i = 0; i < fl_selection_length[0]; i++) { // if (fl_selection_buffer[0][i] == '\n') { // fl_selection_buffer[0][i] = '\0'; // } // } // -// df->fWide = true; +// df->fWide = TRUE; // l = fl_utf2unicode((unsigned char*)fl_selection_buffer[0], // fl_selection_length[0], (xchar*)(((char*)pMem) // + sizeof(DROPFILES))); diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx index a501c27ee..5d8e57475 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw.cxx 6735 2009-04-01 22:11:57Z engelsman $" +// "$Id: fl_draw.cxx 6845 2009-08-28 20:14:41Z greg.ercolano $" // // Label drawing code for the Fast Light Tool Kit (FLTK). // @@ -422,6 +422,31 @@ void fl_measure(const char* str, int& w, int& h, int draw_symbols) { h = lines*h; } +/** + This function returns the actual height of the specified \p font + and \p size. Normally the font height should always be 'size', + but with the advent of XFT, there are (currently) complexities + that seem to only be solved by asking the font what its actual + font height is. (See STR#2115) + + This function was originally undocumented in 1.1.x, and was used + only by Fl_Text_Display. We're now documenting it in 1.3.x so that + apps that need precise height info can get it with this function. + + \returns the height of the font in pixels. + + \todo In the future, when the XFT issues are resolved, this function + should simply return the 'size' value. +*/ +int fl_height(int font, int size) { + if ( font == fl_font() && size == fl_size() ) return(fl_height()); + int tf = fl_font(), ts = fl_size(); // save + fl_font(font,size); + int height = fl_height(); + fl_font(tf,ts); // restore + return(height); +} + // -// End of "$Id: fl_draw.cxx 6735 2009-04-01 22:11:57Z engelsman $". +// End of "$Id: fl_draw.cxx 6845 2009-08-28 20:14:41Z greg.ercolano $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx index 15dce417c..d94e8b3b2 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image_win32.cxx 6616 2009-01-01 21:28:26Z matt $" +// "$Id: fl_draw_image_win32.cxx 6844 2009-08-24 19:55:29Z AlbrechtS $" // // WIN32 image drawing code for the Fast Light Tool Kit (FLTK). // @@ -115,8 +115,10 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, int delta, int linedelta, int depth, Fl_Draw_Image_Cb cb, void* userdata) { + char indexed = 0; + #if USE_COLORMAP - char indexed = (fl_palette != 0); + indexed = (fl_palette != 0); #endif if (depth==0) depth = 3; @@ -319,5 +321,5 @@ void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { } // -// End of "$Id: fl_draw_image_win32.cxx 6616 2009-01-01 21:28:26Z matt $". +// End of "$Id: fl_draw_image_win32.cxx 6844 2009-08-24 19:55:29Z AlbrechtS $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx index db7ef6b3c..fc708a8ca 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx @@ -44,8 +44,8 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize size) { fl_angle_*10, // base-line orientation angle weight, italic, - false, // underline attribute flag - false, // strikeout attribute flag + FALSE, // underline attribute flag + FALSE, // strikeout attribute flag DEFAULT_CHARSET, // character set identifier OUT_DEFAULT_PRECIS, // output precision CLIP_DEFAULT_PRECIS,// clipping precision diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx index c101675a3..a7d43fcd4 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_font_xft.cxx 6779 2009-04-24 09:28:30Z yuri $" +// "$Id: fl_font_xft.cxx 6862 2009-09-13 10:15:42Z matt $" // // Xft font code for the Fast Light Tool Kit (FLTK). // @@ -635,5 +635,5 @@ void fl_rtl_draw(const char* c, int n, int x, int y) { #endif // -// End of "$Id: fl_font_xft.cxx 6779 2009-04-24 09:28:30Z yuri $" +// End of "$Id: fl_font_xft.cxx 6862 2009-09-13 10:15:42Z matt $" // diff --git a/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx index ea97de6c9..e882e1936 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_open_uri.cxx 6641 2009-01-20 11:10:29Z fabien $" +// "$Id: fl_open_uri.cxx 6901 2009-09-26 13:56:04Z matt $" // // fl_open_uri() code for FLTK. // @@ -117,9 +117,9 @@ fl_open_uri(const char *uri, char *msg, int msglen) { #elif defined(__APPLE__) char *argv[3]; // Command-line arguments - argv[0] = "open"; - argv[1] = (char *)uri; - argv[2] = 0; + argv[0] = (char*)"open"; + argv[1] = (char*)uri; + argv[2] = (char*)0; if (msg) snprintf(msg, msglen, "open %s", uri); @@ -364,5 +364,5 @@ int main(int argc, char **argv) { // -// End of "$Id: fl_open_uri.cxx 6641 2009-01-20 11:10:29Z fabien $". +// End of "$Id: fl_open_uri.cxx 6901 2009-09-26 13:56:04Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx index f2f400d8a..56b03241d 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx +++ b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_shortcut.cxx 6760 2009-04-13 11:32:58Z matt $" +// "$Id: fl_shortcut.cxx 6878 2009-09-17 22:12:24Z matt $" // // Shortcut support routines for the Fast Light Tool Kit (FLTK). // @@ -39,7 +39,7 @@ // It also checks against the first character of Fl::event_text(), // and zero for FL_SHIFT means "don't care". // This allows punctuation shortcuts like "#" to work (rather than -// calling it "shift+3") +// calling it "shift+3" on a US keyboard) #include #include @@ -58,19 +58,12 @@ be confused with Fl_Widget::test_shortcut(). */ -int Fl::test_shortcut(int shortcut) { +int Fl::test_shortcut(Fl_Shortcut shortcut) { if (!shortcut) return 0; - int v = shortcut & 0xffff; -#ifdef __APPLE__ - if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { -#else - // most X11 use MSWindows Latin-1 if set to Western encoding, so 0x80 to 0xa0 are defined - if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { -#endif - if (isupper(v)) { - shortcut |= FL_SHIFT; - } + Fl_Char v = shortcut & FL_KEY_MASK; + if (fl_tolower(v)!=v) { + shortcut |= FL_SHIFT; } int shift = Fl::event_state(); @@ -81,17 +74,18 @@ int Fl::test_shortcut(int shortcut) { // these three must always be correct: if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0; - int key = shortcut & 0xffff; + Fl_Char key = shortcut & FL_KEY_MASK; // if shift is also correct, check for exactly equal keysyms: if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1; - // try matching ascii, ignore shift: - if (key == event_text()[0]) return 1; + // try matching utf8, ignore shift: + Fl_Char firstChar = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + if (key==firstChar) return 1; // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'): if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F - && event_text()[0]==(key^0x40)) return 1; + && firstChar==(key^0x40)) return 1; // firstChar should be within a-z return 0; } @@ -180,7 +174,7 @@ static Keyname table[] = { \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers \return a pointer to a static buffer containing human readable text for the shortcut */ -const char* fl_shortcut_label(int shortcut) { +const char* fl_shortcut_label(Fl_Shortcut shortcut) { return fl_shortcut_label(shortcut, 0L); } @@ -190,23 +184,17 @@ const char* fl_shortcut_label(int shortcut) { \param [in] shortcut the integer value containing the ascii charcter or extended keystroke plus modifiers \param [in] eom if this pointer is set, it will receive a pointer to the end of the modifier text \return a pointer to a static buffer containing human readable text for the shortcut - \see fl_shortcut_label(int shortcut) + \see fl_shortcut_label(Fl_Shortcut shortcut) */ -const char* fl_shortcut_label(int shortcut, const char **eom) { +const char* fl_shortcut_label(Fl_Shortcut shortcut, const char **eom) { static char buf[20]; char *p = buf; if (eom) *eom = p; if (!shortcut) {*p = 0; return buf;} // fix upper case shortcuts - int v = shortcut & 0xffff; -#ifdef __APPLE__ - if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { -#else - if (v > 32 && v < 0x7f || v >= 0xa0 && v <= 0xff) { -#endif - if (isupper(v)) { - shortcut |= FL_SHIFT; - } + Fl_Char v = shortcut & FL_KEY_MASK; + if (fl_tolower(v)!=v) { + shortcut |= FL_SHIFT; } #ifdef __APPLE__ // this column contains utf8 characters - v @@ -221,7 +209,7 @@ const char* fl_shortcut_label(int shortcut, const char **eom) { if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} #endif // __APPLE__ if (eom) *eom = p; - int key = shortcut & 0xFFFF; + Fl_Char key = shortcut & FL_KEY_MASK; #if defined(WIN32) || defined(__APPLE__) // if not X if (key >= FL_F && key <= FL_F_Last) { *p++ = 'F'; @@ -234,7 +222,7 @@ const char* fl_shortcut_label(int shortcut, const char **eom) { while (a < b) { int c = (a+b)/2; if (table[c].key == key) { - if (p > buf) { + if (p > buf) { strcpy(p,table[c].name); return buf; } else { @@ -252,7 +240,7 @@ const char* fl_shortcut_label(int shortcut, const char **eom) { *p++ = uchar(key & 127); } else { // if none found, use the keystroke as a match: - *p++ = uchar(toupper(key & 255)); + p += fl_utf8encode(fl_toupper(key), p); } } *p = 0; @@ -262,7 +250,11 @@ const char* fl_shortcut_label(int shortcut, const char **eom) { if (key == FL_Enter || key == '\r') q="Enter"; // don't use Xlib's "Return": else if (key > 32 && key < 0x100) q = 0; else q = XKeysymToString(key); - if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;} + if (!q) { + p += fl_utf8encode(fl_toupper(key), p); + *p = 0; + return buf; + } if (p > buf) { strcpy(p,q); return buf; @@ -278,9 +270,9 @@ const char* fl_shortcut_label(int shortcut, const char **eom) { /** Emulation of XForms named shortcuts. */ -int fl_old_shortcut(const char* s) { +Fl_Shortcut fl_old_shortcut(const char* s) { if (!s || !*s) return 0; - int n = 0; + Fl_Shortcut n = 0; if (*s == '#') {n |= FL_ALT; s++;} if (*s == '+') {n |= FL_SHIFT; s++;} if (*s == '^') {n |= FL_CTRL; s++;} @@ -290,14 +282,14 @@ int fl_old_shortcut(const char* s) { // Tests for &x shortcuts in button labels: -char Fl_Widget::label_shortcut(const char *t) { +Fl_Shortcut Fl_Widget::label_shortcut(const char *t) { if (!t) return 0; for (;;) { if (*t==0) return 0; if (*t=='&') { - char s = t[1]; + Fl_Shortcut s = fl_utf8decode(t+1, 0, 0); if (s==0) return 0; - else if (s=='&') t++; + else if (s==(Fl_Char)'&') t++; else return s; } t++; @@ -309,8 +301,9 @@ int Fl_Widget::test_shortcut(const char *t) { // on MSWindows, users expect shortcuts to work only when the Alt modifier is pressed if (Fl::event_state(FL_ALT)==0) return 0; #endif - char c = Fl::event_text()[0]; - if (!c || !t) return 0; + if (!t) return 0; + Fl_Shortcut c = fl_utf8decode(Fl::event_text(), Fl::event_text()+Fl::event_length(), 0); + if (!c) return 0; if (c == label_shortcut(t)) return 1; return 0; @@ -322,5 +315,5 @@ int Fl_Widget::test_shortcut() { } // -// End of "$Id: fl_shortcut.cxx 6760 2009-04-13 11:32:58Z matt $". +// End of "$Id: fl_shortcut.cxx 6878 2009-09-17 22:12:24Z matt $". // diff --git a/plugins/zynaddsubfx/fltk/src/fl_utf.c b/plugins/zynaddsubfx/fltk/src/fl_utf.c index 1362ef755..cc2059ce5 100644 --- a/plugins/zynaddsubfx/fltk/src/fl_utf.c +++ b/plugins/zynaddsubfx/fltk/src/fl_utf.c @@ -138,11 +138,11 @@ unsigned fl_utf8decode(const char* p, const char* end, int* len) { unsigned char c = *(unsigned char*)p; if (c < 0x80) { - *len = 1; + if (len) *len = 1; return c; #if ERRORS_TO_CP1252 } else if (c < 0xa0) { - *len = 1; + if (len) *len = 1; return cp1252[c-0x80]; #endif } else if (c < 0xc2) { @@ -150,7 +150,7 @@ unsigned fl_utf8decode(const char* p, const char* end, int* len) } if (p+1 >= end || (p[1]&0xc0) != 0x80) goto FAIL; if (c < 0xe0) { - *len = 2; + if (len) *len = 2; return ((p[0] & 0x1f) << 6) + ((p[1] & 0x3f)); @@ -171,7 +171,7 @@ unsigned fl_utf8decode(const char* p, const char* end, int* len) } else if (c < 0xf0) { UTF8_3: if (p+2 >= end || (p[2]&0xc0) != 0x80) goto FAIL; - *len = 3; + if (len) *len = 3; return ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + @@ -182,7 +182,7 @@ unsigned fl_utf8decode(const char* p, const char* end, int* len) } else if (c < 0xf4) { UTF8_4: if (p+3 >= end || (p[2]&0xc0) != 0x80 || (p[3]&0xc0) != 0x80) goto FAIL; - *len = 4; + if (len) *len = 4; #if STRICT_RFC3629 /* RFC 3629 says all codes ending in fffe or ffff are illegal: */ if ((p[1]&0xf)==0xf && @@ -199,7 +199,7 @@ unsigned fl_utf8decode(const char* p, const char* end, int* len) goto UTF8_4; } else { FAIL: - *len = 1; + if (len) *len = 1; #if ERRORS_TO_ISO8859_1 return c; #else diff --git a/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx index adfaa1dd9..fa7e1e139 100644 --- a/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx +++ b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx @@ -58,7 +58,7 @@ static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorIn static RECT screens[16]; static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) { - if (num_screens >= 16) return true; + if (num_screens >= 16) return TRUE; MONITORINFO mi; mi.cbSize = sizeof(mi); @@ -69,7 +69,7 @@ static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) { screens[num_screens] = mi.rcWork; num_screens ++; } - return true; + return TRUE; } static void screen_init() { diff --git a/plugins/zynaddsubfx/src/Controls/Control.cpp b/plugins/zynaddsubfx/src/Controls/Control.cpp index 36792fc63..d7cf5cb9d 100644 --- a/plugins/zynaddsubfx/src/Controls/Control.cpp +++ b/plugins/zynaddsubfx/src/Controls/Control.cpp @@ -22,19 +22,19 @@ #include "Control.h" Control::Control(char ndefaultval) - :defaultval(ndefaultval),lockqueue(-1),locked(false) + :defaultval(ndefaultval), lockqueue(-1), locked(false) {} void Control::lock() { - locked=true; - lockqueue=-1; + locked = true; + lockqueue = -1; } void Control::ulock() { - if (locked&&lockqueue>=0) + if(locked && (lockqueue >= 0)) setmVal(lockqueue); - locked=false; + locked = false; } diff --git a/plugins/zynaddsubfx/src/Controls/Control.h b/plugins/zynaddsubfx/src/Controls/Control.h index 2b6eaea77..931a4745c 100644 --- a/plugins/zynaddsubfx/src/Controls/Control.h +++ b/plugins/zynaddsubfx/src/Controls/Control.h @@ -25,33 +25,33 @@ /**A control for a parameter within the program*/ class Control { -public: - Control(char ndefaultval);/**\todo create proper initialization list*/ - ~Control() {}; - /**Return the string, which represents the internal value - * @return a string representation of the current value*/ - virtual std::string getString()const=0; - /**Set the Control to the given value - * @param nval A number 0-127*/ - virtual void setmVal(char nval)=0; - /**Return the midi value (aka the char) - * @return the current value*/ - virtual char getmVal()const=0; - /** Will lock the Control until it is ulocked - * - * Locking a Control will Stop it from having - * its internal data altered*/ - void lock(); - /** Will unlock the Control - * - * This will also update the Control - * if something attempted to update it while it was locked*/ - void ulock(); -private: - char defaultval;/** DelayCtl::DelayCtl() - :Control(64),value(64/127.0*1.5) {} /**\todo finishme*/ + :Control(64), value(64 / 127.0 * 1.5) {} /**\todo finishme*/ std::string DelayCtl::getString() const { std::ostringstream buf; - buf< #include "AnalogFilter.h" -AnalogFilter::AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +AnalogFilter::AnalogFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - for (int i=0;i<3;i++) { - oldc[i]=0.0; - oldd[i]=0.0; - c[i]=0.0; - d[i]=0.0; - }; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + for(int i = 0; i < 3; i++) { + oldc[i] = 0.0; + oldd[i] = 0.0; + c[i] = 0.0; + d[i] = 0.0; + } + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - firsttime=0; - abovenq=0; - oldabovenq=0; - setfreq_and_q(Ffreq,Fq); - firsttime=1; - d[0]=0;//this is not used - outgain=1.0; -}; + firsttime = 0; + abovenq = 0; + oldabovenq = 0; + setfreq_and_q(Ffreq, Fq); + firsttime = 1; + d[0] = 0; //this is not used + outgain = 1.0; +} AnalogFilter::~AnalogFilter() -{ -}; +{} void AnalogFilter::cleanup() { - for (int i=0;ifreq; - if (freq>(SAMPLE_RATE/2-500.0)) { - freq=SAMPLE_RATE/2-500.0; - zerocoefs=1; - }; - if (freq<0.1) freq=0.1; + REALTYPE freq = this->freq; + if(freq > (SAMPLE_RATE / 2 - 500.0)) { + freq = SAMPLE_RATE / 2 - 500.0; + zerocoefs = 1; + } + if(freq < 0.1) + freq = 0.1; //do not allow bogus Q - if (q<0.0) q=0.0; - REALTYPE tmpq,tmpgain; - if (stages==0) { - tmpq=q; - tmpgain=gain; - } else { - tmpq=(q>1.0 ? pow(q,1.0/(stages+1)) : q); - tmpgain=pow(gain,1.0/(stages+1)); - }; + if(q < 0.0) + q = 0.0; + REALTYPE tmpq, tmpgain; + if(stages == 0) { + tmpq = q; + tmpgain = gain; + } + else { + tmpq = (q > 1.0 ? pow(q, 1.0 / (stages + 1)) : q); + tmpgain = pow(gain, 1.0 / (stages + 1)); + } //most of theese are implementations of //the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson //The original location of the Cookbook is: //http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt - switch (type) { - case 0://LPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=1.0-tmp; - c[1]=0.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + switch(type) { + case 0: //LPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = 1.0 - tmp; + c[1] = 0.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 1://HPF 1 pole - if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); - else tmp=0.0; - c[0]=(1.0+tmp)/2.0; - c[1]=-(1.0+tmp)/2.0; - c[2]=0.0; - d[1]=tmp; - d[2]=0.0; - order=1; + case 1: //HPF 1 pole + if(zerocoefs == 0) + tmp = exp(-2.0 * PI * freq / SAMPLE_RATE); + else + tmp = 0.0; + c[0] = (1.0 + tmp) / 2.0; + c[1] = -(1.0 + tmp) / 2.0; + c[2] = 0.0; + d[1] = tmp; + d[2] = 0.0; + order = 1; break; - case 2://LPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0-cs)/2.0/tmp; - c[1]=(1.0-cs)/tmp; - c[2]=(1.0-cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 2: //LPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 - cs) / 2.0 / tmp; + c[1] = (1.0 - cs) / tmp; + c[2] = (1.0 - cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 3://HPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=(1.0+cs)/2.0/tmp; - c[1]=-(1.0+cs)/tmp; - c[2]=(1.0+cs)/2.0/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 3: //HPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = (1.0 + cs) / 2.0 / tmp; + c[1] = -(1.0 + cs) / tmp; + c[2] = (1.0 + cs) / 2.0 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 4://BPF 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*tmpq); - tmp=1+alpha; - c[0]=alpha/tmp*sqrt(tmpq+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(tmpq+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=0.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 4: //BPF 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * tmpq); + tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(tmpq + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(tmpq + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 0.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 5://NOTCH 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*sqrt(tmpq)); - tmp=1+alpha; - c[0]=1/tmp; - c[1]=-2*cs/tmp; - c[2]=1/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 5: //NOTCH 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * sqrt(tmpq)); + tmp = 1 + alpha; + c[0] = 1 / tmp; + c[1] = -2 * cs / tmp; + c[2] = 1 / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 6://PEAK (2 poles) - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq*=3.0; - alpha=sn/(2*tmpq); - tmp=1+alpha/tmpgain; - c[0]=(1.0+alpha*tmpgain)/tmp; - c[1]=(-2.0*cs)/tmp; - c[2]=(1.0-alpha*tmpgain)/tmp; - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha/tmpgain)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + case 6: //PEAK (2 poles) + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq *= 3.0; + alpha = sn / (2 * tmpq); + tmp = 1 + alpha / tmpgain; + c[0] = (1.0 + alpha * tmpgain) / tmp; + c[1] = (-2.0 * cs) / tmp; + c[2] = (1.0 - alpha * tmpgain) / tmp; + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha / tmpgain) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 7://Low Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn; + case 7: //Low Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) + (tmpgain - 1.0) * cs + beta * sn; - c[0]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=2.0*tmpgain*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=-2.0*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=tmpgain; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + c[0] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = 2.0 * tmpgain + * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = -2.0 * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = tmpgain; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - case 8://High Shelf - 2 poles - if (zerocoefs==0) { - omega=2*PI*freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - tmpq=sqrt(tmpq); - alpha=sn/(2*tmpq); - beta=sqrt(tmpgain)/tmpq; - tmp=(tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn; + case 8: //High Shelf - 2 poles + if(zerocoefs == 0) { + omega = 2 * PI * freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + tmpq = sqrt(tmpq); + alpha = sn / (2 * tmpq); + beta = sqrt(tmpgain) / tmpq; + tmp = (tmpgain + 1.0) - (tmpgain - 1.0) * cs + beta * sn; - c[0]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn)/tmp; - c[1]=-2.0*tmpgain*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp; - c[2]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp; - d[1]=2.0*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp*(-1); - d[2]=((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); - } else { - c[0]=1.0; - c[1]=0.0; - c[2]=0.0; - d[1]=0.0; - d[2]=0.0; - }; - order=2; + c[0] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs + beta * sn) / tmp; + c[1] = -2.0 * tmpgain + * ((tmpgain - 1.0) + (tmpgain + 1.0) * cs) / tmp; + c[2] = tmpgain + * ((tmpgain + + 1.0) + (tmpgain - 1.0) * cs - beta * sn) / tmp; + d[1] = 2.0 * ((tmpgain - 1.0) - (tmpgain + 1.0) * cs) / tmp * (-1); + d[2] = + ((tmpgain + + 1.0) - (tmpgain - 1.0) * cs - beta * sn) / tmp * (-1); + } + else { + c[0] = 1.0; + c[1] = 0.0; + c[2] = 0.0; + d[1] = 0.0; + d[2] = 0.0; + } + order = 2; break; - default://wrong type - type=0; + default: //wrong type + type = 0; computefiltercoefs(); break; - }; -}; + } +} void AnalogFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); - int nyquistthresh=(abovenq^oldabovenq); + int nyquistthresh = (abovenq ^ oldabovenq); - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - for (int i=0;i<3;i++) { - oldc[i]=c[i]; - oldd[i]=d[i]; - }; - for (int i=0;i 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + for(int i = 0; i < 3; i++) { + oldc[i] = c[i]; + oldd[i] = d[i]; + } + for(int i = 0; i < MAX_FILTER_STAGES + 1; i++) { + oldx[i] = x[i]; + oldy[i] = y[i]; + } + if(firsttime == 0) + needsinterpolation = 1; + } + freq = frequency; computefiltercoefs(); - firsttime=0; + firsttime = 0; +} -}; - -void AnalogFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void AnalogFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void AnalogFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void AnalogFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void AnalogFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void AnalogFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void AnalogFilter::singlefilterout(REALTYPE *smp,fstage &x,fstage &y,REALTYPE *c,REALTYPE *d) +void AnalogFilter::singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d) { - int i; + int i; REALTYPE y0; - if (order==1) {//First order filter - for (i=0;i1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + void singlefilterout(REALTYPE *smp, + fstage &x, + fstage &y, + REALTYPE *c, + REALTYPE *d); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters - int order;//the order of the filter (number of poles) + int order; //the order of the filter (number of poles) - REALTYPE c[3],d[3];//coefficients + REALTYPE c[3], d[3]; //coefficients - REALTYPE oldc[3],oldd[3];//old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) + REALTYPE oldc[3], oldd[3]; //old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) - REALTYPE xd[3],yd[3];//used if the filter is applied more times - int needsinterpolation,firsttime;/**\todo see if bool works for these*/ - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq;//if the last time was above nyquist (used to see if it needs interpolation) + REALTYPE xd[3], yd[3]; //used if the filter is applied more times + int needsinterpolation, firsttime; /**\todo see if bool works for these*/ + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; //if the last time was above nyquist (used to see if it needs interpolation) }; diff --git a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt index 8169235e0..c13cd316c 100644 --- a/plugins/zynaddsubfx/src/DSP/CMakeLists.txt +++ b/plugins/zynaddsubfx/src/DSP/CMakeLists.txt @@ -4,6 +4,7 @@ set(zynaddsubfx_dsp_SRCS Filter.cpp FormantFilter.cpp SVFilter.cpp + Unison.cpp ) add_library(zynaddsubfx_dsp STATIC diff --git a/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp b/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp index 7e18ae534..d93c0c40c 100644 --- a/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp +++ b/plugins/zynaddsubfx/src/DSP/FFTwrapper.cpp @@ -25,17 +25,29 @@ FFTwrapper::FFTwrapper(int fftsize_) { - fftsize=fftsize_; - tmpfftdata1=new fftw_real[fftsize]; - tmpfftdata2=new fftw_real[fftsize]; + fftsize = fftsize_; + tmpfftdata1 = new fftw_real[fftsize]; + tmpfftdata2 = new fftw_real[fftsize]; #ifdef FFTW_VERSION_2 - planfftw=rfftw_create_plan(fftsize,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE|FFTW_IN_PLACE); - planfftw_inv=rfftw_create_plan(fftsize,FFTW_COMPLEX_TO_REAL,FFTW_ESTIMATE|FFTW_IN_PLACE); + planfftw = rfftw_create_plan(fftsize, + FFTW_REAL_TO_COMPLEX, + FFTW_ESTIMATE | FFTW_IN_PLACE); + planfftw_inv = rfftw_create_plan(fftsize, + FFTW_COMPLEX_TO_REAL, + FFTW_ESTIMATE | FFTW_IN_PLACE); #else - planfftw=fftwf_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE); - planfftw_inv=fftwf_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE); + planfftw = fftwf_plan_r2r_1d(fftsize, + tmpfftdata1, + tmpfftdata1, + FFTW_R2HC, + FFTW_ESTIMATE); + planfftw_inv = fftwf_plan_r2r_1d(fftsize, + tmpfftdata2, + tmpfftdata2, + FFTW_HC2R, + FFTW_ESTIMATE); #endif -}; +} FFTwrapper::~FFTwrapper() { @@ -49,52 +61,76 @@ FFTwrapper::~FFTwrapper() delete [] tmpfftdata1; delete [] tmpfftdata2; -}; +} /* * do the Fast Fourier Transform */ -void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs) +void FFTwrapper::smps2freqs(REALTYPE *smps, FFTFREQS freqs) { #ifdef FFTW_VERSION_2 - for (int i=0;ic = new REALTYPE[size]; + f->s = new REALTYPE[size]; + for(int i = 0; i < size; i++) { + f->c[i] = 0.0; + f->s[i] = 0.0; + } +} + +void deleteFFTFREQS(FFTFREQS *f) +{ + delete[] f->c; + delete[] f->s; + f->c = f->s = NULL; +} diff --git a/plugins/zynaddsubfx/src/DSP/FFTwrapper.h b/plugins/zynaddsubfx/src/DSP/FFTwrapper.h index f2915f490..17d40805a 100644 --- a/plugins/zynaddsubfx/src/DSP/FFTwrapper.h +++ b/plugins/zynaddsubfx/src/DSP/FFTwrapper.h @@ -47,21 +47,24 @@ Hope all goes right." */ /**A wrapper for the FFTW library (Fast Fourier Transforms)*/ class FFTwrapper { -public: - /**Constructor - * @param fftsize The size of samples to be fed to fftw*/ - FFTwrapper(int fftsize_); - /**Destructor*/ - ~FFTwrapper(); - /**Convert Samples to Frequencies using Fourier Transform - * @param smps Pointer to Samples to be converted; has length fftsize_ - * @param freqs Structure FFTFREQS which stores the frequencies*/ - void smps2freqs(REALTYPE *smps,FFTFREQS freqs); - void freqs2smps(FFTFREQS freqs,REALTYPE *smps); -private: - int fftsize; - fftw_real *tmpfftdata1,*tmpfftdata2; - rfftw_plan planfftw,planfftw_inv; + public: + /**Constructor + * @param fftsize The size of samples to be fed to fftw*/ + FFTwrapper(int fftsize_); + /**Destructor*/ + ~FFTwrapper(); + /**Convert Samples to Frequencies using Fourier Transform + * @param smps Pointer to Samples to be converted; has length fftsize_ + * @param freqs Structure FFTFREQS which stores the frequencies*/ + void smps2freqs(REALTYPE *smps, FFTFREQS freqs); + void freqs2smps(FFTFREQS freqs, REALTYPE *smps); + private: + int fftsize; + fftw_real *tmpfftdata1, *tmpfftdata2; + rfftw_plan planfftw, planfftw_inv; }; + +void newFFTFREQS(FFTFREQS *f, int size); +void deleteFFTFREQS(FFTFREQS *f); #endif diff --git a/plugins/zynaddsubfx/src/DSP/Filter.cpp b/plugins/zynaddsubfx/src/DSP/Filter.cpp index f94a34214..d95abe448 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter.cpp +++ b/plugins/zynaddsubfx/src/DSP/Filter.cpp @@ -27,56 +27,61 @@ Filter::Filter(FilterParams *pars) { - unsigned char Ftype=pars->Ptype; - unsigned char Fstages=pars->Pstages; + unsigned char Ftype = pars->Ptype; + unsigned char Fstages = pars->Pstages; - category=pars->Pcategory; + category = pars->Pcategory; - switch (category) { + switch(category) { case 1: - filter=new FormantFilter(pars); + filter = new FormantFilter(pars); break; case 2: - filter=new SVFilter(Ftype,1000.0,pars->getq(),Fstages); - filter->outgain=dB2rap(pars->getgain()); - if (filter->outgain>1.0) filter->outgain=sqrt(filter->outgain); + filter = new SVFilter(Ftype, 1000.0, pars->getq(), Fstages); + filter->outgain = dB2rap(pars->getgain()); + if(filter->outgain > 1.0) + filter->outgain = sqrt(filter->outgain); break; default: - filter=new AnalogFilter(Ftype,1000.0,pars->getq(),Fstages); - if ((Ftype>=6)&&(Ftype<=8)) filter->setgain(pars->getgain()); - else filter->outgain=dB2rap(pars->getgain()); + filter = new AnalogFilter(Ftype, 1000.0, pars->getq(), Fstages); + if((Ftype >= 6) && (Ftype <= 8)) + filter->setgain(pars->getgain()); + else + filter->outgain = dB2rap(pars->getgain()); break; - }; -}; + } +} Filter::~Filter() { delete (filter); -}; +} void Filter::filterout(REALTYPE *smp) { filter->filterout(smp); -}; +} void Filter::setfreq(REALTYPE frequency) { filter->setfreq(frequency); -}; +} -void Filter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void Filter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - filter->setfreq_and_q(frequency,q_); -}; + filter->setfreq_and_q(frequency, q_); +} void Filter::setq(REALTYPE q_) { filter->setq(q_); -}; +} REALTYPE Filter::getrealfreq(REALTYPE freqpitch) { - if ((category==0)||(category==2)) return(pow(2.0,freqpitch+9.96578428));//log2(1000)=9.95748 - else return(freqpitch); -}; + if((category == 0) || (category == 2)) + return pow(2.0, freqpitch + 9.96578428); //log2(1000)=9.95748 + else + return freqpitch; +} diff --git a/plugins/zynaddsubfx/src/DSP/Filter.h b/plugins/zynaddsubfx/src/DSP/Filter.h index 42bef55ce..b8f568b21 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter.h +++ b/plugins/zynaddsubfx/src/DSP/Filter.h @@ -33,18 +33,18 @@ class Filter { -public: - Filter(FilterParams *pars); - ~Filter(); - void filterout(REALTYPE *smp); - void setfreq(REALTYPE frequency); - void setfreq_and_q(REALTYPE frequency,REALTYPE q_); - void setq(REALTYPE q_); + public: + Filter(FilterParams *pars); + ~Filter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency, REALTYPE q_); + void setq(REALTYPE q_); - REALTYPE getrealfreq(REALTYPE freqpitch); -private: - Filter_ *filter; - unsigned char category; + REALTYPE getrealfreq(REALTYPE freqpitch); + private: + Filter_ *filter; + unsigned char category; }; diff --git a/plugins/zynaddsubfx/src/DSP/Filter_.h b/plugins/zynaddsubfx/src/DSP/Filter_.h index b3f2badc1..b577193f3 100644 --- a/plugins/zynaddsubfx/src/DSP/Filter_.h +++ b/plugins/zynaddsubfx/src/DSP/Filter_.h @@ -27,15 +27,15 @@ class Filter_ { -public: - virtual ~Filter_() {}; - virtual void filterout(REALTYPE *smp)=0; - virtual void setfreq(REALTYPE frequency)=0; - virtual void setfreq_and_q(REALTYPE frequency,REALTYPE q_)=0; - virtual void setq(REALTYPE q_)=0; - virtual void setgain(REALTYPE dBgain) {}; - REALTYPE outgain; -private: + public: + virtual ~Filter_() {} + virtual void filterout(REALTYPE *smp) = 0; + virtual void setfreq(REALTYPE frequency) = 0; + virtual void setfreq_and_q(REALTYPE frequency, REALTYPE q_) = 0; + virtual void setq(REALTYPE q_) = 0; + virtual void setgain(REALTYPE dBgain) {} + REALTYPE outgain; + private: }; diff --git a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp index 297285648..39c1002d9 100644 --- a/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp +++ b/plugins/zynaddsubfx/src/DSP/FormantFilter.cpp @@ -26,151 +26,202 @@ FormantFilter::FormantFilter(FilterParams *pars) { - numformants=pars->Pnumformants; - for (int i=0;iPstages); + numformants = pars->Pnumformants; + for(int i = 0; i < numformants; i++) + formant[i] = new AnalogFilter(4 /*BPF*/, 1000.0, 10.0, pars->Pstages); cleanup(); - inbuffer=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + inbuffer = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpbuf = new REALTYPE [SOUND_BUFFER_SIZE]; - for (int j=0;jgetformantfreq(pars->Pvowels[j].formants[i].freq); - formantpar[j][i].amp=pars->getformantamp(pars->Pvowels[j].formants[i].amp); - formantpar[j][i].q=pars->getformantq(pars->Pvowels[j].formants[i].q); - }; - for (int i=0;igetformantfreq( + pars->Pvowels[j].formants[i].freq); + formantpar[j][i].amp = pars->getformantamp( + pars->Pvowels[j].formants[i].amp); + formantpar[j][i].q = pars->getformantq( + pars->Pvowels[j].formants[i].q); + } + ; + for(int i = 0; i < FF_MAX_FORMANTS; i++) + oldformantamp[i] = 1.0; + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = 1000.0; + currentformants[i].amp = 1.0; + currentformants[i].q = 2.0; + } - formantslowness=pow(1.0-(pars->Pformantslowness/128.0),3.0); + formantslowness = pow(1.0 - (pars->Pformantslowness / 128.0), 3.0); - sequencesize=pars->Psequencesize; - if (sequencesize==0) sequencesize=1; - for (int k=0;kPsequence[k].nvowel; + sequencesize = pars->Psequencesize; + if(sequencesize == 0) + sequencesize = 1; + for(int k = 0; k < sequencesize; k++) + sequence[k].nvowel = pars->Psequence[k].nvowel; - vowelclearness=pow(10.0,(pars->Pvowelclearness-32.0)/48.0); + vowelclearness = pow(10.0, (pars->Pvowelclearness - 32.0) / 48.0); - sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); - if (pars->Psequencereversed) sequencestretch*= -1.0; + sequencestretch = pow(0.1, (pars->Psequencestretch - 32.0) / 48.0); + if(pars->Psequencereversed) + sequencestretch *= -1.0; - outgain=dB2rap(pars->getgain()); + outgain = dB2rap(pars->getgain()); - oldinput=-1.0; - Qfactor=1.0; - oldQfactor=Qfactor; - firsttime=1; -}; + oldinput = -1.0; + Qfactor = 1.0; + oldQfactor = Qfactor; + firsttime = 1; +} FormantFilter::~FormantFilter() { - for (int i=0;icleanup(); -}; + for(int i = 0; i < numformants; i++) + formant[i]->cleanup(); +} void FormantFilter::setpos(REALTYPE input) { - int p1,p2; + int p1, p2; - if (firsttime!=0) slowinput=input; - else slowinput=slowinput*(1.0-formantslowness)+input*formantslowness; + if(firsttime != 0) + slowinput = input; + else + slowinput = slowinput + * (1.0 - formantslowness) + input * formantslowness; - if ((fabs(oldinput-input)<0.001)&&(fabs(slowinput-input)<0.001)&& - (fabs(Qfactor-oldQfactor)<0.001)) { + if((fabs(oldinput - input) < 0.001) && (fabs(slowinput - input) < 0.001) + && (fabs(Qfactor - oldQfactor) < 0.001)) { // oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente - firsttime=0; + firsttime = 0; return; - } else oldinput=input; + } + else + oldinput = input; - REALTYPE pos=fmod(input*sequencestretch,1.0); - if (pos<0.0) pos+=1.0; + REALTYPE pos = fmod(input * sequencestretch, 1.0); + if(pos < 0.0) + pos += 1.0; - F2I(pos*sequencesize,p2); - p1=p2-1; - if (p1<0) p1+=sequencesize; + F2I(pos * sequencesize, p2); + p1 = p2 - 1; + if(p1 < 0) + p1 += sequencesize; - pos=fmod(pos*sequencesize,1.0); - if (pos<0.0) pos=0.0; - else if (pos>1.0) pos=1.0; - pos=(atan((pos*2.0-1.0)*vowelclearness)/atan(vowelclearness)+1.0)*0.5; + pos = fmod(pos * sequencesize, 1.0); + if(pos < 0.0) + pos = 0.0; + else + if(pos > 1.0) + pos = 1.0; + pos = + (atan((pos * 2.0 + - 1.0) * vowelclearness) / atan(vowelclearness) + 1.0) * 0.5; - p1=sequence[p1].nvowel; - p2=sequence[p2].nvowel; + p1 = sequence[p1].nvowel; + p2 = sequence[p2].nvowel; - if (firsttime!=0) { - for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - oldformantamp[i]=currentformants[i].amp; - }; - firsttime=0; - } else { - for (int i=0;isetfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + oldformantamp[i] = currentformants[i].amp; + } + firsttime = 0; + } + else { + for(int i = 0; i < numformants; i++) { + currentformants[i].freq = currentformants[i].freq + * (1.0 - formantslowness) + + (formantpar[p1][i].freq + * (1.0 + - pos) + formantpar[p2][i].freq + * pos) * formantslowness; - currentformants[i].amp=currentformants[i].amp*(1.0-formantslowness) - +(formantpar[p1][i].amp*(1.0-pos)+formantpar[p2][i].amp*pos)*formantslowness; + currentformants[i].amp = currentformants[i].amp + * (1.0 - formantslowness) + + (formantpar[p1][i].amp + * (1.0 + - pos) + formantpar[p2][i].amp + * pos) * formantslowness; - currentformants[i].q=currentformants[i].q*(1.0-formantslowness) - +(formantpar[p1][i].q*(1.0-pos)+formantpar[p2][i].q*pos)*formantslowness; + currentformants[i].q = currentformants[i].q + * (1.0 - formantslowness) + + (formantpar[p1][i].q + * (1.0 + - pos) + formantpar[p2][i].q + * pos) * formantslowness; - formant[i]->setfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); - }; - }; + formant[i]->setfreq_and_q(currentformants[i].freq, + currentformants[i].q * Qfactor); + } + } - oldQfactor=Qfactor; -}; + oldQfactor = Qfactor; +} void FormantFilter::setfreq(REALTYPE frequency) { setpos(frequency); -}; +} void FormantFilter::setq(REALTYPE q_) { - Qfactor=q_; - for (int i=0;isetq(Qfactor*currentformants[i].q); -}; + Qfactor = q_; + for(int i = 0; i < numformants; i++) + formant[i]->setq(Qfactor * currentformants[i].q); +} -void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void FormantFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - Qfactor=q_; + Qfactor = q_; setpos(frequency); -}; +} void FormantFilter::filterout(REALTYPE *smp) { - int i,j; - for (i=0;ifilterout(tmpbuf); - if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) - for (i=0;i #include "SVFilter.h" -SVFilter::SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages) +SVFilter::SVFilter(unsigned char Ftype, + REALTYPE Ffreq, + REALTYPE Fq, + unsigned char Fstages) { - stages=Fstages; - type=Ftype; - freq=Ffreq; - q=Fq; - gain=1.0; - outgain=1.0; - needsinterpolation=0; - firsttime=1; - if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + stages = Fstages; + type = Ftype; + freq = Ffreq; + q = Fq; + gain = 1.0; + outgain = 1.0; + needsinterpolation = 0; + firsttime = 1; + if(stages >= MAX_FILTER_STAGES) + stages = MAX_FILTER_STAGES; cleanup(); - setfreq_and_q(Ffreq,Fq); -}; + setfreq_and_q(Ffreq, Fq); +} SVFilter::~SVFilter() -{ -}; +{} void SVFilter::cleanup() { - for (int i=0;i0.99999) par.f=0.99999; - par.q=1.0-atan(sqrt(q))*2.0/PI; - par.q=pow(par.q,1.0/(stages+1)); - par.q_sqrt=sqrt(par.q); -}; + par.f = freq / SAMPLE_RATE * 4.0; + if(par.f > 0.99999) + par.f = 0.99999; + par.q = 1.0 - atan(sqrt(q)) * 2.0 / PI; + par.q = pow(par.q, 1.0 / (stages + 1)); + par.q_sqrt = sqrt(par.q); +} void SVFilter::setfreq(REALTYPE frequency) { - if (frequency<0.1) frequency=0.1; - REALTYPE rap=freq/frequency; - if (rap<1.0) rap=1.0/rap; + if(frequency < 0.1) + frequency = 0.1; + REALTYPE rap = freq / frequency; + if(rap < 1.0) + rap = 1.0 / rap; - oldabovenq=abovenq; - abovenq=frequency>(SAMPLE_RATE/2-500.0); + oldabovenq = abovenq; + abovenq = frequency > (SAMPLE_RATE / 2 - 500.0); - int nyquistthresh=(abovenq^oldabovenq); + int nyquistthresh = (abovenq ^ oldabovenq); - if ((rap>3.0)||(nyquistthresh!=0)) {//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) - if (firsttime==0) needsinterpolation=1; - ipar=par; - }; - freq=frequency; + if((rap > 3.0) || (nyquistthresh != 0)) { //if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + if(firsttime == 0) + needsinterpolation = 1; + ipar = par; + } + freq = frequency; computefiltercoefs(); - firsttime=0; + firsttime = 0; +} -}; - -void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_) +void SVFilter::setfreq_and_q(REALTYPE frequency, REALTYPE q_) { - q=q_; + q = q_; setfreq(frequency); -}; +} void SVFilter::setq(REALTYPE q_) { - q=q_; + q = q_; computefiltercoefs(); -}; +} void SVFilter::settype(int type_) { - type=type_; + type = type_; computefiltercoefs(); -}; +} void SVFilter::setgain(REALTYPE dBgain) { - gain=dB2rap(dBgain); + gain = dB2rap(dBgain); computefiltercoefs(); -}; +} void SVFilter::setstages(int stages_) { - if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; - stages=stages_; + if(stages_ >= MAX_FILTER_STAGES) + stages_ = MAX_FILTER_STAGES - 1; + stages = stages_; cleanup(); computefiltercoefs(); -}; +} -void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par) +void SVFilter::singlefilterout(REALTYPE *smp, fstage &x, parameters &par) { int i; - REALTYPE *out=NULL; - switch (type) { + REALTYPE *out = NULL; + switch(type) { case 0: - out=&x.low; + out = &x.low; break; case 1: - out=&x.high; + out = &x.high; break; case 2: - out=&x.band; + out = &x.band; break; case 3: - out=&x.notch; + out = &x.notch; break; - }; + } - for (i=0;i1,1->2,etc.) - REALTYPE freq;//Frequency given in Hz - REALTYPE q; //Q factor (resonance or Q factor) - REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + void singlefilterout(REALTYPE *smp, fstage &x, parameters &par); + void computefiltercoefs(); + int type; //The type of the filter (LPF1,HPF1,LPF2,HPF2...) + int stages; //how many times the filter is applied (0->1,1->2,etc.) + REALTYPE freq; //Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain; //the gain of the filter (if are shelf/peak) filters - int abovenq;//this is 1 if the frequency is above the nyquist - int oldabovenq; - int needsinterpolation,firsttime; + int abovenq; //this is 1 if the frequency is above the nyquist + int oldabovenq; + int needsinterpolation, firsttime; }; diff --git a/plugins/zynaddsubfx/src/DSP/Unison.cpp b/plugins/zynaddsubfx/src/DSP/Unison.cpp new file mode 100644 index 000000000..031a868c3 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Unison.cpp @@ -0,0 +1,192 @@ +/* + ZynAddSubFX - a software synthesizer + + Unison.cpp - Unison effect (multivoice chorus) + Copyright (C) 2002-2009 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "Unison.h" + +Unison::Unison(int update_period_samples_, REALTYPE max_delay_sec_) { + update_period_samples = update_period_samples_; + max_delay = (int)(max_delay_sec_ * (REALTYPE)SAMPLE_RATE + 1); + if(max_delay < 10) + max_delay = 10; + delay_buffer = new REALTYPE[max_delay]; + delay_k = 0; + base_freq = 1.0; + unison_bandwidth_cents = 10.0; + + ZERO_REALTYPE(delay_buffer, max_delay); + + uv = NULL; + update_period_sample_k = 0; + first_time = 0; + + set_size(1); +} + +Unison::~Unison() { + delete [] delay_buffer; + if(uv) + delete [] uv; +} + +void Unison::set_size(int new_size) { + if(new_size < 1) + new_size = 1; + unison_size = new_size; + if(uv) + delete [] uv; + uv = new UnisonVoice[unison_size]; + first_time = true; + update_parameters(); +} + +void Unison::set_base_frequency(REALTYPE freq) { + base_freq = freq; + update_parameters(); +} + +void Unison::set_bandwidth(REALTYPE bandwidth) { + if(bandwidth < 0) + bandwidth = 0.0; + if(bandwidth > 1200.0) + bandwidth = 1200.0; + + printf("bandwidth %g\n", bandwidth); +#warning \ + : todo: if bandwidth is too small the audio will be self canceled (because of the sign change of the outputs) + unison_bandwidth_cents = bandwidth; + update_parameters(); +} + +void Unison::update_parameters() { + if(!uv) + return; + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE) update_period_samples; +// printf("#%g, %g\n",increments_per_second,base_freq); + for(int i = 0; i < unison_size; i++) { + REALTYPE base = pow(UNISON_FREQ_SPAN, RND * 2.0 - 1.0); + uv[i].relative_amplitude = base; + REALTYPE period = base / base_freq; + REALTYPE m = 4.0 / (period * increments_per_second); + if(RND < 0.5) + m = -m; + uv[i].step = m; +// printf("%g %g\n",uv[i].relative_amplitude,period); + } + + REALTYPE max_speed = pow(2.0, unison_bandwidth_cents / 1200.0); + unison_amplitude_samples = 0.125 + * (max_speed - 1.0) * SAMPLE_RATE / base_freq; + printf("unison_amplitude_samples %g\n", unison_amplitude_samples); + +#warning \ + todo: test if unison_amplitude_samples is to big and reallocate bigger memory + if(unison_amplitude_samples >= max_delay - 1) + unison_amplitude_samples = max_delay - 2; + + update_unison_data(); +} + +void Unison::process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf) { + if(!uv) + return; + if(!outbuf) + outbuf = inbuf; + + REALTYPE volume = 1.0 / sqrt(unison_size); + REALTYPE xpos_step = 1.0 / (REALTYPE) update_period_samples; + REALTYPE xpos = (REALTYPE) update_period_sample_k * xpos_step; + for(int i = 0; i < bufsize; i++) { + if((update_period_sample_k++) >= update_period_samples) { + update_unison_data(); + update_period_sample_k = 0; + xpos = 0.0; + } + xpos += xpos_step; + REALTYPE in = inbuf[i], out = 0.0; + + REALTYPE sign = 1.0; + for(int k = 0; k < unison_size; k++) { + REALTYPE vpos = uv[k].realpos1 + * (1.0 - xpos) + uv[k].realpos2 * xpos; //optimize + REALTYPE pos = delay_k + max_delay - vpos - 1.0; //optimize + int posi; + REALTYPE posf; + F2I(pos, posi); //optimize! + if(posi >= max_delay) + posi -= max_delay; + posf = pos - floor(pos); + out += + ((1.0 + - posf) * delay_buffer[posi] + posf + * delay_buffer[posi + 1]) * sign; + sign = -sign; + } + outbuf[i] = out * volume; +// printf("%d %g\n",i,outbuf[i]); + delay_buffer[delay_k] = in; + if((++delay_k) >= max_delay) + delay_k = 0; + } +} + +void Unison::update_unison_data() { + if(!uv) + return; + + for(int k = 0; k < unison_size; k++) { + REALTYPE pos = uv[k].position; + REALTYPE step = uv[k].step; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother +#warning \ + I will use relative amplitude, so the delay might be bigger than the whole buffer +#warning \ + I have to enlarge (reallocate) the buffer to make place for the whole delay + REALTYPE newval = 1.0 + 0.5 + * (vibratto_val + + 1.0) * unison_amplitude_samples + * uv[k].relative_amplitude; + + if(first_time) + uv[k].realpos1 = uv[k].realpos2 = newval; + else{ + uv[k].realpos1 = uv[k].realpos2; + uv[k].realpos2 = newval; + } + + uv[k].position = pos; + uv[k].step = step; + } + if(first_time) + first_time = false; +} + diff --git a/plugins/zynaddsubfx/src/DSP/Unison.h b/plugins/zynaddsubfx/src/DSP/Unison.h new file mode 100644 index 000000000..d4254a114 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Unison.h @@ -0,0 +1,69 @@ +/* + ZynAddSubFX - a software synthesizer + + Unison.h - Unison effect (multivoice chorus) + Copyright (C) 2002-2009 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef UNISON_H +#define UNISON_H +#include +#include "../globals.h" + +#define UNISON_FREQ_SPAN 2.0 +//how much the unison frequencies varies (always >= 1.0) + +class Unison +{ + public: + Unison(int update_period_samples_, REALTYPE max_delay_sec_); + ~Unison(); + + void set_size(int new_size); + void set_base_frequency(REALTYPE freq); + void set_bandwidth(REALTYPE bandwidth_cents); + + void process(int bufsize, REALTYPE *inbuf, REALTYPE *outbuf = NULL); + + private: + void update_parameters(); + void update_unison_data(); + + int unison_size; + REALTYPE base_freq; + struct UnisonVoice { + REALTYPE step, position; //base LFO + REALTYPE realpos1, realpos2; //the position regarding samples + REALTYPE relative_amplitude; + REALTYPE lin_fpos, lin_ffreq; + UnisonVoice() { + position = RND * 1.8 - 0.9; + realpos1 = 0.0; + realpos2 = 0.0; + step = 0.0; + relative_amplitude = 1.0; + } + } *uv; + int update_period_samples, update_period_sample_k; + int max_delay, delay_k; + bool first_time; + REALTYPE *delay_buffer; + REALTYPE unison_amplitude_samples; + REALTYPE unison_bandwidth_cents; +}; +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp index a4bf58e54..fb07d4f11 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.cpp +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.cpp @@ -23,83 +23,87 @@ #include #include "Alienwah.h" -Alienwah::Alienwah(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),oldl(NULL),oldr(NULL) +Alienwah::Alienwah(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), oldl(NULL), oldr(NULL) { setpreset(Ppreset); cleanup(); - oldclfol=complex(fb,0.0); - oldclfor=complex(fb,0.0); -}; + oldclfol = complex(fb, 0.0); + oldclfor = complex(fb, 0.0); +} Alienwah::~Alienwah() { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr ; -}; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; +} /* * Apply the effect */ -void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Alienwah::out(REALTYPE *smpsl, REALTYPE *smpsr) { - REALTYPE lfol,lfor; //Left/Right LFOs - complex clfol,clfor,out,tmp; + REALTYPE lfol, lfor; //Left/Right LFOs + complex clfol, clfor, out, tmp; /**\todo Rework, as optimization can be used when the new complex type is * utilized. * Before all calculations needed to be done with individual REALTYPE, * but now they can be done together*/ - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*PI*2.0; - lfor*=depth*PI*2.0; - clfol=complex(cos(lfol+phase)*fb,sin(lfol+phase)*fb); //rework - clfor=complex(cos(lfor+phase)*fb,sin(lfor+phase)*fb); //rework + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * PI * 2.0; + lfor *= depth * PI * 2.0; + clfol = complex(cos(lfol + phase) * fb, sin(lfol + phase) * fb); //rework + clfor = complex(cos(lfor + phase) * fb, sin(lfor + phase) * fb); //rework - for (int i=0;i=Pdelay) oldk=0; + if(++oldk >= Pdelay) + oldk = 0; //LRcross - efxoutl[i]=l*(1.0-lrcross)+r*lrcross; - efxoutr[i]=r*(1.0-lrcross)+l*lrcross; - }; + efxoutl[i] = l * (1.0 - lrcross) + r * lrcross; + efxoutr[i] = r * (1.0 - lrcross) + l * lrcross; + } - oldclfol=clfol; - oldclfor=clfor; - -}; + oldclfol = clfol; + oldclfor = clfor; +} /* * Cleanup the effect */ void Alienwah::cleanup() { - for (int i=0;i(0.0,0.0); - oldr[i]=complex(0.0,0.0); - }; - oldk=0; -}; + for(int i = 0; i < Pdelay; i++) { + oldl[i] = complex(0.0, 0.0); + oldr[i] = complex(0.0, 0.0); + } + oldk = 0; +} /* @@ -108,81 +112,92 @@ void Alienwah::cleanup() void Alienwah::setdepth(const unsigned char &Pdepth) { - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} void Alienwah::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=fabs((Pfb-64.0)/64.1); - fb=sqrt(fb); - if (fb<0.4) fb=0.4; - if (Pfb<64) fb=-fb; -}; + this->Pfb = Pfb; + fb = fabs((Pfb - 64.0) / 64.1); + fb = sqrt(fb); + if(fb < 0.4) + fb = 0.4; + if(Pfb < 64) + fb = -fb; +} void Alienwah::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Alienwah::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Alienwah::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Alienwah::setphase(const unsigned char &Pphase) { - this->Pphase=Pphase; - phase=(Pphase-64.0)/64.0*PI; -}; + this->Pphase = Pphase; + phase = (Pphase - 64.0) / 64.0 * PI; +} void Alienwah::setdelay(const unsigned char &Pdelay) { - if (oldl!=NULL) delete [] oldl; - if (oldr!=NULL) delete [] oldr; - if (Pdelay>=MAX_ALIENWAH_DELAY) this->Pdelay=MAX_ALIENWAH_DELAY; - else this->Pdelay=Pdelay; - oldl=new complex[Pdelay]; - oldr=new complex[Pdelay]; + if(oldl != NULL) + delete [] oldl; + if(oldr != NULL) + delete [] oldr; + if(Pdelay >= MAX_ALIENWAH_DELAY) + this->Pdelay = MAX_ALIENWAH_DELAY; + else + this->Pdelay = Pdelay; + oldl = new complex[Pdelay]; + oldr = new complex[Pdelay]; cleanup(); -}; +} void Alienwah::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=4; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 4; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //AlienWah1 - {127,64,70,0,0,62,60,105,25,0,64}, + {127, 64, 70, 0, 0, 62, 60, 105, 25, 0, 64}, //AlienWah2 - {127,64,73,106,0,101,60,105,17,0,64}, + {127, 64, 73, 106, 0, 101, 60, 105, 17, 0, 64}, //AlienWah3 - {127,64,63,0,1,100,112,105,31,0,42}, + {127, 64, 63, 0, 1, 100, 112, 105, 31, 0, 42}, //AlienWah4 - {93,64,25,0,1,66,101,11,47,0,86} + {93, 64, 25, 0, 1, 66, 101, 11, 47, 0, 86} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; +} -void Alienwah::changepar(const int &npar,const unsigned char &value) +void Alienwah::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -190,19 +205,19 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -220,48 +235,47 @@ void Alienwah::changepar(const int &npar,const unsigned char &value) case 10: setphase(value); break; - }; -}; + } +} -unsigned char Alienwah::getpar(const int &npar)const +unsigned char Alienwah::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pfb); + return Pfb; break; case 8: - return(Pdelay); + return Pdelay; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pphase); + return Pphase; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.h b/plugins/zynaddsubfx/src/Effects/Alienwah.h index e813737bf..175c41f24 100644 --- a/plugins/zynaddsubfx/src/Effects/Alienwah.h +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.h @@ -34,49 +34,51 @@ using namespace std; /**"AlienWah" Effect*/ class Alienwah:public Effect { -public: - /** - * Constructor - * @param insetion_ 1 for insertion Effect, 0 for others - * @param efxoutl_ Pointer to Alienwah's left channel output buffer - * @param efxoutr_ Pointer to Alienwah's left channel output buffer - * @return Initialized Alienwah - */ - Alienwah(const int &insetion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); - ~Alienwah(); - void out(REALTYPE *const smpsl,REALTYPE *const smpsr); + public: + /** + * Constructor + * @param insetion_ 1 for insertion Effect, 0 for others + * @param efxoutl_ Pointer to Alienwah's left channel output buffer + * @param efxoutr_ Pointer to Alienwah's left channel output buffer + * @return Initialized Alienwah + */ + Alienwah(const int &insetion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); + ~Alienwah(); + void out(REALTYPE *const smpsl, REALTYPE *const smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); -private: - //Alienwah Parameters - EffectLFO lfo;//lfo-ul Alienwah - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Alienwah - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pdelay; - unsigned char Pphase; + private: + //Alienwah Parameters + EffectLFO lfo; //lfo-ul Alienwah + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Alienwah + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pdelay; + unsigned char Pphase; - //Control Parameters - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); - void setdelay(const unsigned char &Pdelay); - void setphase(const unsigned char &Pphase); + //Control Parameters + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + void setdelay(const unsigned char &Pdelay); + void setphase(const unsigned char &Pphase); - //Internal Values - REALTYPE panning,fb,depth,lrcross,phase; - complex *oldl,*oldr; - complex oldclfol,oldclfor; - int oldk; + //Internal Values + REALTYPE panning, fb, depth, lrcross, phase; + complex *oldl, *oldr; + complex oldclfol, oldclfor; + int oldk; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.cpp b/plugins/zynaddsubfx/src/Effects/Chorus.cpp index 844e87f50..708c0cd75 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.cpp +++ b/plugins/zynaddsubfx/src/Effects/Chorus.cpp @@ -26,26 +26,28 @@ using namespace std; -Chorus::Chorus(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - maxdelay((int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE)), - delaySample(maxdelay) +Chorus::Chorus(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + maxdelay((int)(MAX_CHORUS_DELAY / 1000.0 * SAMPLE_RATE)), + delaySample(maxdelay) { - dlk=0; - drk=0; + dlk = 0; + drk = 0; //maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); //delayl=new REALTYPE[maxdelay]; //delayr=new REALTYPE[maxdelay]; setpreset(Ppreset); - lfo.effectlfoout(&lfol,&lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + lfo.effectlfoout(&lfol, &lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); cleanup(); -}; +} -Chorus::~Chorus() {}; +Chorus::~Chorus() {} /* * get the delay value in samples; xlfo is the current lfo value @@ -53,91 +55,100 @@ Chorus::~Chorus() {}; REALTYPE Chorus::getdelay(REALTYPE xlfo) { REALTYPE result; - if (Pflangemode==0) { - result=(delay+xlfo*depth)*SAMPLE_RATE; - } else result=0; + if(Pflangemode == 0) + result = (delay + xlfo * depth) * SAMPLE_RATE; + else + result = 0; //check if it is too big delay(caused bu errornous setdelay() and setdepth() /**\todo fix setdelay() and setdepth(), so this error cannot occur*/ - if ((result+0.5)>=maxdelay) { - cerr << "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; - result=maxdelay-1.0; - }; - return(result); -}; + if((result + 0.5) >= maxdelay) { + cerr + << + "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; + result = maxdelay - 1.0; + } + return result; +} /* * Apply the effect */ -void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Chorus::out(REALTYPE *smpsl, REALTYPE *smpsr) { - const Stereo input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + const Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Chorus::out(const Stereo &input) { - const REALTYPE one=1.0; - dl1=dl2; - dr1=dr2; - lfo.effectlfoout(&lfol,&lfor); + const REALTYPE one = 1.0; + dl1 = dl2; + dr1 = dr2; + lfo.effectlfoout(&lfol, &lfor); - dl2=getdelay(lfol); - dr2=getdelay(lfor); + dl2 = getdelay(lfol); + dr2 = getdelay(lfor); - for (int i=0;i tmpc(inl,inr); + Stereo tmpc(inl, inr); //REALTYPE r=inr; - inl=tmpc.l()*(1.0-lrcross)+tmpc.r()*lrcross; - inr=tmpc.r()*(1.0-lrcross)+tmpc.l()*lrcross; + inl = tmpc.l() * (1.0 - lrcross) + tmpc.r() * lrcross; + inr = tmpc.r() * (1.0 - lrcross) + tmpc.l() * lrcross; //Left channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dl1*(SOUND_BUFFER_SIZE-i)+dl2*i)/SOUND_BUFFER_SIZE; - if (++dlk>=maxdelay) dlk=0; - REALTYPE tmp=dlk-mdel+maxdelay*2.0;//where should I get the sample from + mdel = (dl1 * (SOUND_BUFFER_SIZE - i) + dl2 * i) / SOUND_BUFFER_SIZE; + if(++dlk >= maxdelay) + dlk = 0; + REALTYPE tmp = dlk - mdel + maxdelay * 2.0; //where should I get the sample from - F2I(tmp,dlhi); - dlhi%=maxdelay; + F2I(tmp, dlhi); + dlhi %= maxdelay; - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutl[i]=delaySample.l()[dlhi2]*dllo+delaySample.l()[dlhi]*(1.0-dllo); - delaySample.l()[dlk]=inl+efxoutl[i]*fb; + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutl[i] = delaySample.l()[dlhi2] * dllo + delaySample.l()[dlhi] + * (1.0 - dllo); + delaySample.l()[dlk] = inl + efxoutl[i] * fb; //Right channel //compute the delay in samples using linear interpolation between the lfo delays - mdel=(dr1*(SOUND_BUFFER_SIZE-i)+dr2*i)/SOUND_BUFFER_SIZE; - if (++drk>=maxdelay) drk=0; - tmp=drk*1.0-mdel+maxdelay*2.0;//where should I get the sample from + mdel = (dr1 * (SOUND_BUFFER_SIZE - i) + dr2 * i) / SOUND_BUFFER_SIZE; + if(++drk >= maxdelay) + drk = 0; + tmp = drk * 1.0 - mdel + maxdelay * 2.0; //where should I get the sample from - F2I(tmp,dlhi); - dlhi%=maxdelay; + F2I(tmp, dlhi); + dlhi %= maxdelay; - dlhi2=(dlhi-1+maxdelay)%maxdelay; - dllo=1.0-fmod(tmp,one); - efxoutr[i]=delaySample.r()[dlhi2]*dllo+delaySample.r()[dlhi]*(1.0-dllo); - delaySample.r()[dlk]=inr+efxoutr[i]*fb; + dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + dllo = 1.0 - fmod(tmp, one); + efxoutr[i] = delaySample.r()[dlhi2] * dllo + delaySample.r()[dlhi] + * (1.0 - dllo); + delaySample.r()[dlk] = inr + efxoutr[i] * fb; + } - }; - - if (Poutsub!=0) - for (int i=0;iPdepth=Pdepth; - depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdepth = Pdepth; + depth = (pow(8.0, (Pdepth / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setdelay(const unsigned char &Pdelay) { - this->Pdelay=Pdelay; - delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds -}; + this->Pdelay = Pdelay; + delay = (pow(10.0, (Pdelay / 127.0) * 2.0) - 1.0) / 1000.0; //seconds +} void Chorus::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} void Chorus::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void Chorus::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void Chorus::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} void Chorus::setpreset(unsigned char npreset) { - const int PRESET_SIZE=12; - const int NUM_PRESETS=10; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 10; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Chorus1 - {64,64,50,0,0,90,40,85,64,119,0,0}, + {64, 64, 50, 0, 0, 90, 40, 85, 64, 119, 0, 0 }, //Chorus2 - {64,64,45,0,0,98,56,90,64,19,0,0}, + {64, 64, 45, 0, 0, 98, 56, 90, 64, 19, 0, 0 }, //Chorus3 - {64,64,29,0,1,42,97,95,90,127,0,0}, + {64, 64, 29, 0, 1, 42, 97, 95, 90, 127, 0, 0 }, //Celeste1 - {64,64,26,0,0,42,115,18,90,127,0,0}, + {64, 64, 26, 0, 0, 42, 115, 18, 90, 127, 0, 0 }, //Celeste2 - {64,64,29,117,0,50,115,9,31,127,0,1}, + {64, 64, 29, 117, 0, 50, 115, 9, 31, 127, 0, 1 }, //Flange1 - {64,64,57,0,0,60,23,3,62,0,0,0}, + {64, 64, 57, 0, 0, 60, 23, 3, 62, 0, 0, 0 }, //Flange2 - {64,64,33,34,1,40,35,3,109,0,0,0}, + {64, 64, 33, 34, 1, 40, 35, 3, 109, 0, 0, 0 }, //Flange3 - {64,64,53,34,1,94,35,3,54,0,0,1}, + {64, 64, 53, 34, 1, 94, 35, 3, 54, 0, 0, 1 }, //Flange4 - {64,64,40,0,1,62,12,19,97,0,0,0}, + {64, 64, 40, 0, 1, 62, 12, 19, 97, 0, 0, 0 }, //Flange5 - {64,64,55,105,0,24,39,19,17,0,0,1} + {64, 64, 55, 105, 0, 24, 39, 19, 17, 0, 0, 1 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void Chorus::changepar(const int &npar,const unsigned char &value) +void Chorus::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -231,19 +246,19 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -259,58 +274,61 @@ void Chorus::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 10: - if (value>1) Pflangemode=1; - else Pflangemode=value; + if(value > 1) + Pflangemode = 1; + else + Pflangemode = value; break; case 11: - if (value>1) Poutsub=1; - else Poutsub=value; + if(value > 1) + Poutsub = 1; + else + Poutsub = value; break; - }; -}; + } +} -unsigned char Chorus::getpar(const int &npar)const +unsigned char Chorus::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pdelay); + return Pdelay; break; case 8: - return(Pfb); + return Pfb; break; case 9: - return(Plrcross); + return Plrcross; break; case 10: - return(Pflangemode); + return Pflangemode; break; case 11: - return(Poutsub); + return Poutsub; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.h b/plugins/zynaddsubfx/src/Effects/Chorus.h index 488e4d85d..748ce5eaf 100644 --- a/plugins/zynaddsubfx/src/Effects/Chorus.h +++ b/plugins/zynaddsubfx/src/Effects/Chorus.h @@ -33,83 +33,83 @@ /**Chorus and Flange effects*/ class Chorus:public Effect { -public: - Chorus(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - /**Destructor*/ - ~Chorus(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void out(const Stereo &input); - void setpreset(unsigned char npreset); - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int &npar,const unsigned char &value); - /** - * Gets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# LFO Frequency - * -# LFO Randomness - * -# LFO Type - * -# LFO stereo - * -# Depth - * -# Delay - * -# Feedback - * -# Flange Mode - * -# Subtractive - * @param npar number of chosen parameter - * @return the value of the parameter - */ - unsigned char getpar(const int &npar)const; - void cleanup(); + public: + Chorus(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + /**Destructor*/ + ~Chorus(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void out(const Stereo &input); + void setpreset(unsigned char npreset); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); + /** + * Gets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @return the value of the parameter + */ + unsigned char getpar(const int &npar) const; + void cleanup(); -private: - //Chorus Parameters - EffectLFO lfo;//lfo-ul chorus - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;//the depth of the Chorus(ms) - unsigned char Pdelay;//the delay (ms) - unsigned char Pfb;//feedback - unsigned char Plrcross;//feedback - unsigned char Pflangemode;//how the LFO is scaled, to result chorus or flange - unsigned char Poutsub;//if I wish to substract the output instead of the adding it + private: + //Chorus Parameters + EffectLFO lfo; //lfo-ul chorus + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth; //the depth of the Chorus(ms) + unsigned char Pdelay; //the delay (ms) + unsigned char Pfb; //feedback + unsigned char Plrcross; //feedback + unsigned char Pflangemode; //how the LFO is scaled, to result chorus or flange + unsigned char Poutsub; //if I wish to substract the output instead of the adding it - //Parameter Controls - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setdepth(const unsigned char &Pdepth); - void setdelay(const unsigned char &Pdelay); - void setfb(const unsigned char &Pfb); - void setlrcross(const unsigned char &Plrcross); + //Parameter Controls + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setdelay(const unsigned char &Pdelay); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); - //Internal Values - REALTYPE depth,delay,fb,lrcross,panning; - REALTYPE dl1,dl2,dr1,dr2,lfol,lfor; - int maxdelay; - Stereo delaySample; - //REALTYPE *delayl,*delayr; - int dlk,drk,dlhi,dlhi2; - REALTYPE getdelay(REALTYPE xlfo); - REALTYPE dllo,mdel; + //Internal Values + REALTYPE depth, delay, fb, lrcross, panning; + REALTYPE dl1, dl2, dr1, dr2, lfol, lfor; + int maxdelay; + Stereo delaySample; + //REALTYPE *delayl,*delayr; + int dlk, drk, dlhi, dlhi2; + REALTYPE getdelay(REALTYPE xlfo); + REALTYPE dllo, mdel; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp index 6aeaab4fb..61fe9966b 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.cpp +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.cpp @@ -28,159 +28,199 @@ * Waveshape (this is called by OscilGen::waveshape and Distorsion::process) */ -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive) +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive) { - int i; - REALTYPE ws=drive/127.0; + int i; + REALTYPE ws = drive / 127.0; REALTYPE tmpv; - switch (type) { + switch(type) { case 1: - ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent - for (i=0;iws) { - if (tmp>=0.0) smps[i]=1.0; - else smps[i]=-1.0; - } else smps[i]/=ws; - }; + ws = pow(2.0, -ws * ws * 8.0); //Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = 1.0; + else + smps[i] = -1.0; + } + else + smps[i] /= ws; + } break; case 8: - ws=pow(2.0,-ws*ws*8.0); //Upper Limiter - for (i=0;iws) smps[i]=ws; - smps[i]*=2.0; - }; + ws = pow(2.0, -ws * ws * 8.0); //Upper Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(tmp > ws) + smps[i] = ws; + smps[i] *= 2.0; + } break; case 9: - ws=pow(2.0,-ws*ws*8.0); //Lower Limiter - for (i=0;iws) { - if (tmp>=0.0) smps[i]=tmp-ws; - else smps[i]=tmp+ws; - } else smps[i]=0; - }; + ws = (pow(2.0, ws * 6.0) - 1.0) / pow(2.0, 6.0); //Inverse Limiter + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i]; + if(fabs(tmp) > ws) { + if(tmp >= 0.0) + smps[i] = tmp - ws; + else + smps[i] = tmp + ws; + } + else + smps[i] = 0; + } break; case 11: - ws=pow(5,ws*ws*1.0)-1.0;//Clip - for (i=0;i-2.0) && (tmp<1.0)) smps[i]=tmp*(1.0-tmp)*(tmp+2.0)/tmpv; - else smps[i]=0.0; - }; + ws = ws * ws * ws * 30 + 0.001; //Asym2 + if(ws < 0.3) + tmpv = ws; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -2.0) && (tmp < 1.0)) + smps[i] = tmp * (1.0 - tmp) * (tmp + 2.0) / tmpv; + else + smps[i] = 0.0; + } break; case 13: - ws=ws*ws*ws*32.0+0.0001;//Pow2 - if (ws<1.0) tmpv=ws*(1+ws)/2.0; - else tmpv=1.0; - for (i=0;i-1.0)&&(tmp<1.618034)) smps[i]=tmp*(1.0-tmp)/tmpv; - else if (tmp>0.0) smps[i]=-1.0; - else smps[i]=-2.0; - }; + ws = ws * ws * ws * 32.0 + 0.0001; //Pow2 + if(ws < 1.0) + tmpv = ws * (1 + ws) / 2.0; + else + tmpv = 1.0; + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if((tmp > -1.0) && (tmp < 1.618034)) + smps[i] = tmp * (1.0 - tmp) / tmpv; + else + if(tmp > 0.0) + smps[i] = -1.0; + else + smps[i] = -2.0; + } break; case 14: - ws=pow(ws,5.0)*80.0+0.0001;//sigmoid - if (ws>10.0) tmpv=0.5; - else tmpv=0.5-1.0/(exp(ws)+1.0); - for (i=0;i10.0) tmp=10.0; - tmp=0.5-1.0/(exp(tmp)+1.0); - smps[i]=tmp/tmpv; - }; + ws = pow(ws, 5.0) * 80.0 + 0.0001; //sigmoid + if(ws > 10.0) + tmpv = 0.5; + else + tmpv = 0.5 - 1.0 / (exp(ws) + 1.0); + for(i = 0; i < n; i++) { + REALTYPE tmp = smps[i] * ws; + if(tmp < -10.0) + tmp = -10.0; + else + if(tmp > 10.0) + tmp = 10.0; + tmp = 0.5 - 1.0 / (exp(tmp) + 1.0); + smps[i] = tmp / tmpv; + } break; /**\todo update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions*/ - }; - -}; + } +} -Distorsion::Distorsion(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +Distorsion::Distorsion(const int &insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - lpfl=new AnalogFilter(2,22000,1,0); - lpfr=new AnalogFilter(2,22000,1,0); - hpfl=new AnalogFilter(3,20,1,0); - hpfr=new AnalogFilter(3,20,1,0); + lpfl = new AnalogFilter(2, 22000, 1, 0); + lpfr = new AnalogFilter(2, 22000, 1, 0); + hpfl = new AnalogFilter(3, 20, 1, 0); + hpfr = new AnalogFilter(3, 20, 1, 0); //default values - Pvolume=50; - Plrcross=40; - Pdrive=90; - Plevel=64; - Ptype=0; - Pnegate=0; - Plpf=127; - Phpf=0; - Pstereo=0; - Pprefiltering=0; + Pvolume = 50; + Plrcross = 40; + Pdrive = 90; + Plevel = 64; + Ptype = 0; + Pnegate = 0; + Plpf = 127; + Phpf = 0; + Pstereo = 0; + Pprefiltering = 0; setpreset(Ppreset); cleanup(); -}; +} Distorsion::~Distorsion() { @@ -188,8 +228,7 @@ Distorsion::~Distorsion() delete lpfr; delete hpfl; delete hpfr; - -}; +} /* * Cleanup the effect @@ -200,72 +239,77 @@ void Distorsion::cleanup() hpfl->cleanup(); lpfr->cleanup(); hpfr->cleanup(); -}; +} /* * Apply the filters */ -void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr) +void Distorsion::applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr) { lpfl->filterout(efxoutl); hpfl->filterout(efxoutl); - if (Pstereo!=0) {//stereo + if(Pstereo != 0) { //stereo lpfr->filterout(efxoutr); hpfr->filterout(efxoutr); - }; - -}; + } +} /* * Effect output */ -void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr) +void Distorsion::out(REALTYPE *smpsl, REALTYPE *smpsr) { - int i; - REALTYPE l,r,lout,rout; + int i; + REALTYPE l, r, lout, rout; - REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0); - if (Pnegate!=0) inputvol*=-1.0; + REALTYPE inputvol = pow(5.0, (Pdrive - 32.0) / 127.0); + if(Pnegate != 0) + inputvol *= -1.0; - if (Pstereo!=0) {//Stereo - for (i=0;iPvolume=Pvolume; + this->Pvolume = Pvolume; - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); - -}; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); +} void Distorsion::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; -}; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; +} void Distorsion::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; -}; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; +} void Distorsion::setlpf(const unsigned char &Plpf) { - this->Plpf=Plpf; - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; + this->Plpf = Plpf; + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; lpfl->setfreq(fr); lpfr->setfreq(fr); -}; +} void Distorsion::sethpf(const unsigned char &Phpf) { - this->Phpf=Phpf; - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0; + this->Phpf = Phpf; + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(25000.0)) + 20.0; hpfl->setfreq(fr); hpfr->setfreq(fr); -}; +} void Distorsion::setpreset(unsigned char npreset) { - const int PRESET_SIZE=11; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 11; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Overdrive 1 - {127,64,35,56,70,0,0,96,0,0,0}, + {127, 64, 35, 56, 70, 0, 0, 96, 0, 0, 0 }, //Overdrive 2 - {127,64,35,29,75,1,0,127,0,0,0}, + {127, 64, 35, 29, 75, 1, 0, 127, 0, 0, 0 }, //A. Exciter 1 - {64,64,35,75,80,5,0,127,105,1,0}, + {64, 64, 35, 75, 80, 5, 0, 127, 105, 1, 0 }, //A. Exciter 2 - {64,64,35,85,62,1,0,127,118,1,0}, + {64, 64, 35, 85, 62, 1, 0, 127, 118, 1, 0 }, //Guitar Amp - {127,64,35,63,75,2,0,55,0,0,0}, + {127, 64, 35, 63, 75, 2, 0, 55, 0, 0, 0 }, //Quantisize - {127,64,35,88,75,4,0,127,0,1,0} + {127, 64, 35, 88, 75, 4, 0, 127, 0, 1, 0 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion == 0) + changepar(0, (int) (presets[npreset][0] / 1.5)); //lower the volume if this is system effect + Ppreset = npreset; cleanup(); -}; +} -void Distorsion::changepar(const int &npar,const unsigned char &value) +void Distorsion::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -356,18 +404,22 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) setlrcross(value); break; case 3: - Pdrive=value; + Pdrive = value; break; case 4: - Plevel=value; + Plevel = value; break; case 5: - if (value>13) Ptype=13;//this must be increased if more distorsion types are added - else Ptype=value; + if(value > 13) + Ptype = 13; //this must be increased if more distorsion types are added + else + Ptype = value; break; case 6: - if (value>1) Pnegate=1; - else Pnegate=value; + if(value > 1) + Pnegate = 1; + else + Pnegate = value; break; case 7: setlpf(value); @@ -376,52 +428,54 @@ void Distorsion::changepar(const int &npar,const unsigned char &value) sethpf(value); break; case 9: - if (value>1) Pstereo=1; - else Pstereo=value; + if(value > 1) + Pstereo = 1; + else + Pstereo = value; break; case 10: - Pprefiltering=value; + Pprefiltering = value; break; - }; -}; + } +} -unsigned char Distorsion::getpar(const int &npar)const +unsigned char Distorsion::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(Plrcross); + return Plrcross; break; case 3: - return(Pdrive); + return Pdrive; break; case 4: - return(Plevel); + return Plevel; break; case 5: - return(Ptype); + return Ptype; break; case 6: - return(Pnegate); + return Pnegate; break; case 7: - return(Plpf); + return Plpf; break; case 8: - return(Phpf); + return Phpf; break; case 9: - return(Pstereo); + return Pstereo; break; case 10: - return(Pprefiltering); + return Pprefiltering; break; - }; - return(0);//in case of bogus parameter number -}; + } + return 0; //in case of bogus parameter number +} diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.h b/plugins/zynaddsubfx/src/Effects/Distorsion.h index efe3b8287..8c082f13f 100644 --- a/plugins/zynaddsubfx/src/Effects/Distorsion.h +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.h @@ -28,44 +28,46 @@ #include "Effect.h" //Waveshaping(called by Distorsion effect and waveshape from OscilGen) -void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive); +void waveshapesmps(int n, + REALTYPE *smps, + unsigned char type, + unsigned char drive); /**Distortion Effect*/ class Distorsion:public Effect { -public: - Distorsion(const int &insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Distorsion(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr); + public: + Distorsion(const int &insertion, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Distorsion(); + void out(REALTYPE *smpsl, REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void applyfilters(REALTYPE *efxoutl, REALTYPE *efxoutr); -private: - //Parametrii - unsigned char Pvolume; //Volumul or E/R - unsigned char Ppanning;//Panning - unsigned char Plrcross;// L/R Mixing - unsigned char Pdrive; //the input amplification - unsigned char Plevel; //the output amplification - unsigned char Ptype; //Distorsion type - unsigned char Pnegate; //if the input is negated - unsigned char Plpf; //lowpass filter - unsigned char Phpf; //highpass filter - unsigned char Pstereo; //0=mono,1=stereo - unsigned char Pprefiltering;//if you want to do the filtering before the distorsion + private: + //Parametrii + unsigned char Pvolume; //Volumul or E/R + unsigned char Ppanning; //Panning + unsigned char Plrcross; // L/R Mixing + unsigned char Pdrive; //the input amplification + unsigned char Plevel; //the output amplification + unsigned char Ptype; //Distorsion type + unsigned char Pnegate; //if the input is negated + unsigned char Plpf; //lowpass filter + unsigned char Phpf; //highpass filter + unsigned char Pstereo; //0=mono,1=stereo + unsigned char Pprefiltering; //if you want to do the filtering before the distorsion - void setvolume(const unsigned char &Pvolume); - void setpanning(const unsigned char &Ppanning); - void setlrcross(const unsigned char &Plrcross); - void setlpf(const unsigned char &Plpf); - void sethpf(const unsigned char &Phpf); - - //Real Parameters - REALTYPE panning,lrcross; - AnalogFilter *lpfl,*lpfr,*hpfl,*hpfr; + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setlrcross(const unsigned char &Plrcross); + void setlpf(const unsigned char &Plpf); + void sethpf(const unsigned char &Phpf); + //Real Parameters + REALTYPE panning, lrcross; + AnalogFilter *lpfl, *lpfr, *hpfl, *hpfr; }; diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp index b7b367ea3..1b2bb1eb0 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.cpp @@ -23,74 +23,75 @@ #include #include "DynamicFilter.h" -DynamicFilter::DynamicFilter(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,new FilterParams(0,64,64),0), - Pvolume(110),Ppanning(64),Pdepth(0),Pampsns(90), - Pampsnsinv(0),Pampsmooth(60), - filterl(NULL),filterr(NULL) +DynamicFilter::DynamicFilter(int insertion_, + REALTYPE *efxoutl_, + REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, new FilterParams(0, 64, 64), 0), + Pvolume(110), Ppanning(64), Pdepth(0), Pampsns(90), + Pampsnsinv(0), Pampsmooth(60), + filterl(NULL), filterr(NULL) { setpreset(Ppreset); cleanup(); -}; +} DynamicFilter::~DynamicFilter() { delete filterpars; delete filterl; delete filterr; -}; +} /* * Apply the effect */ -void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr) +void DynamicFilter::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (filterpars->changed) { - filterpars->changed=false; + if(filterpars->changed) { + filterpars->changed = false; cleanup(); - }; + } - REALTYPE lfol,lfor; - lfo.effectlfoout(&lfol,&lfor); - lfol*=depth*5.0; - lfor*=depth*5.0; - REALTYPE freq=filterpars->getfreq(); - REALTYPE q=filterpars->getq(); + REALTYPE lfol, lfor; + lfo.effectlfoout(&lfol, &lfor); + lfol *= depth * 5.0; + lfor *= depth * 5.0; + REALTYPE freq = filterpars->getfreq(); + REALTYPE q = filterpars->getq(); - for (i=0;igetrealfreq(freq+lfol+rms); - REALTYPE frr=filterr->getrealfreq(freq+lfor+rms); + REALTYPE frl = filterl->getrealfreq(freq + lfol + rms); + REALTYPE frr = filterr->getrealfreq(freq + lfor + rms); - filterl->setfreq_and_q(frl,q); - filterr->setfreq_and_q(frr,q); + filterl->setfreq_and_q(frl, q); + filterr->setfreq_and_q(frr, q); filterl->filterout(efxoutl); filterr->filterout(efxoutr); //panning - for (i=0;iPdepth=Pdepth; - depth=pow((Pdepth/127.0),2.0); -}; + this->Pdepth = Pdepth; + depth = pow((Pdepth / 127.0), 2.0); +} void DynamicFilter::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} void DynamicFilter::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} void DynamicFilter::setampsns(const unsigned char &Pampsns) { - ampsns=pow(Pampsns/127.0,2.5)*10.0; - if (Pampsnsinv!=0) ampsns=-ampsns; - ampsmooth=exp(-Pampsmooth/127.0*10.0)*0.99; - this->Pampsns=Pampsns; -}; + ampsns = pow(Pampsns / 127.0, 2.5) * 10.0; + if(Pampsnsinv != 0) + ampsns = -ampsns; + ampsmooth = exp(-Pampsmooth / 127.0 * 10.0) * 0.99; + this->Pampsns = Pampsns; +} void DynamicFilter::reinitfilter() { - if (filterl!=NULL) delete(filterl); - if (filterr!=NULL) delete(filterr); - filterl=new Filter(filterpars); - filterr=new Filter(filterpars); -}; + if(filterl != NULL) + delete (filterl); + if(filterr != NULL) + delete (filterr); + filterl = new Filter(filterpars); + filterr = new Filter(filterpars); +} void DynamicFilter::setpreset(unsigned char npreset) { - const int PRESET_SIZE=10; - const int NUM_PRESETS=5; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 10; + const int NUM_PRESETS = 5; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //WahWah - {110,64,80,0,0,64,0,90,0,60}, + {110, 64, 80, 0, 0, 64, 0, 90, 0, 60}, //AutoWah - {110,64,70,0,0,80,70,0,0,60}, + {110, 64, 70, 0, 0, 80, 70, 0, 0, 60}, //Sweep - {100,64,30,0,0,50,80,0,0,60}, + {100, 64, 30, 0, 0, 50, 80, 0, 0, 60}, //VocalMorph1 - {110,64,80,0,0,64,0,64,0,60}, + {110, 64, 80, 0, 0, 64, 0, 64, 0, 60}, //VocalMorph1 - {127,64,50,0,0,96,64,0,0,60} + {127, 64, 50, 0, 0, 96, 64, 0, 0, 60} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); filterpars->defaults(); - switch (npreset) { + switch(npreset) { case 0: - filterpars->Pcategory=0; - filterpars->Ptype=2; - filterpars->Pfreq=45; - filterpars->Pq=64; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 2; + filterpars->Pfreq = 45; + filterpars->Pq = 64; + filterpars->Pstages = 1; + filterpars->Pgain = 64; break; case 1: - filterpars->Pcategory=2; - filterpars->Ptype=0; - filterpars->Pfreq=72; - filterpars->Pq=64; - filterpars->Pstages=0; - filterpars->Pgain=64; + filterpars->Pcategory = 2; + filterpars->Ptype = 0; + filterpars->Pfreq = 72; + filterpars->Pq = 64; + filterpars->Pstages = 0; + filterpars->Pgain = 64; break; case 2: - filterpars->Pcategory=0; - filterpars->Ptype=4; - filterpars->Pfreq=64; - filterpars->Pq=64; - filterpars->Pstages=2; - filterpars->Pgain=64; + filterpars->Pcategory = 0; + filterpars->Ptype = 4; + filterpars->Pfreq = 64; + filterpars->Pq = 64; + filterpars->Pstages = 2; + filterpars->Pgain = 64; break; case 3: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=50; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 50; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; - filterpars->Psequencesize=2; + filterpars->Psequencesize = 2; // "I" - filterpars->Pvowels[0].formants[0].freq=34; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=99; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; - filterpars->Pvowels[0].formants[2].freq=108; - filterpars->Pvowels[0].formants[2].amp=112; - filterpars->Pvowels[0].formants[2].q=64; + filterpars->Pvowels[0].formants[0].freq = 34; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 99; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; + filterpars->Pvowels[0].formants[2].freq = 108; + filterpars->Pvowels[0].formants[2].amp = 112; + filterpars->Pvowels[0].formants[2].q = 64; // "A" - filterpars->Pvowels[1].formants[0].freq=61; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=71; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; - filterpars->Pvowels[1].formants[2].freq=99; - filterpars->Pvowels[1].formants[2].amp=117; - filterpars->Pvowels[1].formants[2].q=64; + filterpars->Pvowels[1].formants[0].freq = 61; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 71; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; + filterpars->Pvowels[1].formants[2].freq = 99; + filterpars->Pvowels[1].formants[2].amp = 117; + filterpars->Pvowels[1].formants[2].q = 64; break; case 4: - filterpars->Pcategory=1; - filterpars->Ptype=0; - filterpars->Pfreq=64; - filterpars->Pq=70; - filterpars->Pstages=1; - filterpars->Pgain=64; + filterpars->Pcategory = 1; + filterpars->Ptype = 0; + filterpars->Pfreq = 64; + filterpars->Pq = 70; + filterpars->Pstages = 1; + filterpars->Pgain = 64; - filterpars->Psequencesize=2; - filterpars->Pnumformants=2; - filterpars->Pvowelclearness=0; + filterpars->Psequencesize = 2; + filterpars->Pnumformants = 2; + filterpars->Pvowelclearness = 0; - filterpars->Pvowels[0].formants[0].freq=70; - filterpars->Pvowels[0].formants[0].amp=127; - filterpars->Pvowels[0].formants[0].q=64; - filterpars->Pvowels[0].formants[1].freq=80; - filterpars->Pvowels[0].formants[1].amp=122; - filterpars->Pvowels[0].formants[1].q=64; + filterpars->Pvowels[0].formants[0].freq = 70; + filterpars->Pvowels[0].formants[0].amp = 127; + filterpars->Pvowels[0].formants[0].q = 64; + filterpars->Pvowels[0].formants[1].freq = 80; + filterpars->Pvowels[0].formants[1].amp = 122; + filterpars->Pvowels[0].formants[1].q = 64; - filterpars->Pvowels[1].formants[0].freq=20; - filterpars->Pvowels[1].formants[0].amp=127; - filterpars->Pvowels[1].formants[0].q=64; - filterpars->Pvowels[1].formants[1].freq=100; - filterpars->Pvowels[1].formants[1].amp=121; - filterpars->Pvowels[1].formants[1].q=64; + filterpars->Pvowels[1].formants[0].freq = 20; + filterpars->Pvowels[1].formants[0].amp = 127; + filterpars->Pvowels[1].formants[0].q = 64; + filterpars->Pvowels[1].formants[1].freq = 100; + filterpars->Pvowels[1].formants[1].amp = 121; + filterpars->Pvowels[1].formants[1].q = 64; break; - }; + } // for (int i=0;i<5;i++){ // printf("freq=%d amp=%d q=%d\n",filterpars->Pvowels[0].formants[i].freq,filterpars->Pvowels[0].formants[i].amp,filterpars->Pvowels[0].formants[i].q); // }; - if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect - Ppreset=npreset; + if(insertion == 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if this is system effect + Ppreset = npreset; reinitfilter(); -}; +} -void DynamicFilter::changepar(const int &npar,const unsigned char &value) +void DynamicFilter::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -271,19 +280,19 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setpanning(value); break; case 2: - lfo.Pfreq=value; + lfo.Pfreq = value; lfo.updateparams(); break; case 3: - lfo.Prandomness=value; + lfo.Prandomness = value; lfo.updateparams(); break; case 4: - lfo.PLFOtype=value; + lfo.PLFOtype = value; lfo.updateparams(); break; case 5: - lfo.Pstereo=value; + lfo.Pstereo = value; lfo.updateparams(); break; case 6: @@ -293,52 +302,51 @@ void DynamicFilter::changepar(const int &npar,const unsigned char &value) setampsns(value); break; case 8: - Pampsnsinv=value; + Pampsnsinv = value; setampsns(Pampsns); break; case 9: - Pampsmooth=value; + Pampsmooth = value; setampsns(Pampsns); break; - }; -}; + } +} -unsigned char DynamicFilter::getpar(const int &npar)const +unsigned char DynamicFilter::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(lfo.Pfreq); + return lfo.Pfreq; break; case 3: - return(lfo.Prandomness); + return lfo.Prandomness; break; case 4: - return(lfo.PLFOtype); + return lfo.PLFOtype; break; case 5: - return(lfo.Pstereo); + return lfo.Pstereo; break; case 6: - return(Pdepth); + return Pdepth; break; case 7: - return(Pampsns); + return Pampsns; break; case 8: - return(Pampsnsinv); + return Pampsnsinv; break; case 9: - return(Pampsmooth); + return Pampsmooth; break; default: - return (0); - }; - -}; + return 0; + } +} diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h index 9c547c332..2bb5fcd9b 100644 --- a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h @@ -30,42 +30,42 @@ /**DynamicFilter Effect*/ class DynamicFilter:public Effect { -public: - DynamicFilter(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~DynamicFilter(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); + public: + DynamicFilter(int insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~DynamicFilter(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); // void setdryonly(); -private: - //Parametrii DynamicFilter - EffectLFO lfo;//lfo-ul DynamicFilter - unsigned char Pvolume; - unsigned char Ppanning; - unsigned char Pdepth;/** #include "EQ.h" -EQ::EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +EQ::EQ(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) { - - for (int i=0;icleanup(); filter[i].r->cleanup(); - }; -}; + } +} /* * Effect output */ -void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EQ::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - for (i=0;ifilterout(efxoutl); filter[i].r->filterout(efxoutr); - }; -}; + } +} /* @@ -84,131 +83,138 @@ void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr) */ void EQ::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; + this->Pvolume = Pvolume; - outvolume=pow(0.005,(1.0-Pvolume/127.0))*10.0; - if (insertion==0) { - volume=1.0; - } else { - volume=outvolume; - }; - -}; + outvolume = pow(0.005, (1.0 - Pvolume / 127.0)) * 10.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; + ; +} void EQ::setpreset(unsigned char npreset) { - const int PRESET_SIZE=1; - const int NUM_PRESETS=2; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 1; + const int NUM_PRESETS = 2; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //EQ 1 {67}, //EQ 2 {67} }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} -void EQ::changepar(const int &npar,const unsigned char &value) +void EQ::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; - }; - if (npar<10) return; + } + if(npar < 10) + return; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return; - int bp=npar%5;//band paramenter + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return; + int bp = npar % 5; //band paramenter REALTYPE tmp; - switch (bp) { + switch(bp) { case 0: - filter[nb].Ptype=value; - if (value>9) filter[nb].Ptype=0;//has to be changed if more filters will be added - if (filter[nb].Ptype!=0) { - filter[nb].l->settype(value-1); - filter[nb].r->settype(value-1); - }; + filter[nb].Ptype = value; + if(value > 9) + filter[nb].Ptype = 0; //has to be changed if more filters will be added + if(filter[nb].Ptype != 0) { + filter[nb].l->settype(value - 1); + filter[nb].r->settype(value - 1); + } break; case 1: - filter[nb].Pfreq=value; - tmp=600.0*pow(30.0,(value-64.0)/64.0); + filter[nb].Pfreq = value; + tmp = 600.0 * pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setfreq(tmp); filter[nb].r->setfreq(tmp); break; case 2: - filter[nb].Pgain=value; - tmp=30.0*(value-64.0)/64.0; + filter[nb].Pgain = value; + tmp = 30.0 * (value - 64.0) / 64.0; filter[nb].l->setgain(tmp); filter[nb].r->setgain(tmp); break; case 3: - filter[nb].Pq=value; - tmp=pow(30.0,(value-64.0)/64.0); + filter[nb].Pq = value; + tmp = pow(30.0, (value - 64.0) / 64.0); filter[nb].l->setq(tmp); filter[nb].r->setq(tmp); break; case 4: - filter[nb].Pstages=value; - if (value>=MAX_FILTER_STAGES) filter[nb].Pstages=MAX_FILTER_STAGES-1; + filter[nb].Pstages = value; + if(value >= MAX_FILTER_STAGES) + filter[nb].Pstages = MAX_FILTER_STAGES - 1; filter[nb].l->setstages(value); filter[nb].r->setstages(value); break; - }; -}; + } +} -unsigned char EQ::getpar(const int &npar)const +unsigned char EQ::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; - }; + } - if (npar<10) return(0); + if(npar < 10) + return 0; - int nb=(npar-10)/5;//number of the band (filter) - if (nb>=MAX_EQ_BANDS) return(0); - int bp=npar%5;//band paramenter - switch (bp) { + int nb = (npar - 10) / 5; //number of the band (filter) + if(nb >= MAX_EQ_BANDS) + return 0; + int bp = npar % 5; //band paramenter + switch(bp) { case 0: - return(filter[nb].Ptype); + return filter[nb].Ptype; break; case 1: - return(filter[nb].Pfreq); + return filter[nb].Pfreq; break; case 2: - return(filter[nb].Pgain); + return filter[nb].Pgain; break; case 3: - return(filter[nb].Pq); + return filter[nb].Pq; break; case 4: - return(filter[nb].Pstages); + return filter[nb].Pstages; break; - }; + } - return(0);//in case of bogus parameter number -}; + return 0; //in case of bogus parameter number +} REALTYPE EQ::getfreqresponse(REALTYPE freq) { - REALTYPE resp=1.0; - - for (int i=0;iH(freq); - }; - return(rap2dB(resp*outvolume)); -}; + REALTYPE resp = 1.0; + for(int i = 0; i < MAX_EQ_BANDS; i++) { + if(filter[i].Ptype == 0) + continue; + resp *= filter[i].l->H(freq); + } + return rap2dB(resp * outvolume); +} diff --git a/plugins/zynaddsubfx/src/Effects/EQ.h b/plugins/zynaddsubfx/src/Effects/EQ.h index 810dd6ee6..6f4130cd1 100644 --- a/plugins/zynaddsubfx/src/Effects/EQ.h +++ b/plugins/zynaddsubfx/src/Effects/EQ.h @@ -30,31 +30,29 @@ /**EQ Effect*/ class EQ:public Effect { -public: - EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~EQ(); - void out(REALTYPE *smpsl,REALTYPE *smpr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - REALTYPE getfreqresponse(REALTYPE freq); -private: - //Parameters - unsigned char Pvolume;/** #include "Echo.h" -Echo::Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) - : Effect(insertion_,efxoutl_,efxoutr_,NULL,0), - Pvolume(50),Ppanning(64),//Pdelay(60), - Plrdelay(100),Plrcross(100),Pfb(40),Phidamp(60), - lrdelay(0),delaySample(1),old(0.0) +Echo::Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), + Pvolume(50), Ppanning(64), //Pdelay(60), + Plrdelay(100), Plrcross(100), Pfb(40), Phidamp(60), + lrdelay(0), delaySample(1), old(0.0) { setpreset(Ppreset); } @@ -42,7 +44,7 @@ void Echo::cleanup() { delaySample.l().clear(); delaySample.r().clear(); - old=Stereo(0.0); + old = Stereo(0.0); } @@ -52,85 +54,91 @@ void Echo::cleanup() void Echo::initdelays() { /**\todo make this adjust insted of destroy old delays*/ - kl=0; - kr=0; - dl=(int)(1+delay.getiVal()*SAMPLE_RATE-lrdelay); - if (dl<1) dl=1; - dr=(int)(1+delay.getiVal()*SAMPLE_RATE+lrdelay); - if (dr<1) dr=1; + kl = 0; + kr = 0; + dl = (int)(1 + delay.getiVal() * SAMPLE_RATE - lrdelay); + if(dl < 1) + dl = 1; + dr = (int)(1 + delay.getiVal() * SAMPLE_RATE + lrdelay); + if(dr < 1) + dr = 1; - delaySample.l()=AuSample(dl); - delaySample.r()=AuSample(dr); + delaySample.l() = AuSample(dl); + delaySample.r() = AuSample(dr); - old=Stereo(0.0); + old = Stereo(0.0); } /* * Effect output */ -void Echo::out(REALTYPE *const smpsl,REALTYPE *const smpsr) +void Echo::out(REALTYPE *const smpsl, REALTYPE *const smpsr) { - Stereo input(AuSample(SOUND_BUFFER_SIZE,smpsl),AuSample(SOUND_BUFFER_SIZE,smpsr)); + Stereo input(AuSample(SOUND_BUFFER_SIZE, smpsl), AuSample( + SOUND_BUFFER_SIZE, + smpsr)); out(input); } void Echo::out(const Stereo &input) { //void Echo::out(const Stereo & input){ //ideal - REALTYPE l,r,ldl,rdl;/**\todo move l+r->? ldl+rdl->?*/ + REALTYPE l, r, ldl, rdl; /**\todo move l+r->? ldl+rdl->?*/ - for (int i=0;i=dl) kl=0; - if (++kr>=dr) kr=0; - }; + delaySample.l()[kl] = ldl = ldl * hidamp + old.l() * (1.0 - hidamp); + delaySample.r()[kr] = rdl = rdl * hidamp + old.r() * (1.0 - hidamp); + old.l() = ldl; + old.r() = rdl; + if(++kl >= dl) + kl = 0; + if(++kr >= dr) + kr = 0; + } } /* * Parameter control */ -void Echo::setvolume(const unsigned char & Pvolume) +void Echo::setvolume(const unsigned char &Pvolume) { - this->Pvolume=Pvolume; - - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - }; - if (Pvolume==0) cleanup(); + this->Pvolume = Pvolume; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else + volume = outvolume = Pvolume / 127.0; + ; + if(Pvolume == 0) + cleanup(); } -void Echo::setpanning(const unsigned char & Ppanning) +void Echo::setpanning(const unsigned char &Ppanning) { - this->Ppanning=Ppanning; - panning=(Ppanning+0.5)/127.0; + this->Ppanning = Ppanning; + panning = (Ppanning + 0.5) / 127.0; } -void Echo::setdelay(const unsigned char & Pdelay) +void Echo::setdelay(const unsigned char &Pdelay) { delay.setmVal(Pdelay); //this->Pdelay=Pdelay; @@ -138,71 +146,76 @@ void Echo::setdelay(const unsigned char & Pdelay) initdelays(); } -void Echo::setlrdelay(const unsigned char & Plrdelay) +void Echo::setlrdelay(const unsigned char &Plrdelay) { REALTYPE tmp; - this->Plrdelay=Plrdelay; - tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE; - if (Plrdelay<64.0) tmp=-tmp; - lrdelay=(int) tmp; + this->Plrdelay = Plrdelay; + tmp = + (pow(2, fabs(Plrdelay - 64.0) / 64.0 * 9) - 1.0) / 1000.0 * SAMPLE_RATE; + if(Plrdelay < 64.0) + tmp = -tmp; + lrdelay = (int) tmp; initdelays(); } -void Echo::setlrcross(const unsigned char & Plrcross) +void Echo::setlrcross(const unsigned char &Plrcross) { - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0*1.0; + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0 * 1.0; } -void Echo::setfb(const unsigned char & Pfb) +void Echo::setfb(const unsigned char &Pfb) { - this->Pfb=Pfb; - fb=Pfb/128.0; + this->Pfb = Pfb; + fb = Pfb / 128.0; } -void Echo::sethidamp(const unsigned char & Phidamp) +void Echo::sethidamp(const unsigned char &Phidamp) { - this->Phidamp=Phidamp; - hidamp=1.0-Phidamp/127.0; + this->Phidamp = Phidamp; + hidamp = 1.0 - Phidamp / 127.0; } void Echo::setpreset(unsigned char npreset) { /**\todo see if the preset array can be replaced with a struct or a class*/ - const int PRESET_SIZE=7; - const int NUM_PRESETS=9; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + const int PRESET_SIZE = 7; + const int NUM_PRESETS = 9; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { //Echo 1 - {67,64,35,64,30,59,0}, + {67, 64, 35, 64, 30, 59, 0 }, //Echo 2 - {67,64,21,64,30,59,0}, + {67, 64, 21, 64, 30, 59, 0 }, //Echo 3 - {67,75,60,64,30,59,10}, + {67, 75, 60, 64, 30, 59, 10 }, //Simple Echo - {67,60,44,64,30,0,0}, + {67, 60, 44, 64, 30, 0, 0 }, //Canyon - {67,60,102,50,30,82,48}, + {67, 60, 102, 50, 30, 82, 48 }, //Panning Echo 1 - {67,64,44,17,0,82,24}, + {67, 64, 44, 17, 0, 82, 24 }, //Panning Echo 2 - {81,60,46,118,100,68,18}, + {81, 60, 46, 118, 100, 68, 18 }, //Panning Echo 3 - {81,60,26,100,127,67,36}, + {81, 60, 26, 100, 127, 67, 36 }, //Feedback Echo - {62,64,28,64,100,90,55} + {62, 64, 28, 64, 100, 90, 55 } }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion) + setvolume(presets[npreset][0] / 2); //lower the volume if this is insertion effect + Ppreset = npreset; } -void Echo::changepar(const int & npar,const unsigned char & value) +void Echo::changepar(const int &npar, const unsigned char &value) { - switch (npar) { + switch(npar) { case 0: setvolume(value); break; @@ -224,34 +237,34 @@ void Echo::changepar(const int & npar,const unsigned char & value) case 6: sethidamp(value); break; - }; + } } -unsigned char Echo::getpar(const int & npar)const +unsigned char Echo::getpar(const int &npar) const { - switch (npar) { + switch(npar) { case 0: - return(Pvolume); + return Pvolume; break; case 1: - return(Ppanning); + return Ppanning; break; case 2: - return(delay.getmVal()); + return delay.getmVal(); break; case 3: - return(Plrdelay); + return Plrdelay; break; case 4: - return(Plrcross); + return Plrcross; break; case 5: - return(Pfb); + return Pfb; break; case 6: - return(Phidamp); + return Phidamp; break; - }; - return(0);// in case of bogus parameter number + } + return 0; // in case of bogus parameter number } diff --git a/plugins/zynaddsubfx/src/Effects/Echo.h b/plugins/zynaddsubfx/src/Effects/Echo.h index 5ed429609..4dbe40925 100644 --- a/plugins/zynaddsubfx/src/Effects/Echo.h +++ b/plugins/zynaddsubfx/src/Effects/Echo.h @@ -32,105 +32,107 @@ /**Echo Effect*/ class Echo:public Effect { -public: + public: - /** - * The Constructor For Echo - * @param insertion_ integer to determine if Echo is an insertion effect - * or not - * @param efxoutl_ Effect out Left Channel - * @param efxoutr_ Effect out Right Channel - * @return An initialized Echo Object - */ - Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); + /** + * The Constructor For Echo + * @param insertion_ integer to determine if Echo is an insertion effect + * or not + * @param efxoutl_ Effect out Left Channel + * @param efxoutr_ Effect out Right Channel + * @return An initialized Echo Object + */ + Echo(const int &insertion_, + REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_); - /** - * The destructor - */ - ~Echo(); + /** + * The destructor + */ + ~Echo(); - /** - * Outputs the echo to efxoutl and efxoutr - * @param smpsl Sample from Left channel - * @param smpsr Sample from Right channel - * \todo try to figure out if smpsl should be const *const - * or not (It should be) - */ - void out(REALTYPE *const smpsl,REALTYPE *const smpr); - void out(const Stereo &input); + /** + * Outputs the echo to efxoutl and efxoutr + * @param smpsl Sample from Left channel + * @param smpsr Sample from Right channel + * \todo try to figure out if smpsl should be const *const + * or not (It should be) + */ + void out(REALTYPE *const smpsl, REALTYPE *const smpr); + void out(const Stereo &input); - /** - * Sets the state of Echo to the specified preset - * @param npreset number of chosen preset - */ - void setpreset(unsigned char npreset); + /** + * Sets the state of Echo to the specified preset + * @param npreset number of chosen preset + */ + void setpreset(unsigned char npreset); - /** - * Sets the value of the chosen variable - * - * The possible parameters are: - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @param value the new value - */ - void changepar(const int & npar,const unsigned char & value); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar, const unsigned char &value); - /** - * Gets the specified parameter - * - * The possible parameters are - * -# Volume - * -# Panning - * -# Delay - * -# L/R Delay - * -# L/R Crossover - * -# Feedback - * -# Dampening - * @param npar number of chosen parameter - * @return value of parameter - */ - unsigned char getpar(const int & npar)const; + /** + * Gets the specified parameter + * + * The possible parameters are + * -# Volume + * -# Panning + * -# Delay + * -# L/R Delay + * -# L/R Crossover + * -# Feedback + * -# Dampening + * @param npar number of chosen parameter + * @return value of parameter + */ + unsigned char getpar(const int &npar) const; - int getnumparams(); + int getnumparams(); - /**Zeros out the state of the Echo*/ - void cleanup(); + /**Zeros out the state of the Echo*/ + void cleanup(); - /**\todo This function needs to be implemented or the prototype should be removed*/ - void setdryonly(); -private: - //Parameters - char Pvolume;/**<#1 Volume or Dry/Wetness*/ - char Ppanning;/**<#2 Panning*/ - DelayCtl delay;/**<#3 Delay of the Echo*/ - char Plrdelay;/**<#4 L/R delay difference*/ - char Plrcross;/**<#5 L/R Mixing*/ - char Pfb;/**<#6Feedback*/ - char Phidamp;/**<#7Dampening of the Echo*/ + /**\todo This function needs to be implemented or the prototype should be removed*/ + void setdryonly(); + private: + //Parameters + char Pvolume; /**<#1 Volume or Dry/Wetness*/ + char Ppanning; /**<#2 Panning*/ + DelayCtl delay; /**<#3 Delay of the Echo*/ + char Plrdelay; /**<#4 L/R delay difference*/ + char Plrcross; /**<#5 L/R Mixing*/ + char Pfb; /**<#6Feedback*/ + char Phidamp; /**<#7Dampening of the Echo*/ - void setvolume(const unsigned char & Pvolume); - void setpanning(const unsigned char & Ppanning); - void setdelay(const unsigned char & Pdelay); - void setlrdelay(const unsigned char & Plrdelay); - void setlrcross(const unsigned char & Plrcross); - void setfb(const unsigned char & Pfb); - void sethidamp(const unsigned char & Phidamp); + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdelay(const unsigned char &Pdelay); + void setlrdelay(const unsigned char &Plrdelay); + void setlrcross(const unsigned char &Plrcross); + void setfb(const unsigned char &Pfb); + void sethidamp(const unsigned char &Phidamp); - //Real Parameters - REALTYPE panning,lrcross,fb,hidamp; //needs better names - int dl,dr,lrdelay; //needs better names + //Real Parameters + REALTYPE panning, lrcross, fb, hidamp; //needs better names + int dl, dr, lrdelay; //needs better names - void initdelays(); - Stereo delaySample; - Stereo old; + void initdelays(); + Stereo delaySample; + Stereo old; - int kl,kr; + int kl, kr; }; #endif diff --git a/plugins/zynaddsubfx/src/Effects/Effect.cpp b/plugins/zynaddsubfx/src/Effects/Effect.cpp index b0b4dac30..0a17ebdc4 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.cpp +++ b/plugins/zynaddsubfx/src/Effects/Effect.cpp @@ -23,8 +23,9 @@ #include "Effect.h" -Effect::Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_) - :Ppreset(Ppreset_),efxoutl(efxoutl_),efxoutr(efxoutr_), - filterpars(filterpars_),insertion(insertion_) {} +Effect::Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_) + :Ppreset(Ppreset_), efxoutl(efxoutl_), efxoutr(efxoutr_), + filterpars(filterpars_), insertion(insertion_) {} + diff --git a/plugins/zynaddsubfx/src/Effects/Effect.h b/plugins/zynaddsubfx/src/Effects/Effect.h index 0da3d8317..7f769ead8 100644 --- a/plugins/zynaddsubfx/src/Effects/Effect.h +++ b/plugins/zynaddsubfx/src/Effects/Effect.h @@ -31,71 +31,71 @@ /**this class is inherited by the all effects(Reverb, Echo, ..)*/ class Effect { -public: - /** - * Effect Constructor - * @param insertion_ 1 when it is an insertion Effect and 0 when it - * is not an insertion Effect - * @param efxoutl_ Effect output buffer Left channel - * @param efxoutr_ Effect output buffer Right channel - * @param filterpars_ pointer to FilterParams array - * @param Ppreset_ chosen preset - * @return Initialized Effect object*/ - Effect(bool insertion_,REALTYPE *const efxoutl_, - REALTYPE *const efxoutr_,FilterParams *filterpars_, - const unsigned char & Ppreset_); - /**Deconstructor - * - * Deconstructs the Effect and releases any resouces that it has - * allocated for itself*/ - virtual ~Effect() {}; - /** - * Choose a preset - * @param npreset number of chosen preset*/ - virtual void setpreset(unsigned char npreset)=0; - /**Change parameter npar to value - * @param npar chosen parameter - * @param value chosen new value*/ - virtual void changepar(const int &npar,const unsigned char &value)=0; - /**Get the value of parameter npar - * @param npar chosen parameter - * @return the value of the parameter in an unsigned char or 0 if it - * does not exist*/ - virtual unsigned char getpar(const int &npar)const=0; - /**Output result of effect based on the given buffers - * - * This method should result in the effect generating its results - * and placing them into the efxoutl and efxoutr buffers. - * Every Effect should overide this method. - * - * @param smpsl Input buffer for the Left channel - * @param smpsr Input buffer for the Right channel - */ - virtual void out(REALTYPE *const smpsl,REALTYPE *const smpsr)=0; - /**Reset the state of the effect*/ - virtual void cleanup() {}; - /**This is only used for EQ (for user interface)*/ - virtual REALTYPE getfreqresponse(REALTYPE freq) { - return (0); - }; + public: + /** + * Effect Constructor + * @param insertion_ 1 when it is an insertion Effect and 0 when it + * is not an insertion Effect + * @param efxoutl_ Effect output buffer Left channel + * @param efxoutr_ Effect output buffer Right channel + * @param filterpars_ pointer to FilterParams array + * @param Ppreset_ chosen preset + * @return Initialized Effect object*/ + Effect(bool insertion_, REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_, FilterParams *filterpars_, + const unsigned char &Ppreset_); + /**Deconstructor + * + * Deconstructs the Effect and releases any resouces that it has + * allocated for itself*/ + virtual ~Effect() {} + /** + * Choose a preset + * @param npreset number of chosen preset*/ + virtual void setpreset(unsigned char npreset) = 0; + /**Change parameter npar to value + * @param npar chosen parameter + * @param value chosen new value*/ + virtual void changepar(const int &npar, const unsigned char &value) = 0; + /**Get the value of parameter npar + * @param npar chosen parameter + * @return the value of the parameter in an unsigned char or 0 if it + * does not exist*/ + virtual unsigned char getpar(const int &npar) const = 0; + /**Output result of effect based on the given buffers + * + * This method should result in the effect generating its results + * and placing them into the efxoutl and efxoutr buffers. + * Every Effect should overide this method. + * + * @param smpsl Input buffer for the Left channel + * @param smpsr Input buffer for the Right channel + */ + virtual void out(REALTYPE *const smpsl, REALTYPE *const smpsr) = 0; + /**Reset the state of the effect*/ + virtual void cleanup() {} + /**This is only used for EQ (for user interface)*/ + virtual REALTYPE getfreqresponse(REALTYPE freq) { + return 0; + } - unsigned char Ppreset;/**0.49999999) incx=0.499999999; //Limit the Frequency + REALTYPE lfofreq = (pow(2, Pfreq / 127.0 * 10.0) - 1.0) * 0.03; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + if(incx > 0.49999999) + incx = 0.499999999; //Limit the Frequency - lfornd=Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; - if (PLFOtype>1) PLFOtype=1;//this has to be updated if more lfo's are added - lfotype=PLFOtype; + if(PLFOtype > 1) + PLFOtype = 1; //this has to be updated if more lfo's are added + lfotype = PLFOtype; - xr=fmod(xl+(Pstereo-64.0)/127.0+1.0,1.0); -}; + xr = fmod(xl + (Pstereo - 64.0) / 127.0 + 1.0, 1.0); +} /* @@ -74,44 +78,50 @@ void EffectLFO::updateparams() REALTYPE EffectLFO::getlfoshape(REALTYPE x) { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //EffectLFO_TRIANGLE - if ((x>0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x > 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; - /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ + /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ default: - out=cos(x*2*PI);//EffectLFO_SINE - }; - return(out); -}; + out = cos(x * 2 * PI); //EffectLFO_SINE + } + return out; +} /* * LFO output */ -void EffectLFO::effectlfoout(REALTYPE *outl,REALTYPE *outr) +void EffectLFO::effectlfoout(REALTYPE *outl, REALTYPE *outr) { REALTYPE out; - out=getlfoshape(xl); - if ((lfotype==0)||(lfotype==1)) out*=(ampl1+xl*(ampl2-ampl1)); - xl+=incx; - if (xl>1.0) { - xl-=1.0; - ampl1=ampl2; - ampl2=(1.0-lfornd)+lfornd*RND; - }; - *outl=(out+1.0)*0.5; + out = getlfoshape(xl); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampl1 + xl * (ampl2 - ampl1)); + xl += incx; + if(xl > 1.0) { + xl -= 1.0; + ampl1 = ampl2; + ampl2 = (1.0 - lfornd) + lfornd * RND; + } + *outl = (out + 1.0) * 0.5; - out=getlfoshape(xr); - if ((lfotype==0)||(lfotype==1)) out*=(ampr1+xr*(ampr2-ampr1)); - xr+=incx; - if (xr>1.0) { - xr-=1.0; - ampr1=ampr2; - ampr2=(1.0-lfornd)+lfornd*RND; - }; - *outr=(out+1.0)*0.5; -}; + out = getlfoshape(xr); + if((lfotype == 0) || (lfotype == 1)) + out *= (ampr1 + xr * (ampr2 - ampr1)); + xr += incx; + if(xr > 1.0) { + xr -= 1.0; + ampr1 = ampr2; + ampr2 = (1.0 - lfornd) + lfornd * RND; + } + *outr = (out + 1.0) * 0.5; +} diff --git a/plugins/zynaddsubfx/src/Effects/EffectLFO.h b/plugins/zynaddsubfx/src/Effects/EffectLFO.h index 54a595110..cc14d6652 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectLFO.h +++ b/plugins/zynaddsubfx/src/Effects/EffectLFO.h @@ -28,24 +28,24 @@ * \todo see if this should inherit LFO*/ class EffectLFO { -public: - EffectLFO(); - ~EffectLFO(); - void effectlfoout(REALTYPE *outl,REALTYPE *outr); - void updateparams(); - unsigned char Pfreq; - unsigned char Prandomness; - unsigned char PLFOtype; - unsigned char Pstereo;//"64"=0 -private: - REALTYPE getlfoshape(REALTYPE x); + public: + EffectLFO(); + ~EffectLFO(); + void effectlfoout(REALTYPE *outl, REALTYPE *outr); + void updateparams(); + unsigned char Pfreq; + unsigned char Prandomness; + unsigned char PLFOtype; + unsigned char Pstereo; //"64"=0 + private: + REALTYPE getlfoshape(REALTYPE x); - REALTYPE xl,xr; - REALTYPE incx; - REALTYPE ampl1,ampl2,ampr1,ampr2;//necessary for "randomness" - REALTYPE lfointensity; - REALTYPE lfornd; - char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ + REALTYPE xl, xr; + REALTYPE incx; + REALTYPE ampl1, ampl2, ampr1, ampr2; //necessary for "randomness" + REALTYPE lfointensity; + REALTYPE lfornd; + char lfotype; /**\todo GET RID OF CHAR (replace with short or enum)*/ }; diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp b/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp index 081101184..cbb44c02f 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.cpp @@ -22,11 +22,11 @@ #include "EffectMgr.h" -EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) - :insertion(insertion_), - efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), - efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), - filterpars(NULL),nefx(0),efx(NULL),mutex(mutex_),dryonly(false) +EffectMgr::EffectMgr(int insertion_, pthread_mutex_t *mutex_) + :insertion(insertion_), + efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), + efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), + filterpars(NULL), nefx(0), efx(NULL), mutex(mutex_), dryonly(false) { setpresettype("Peffect"); /**\todo Figure out what this is doing * , as it might be another leaky abstraction.*/ @@ -36,10 +36,10 @@ EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) // mutex=mutex_; // efxoutl=new REALTYPE[SOUND_BUFFER_SIZE]; // efxoutr=new REALTYPE[SOUND_BUFFER_SIZE]; - for (int i=0;ifilterpars; + if(efx != NULL) + filterpars = efx->filterpars; } /* @@ -112,7 +116,7 @@ void EffectMgr::changeeffect(int nefx_) */ int EffectMgr::geteffect() { - return (nefx); + return nefx; } /* @@ -120,7 +124,8 @@ int EffectMgr::geteffect() */ void EffectMgr::cleanup() { - if (efx!=NULL) efx->cleanup(); + if(efx != NULL) + efx->cleanup(); } @@ -130,8 +135,10 @@ void EffectMgr::cleanup() unsigned char EffectMgr::getpreset() { - if (efx!=NULL) return(efx->Ppreset); - else return(0); + if(efx != NULL) + return efx->Ppreset; + else + return 0; } /* @@ -139,7 +146,8 @@ unsigned char EffectMgr::getpreset() */ void EffectMgr::changepreset_nolock(unsigned char npreset) { - if (efx!=NULL) efx->setpreset(npreset); + if(efx != NULL) + efx->setpreset(npreset); } /* @@ -156,19 +164,20 @@ void EffectMgr::changepreset(unsigned char npreset) /* * Change a parameter of the current effect */ -void EffectMgr::seteffectpar_nolock(int npar,unsigned char value) +void EffectMgr::seteffectpar_nolock(int npar, unsigned char value) { - if (efx==NULL) return; - efx->changepar(npar,value); + if(efx == NULL) + return; + efx->changepar(npar, value); } /* * Change a parameter of the current effect (with thread locking) */ -void EffectMgr::seteffectpar(int npar,unsigned char value) +void EffectMgr::seteffectpar(int npar, unsigned char value) { pthread_mutex_lock(mutex); - seteffectpar_nolock(npar,value); + seteffectpar_nolock(npar, value); pthread_mutex_unlock(mutex); } @@ -177,80 +186,85 @@ void EffectMgr::seteffectpar(int npar,unsigned char value) */ unsigned char EffectMgr::geteffectpar(int npar) { - if (efx==NULL) return(0); - return(efx->getpar(npar)); + if(efx == NULL) + return 0; + return efx->getpar(npar); } /* * Apply the effect */ -void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr) +void EffectMgr::out(REALTYPE *smpsl, REALTYPE *smpsr) { int i; - if (efx==NULL) { - if (insertion==0) - for (i=0;iout(smpsl,smpsr); + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + smpsl[i] += denormalkillbuf[i]; + smpsr[i] += denormalkillbuf[i]; + efxoutl[i] = 0.0; + efxoutr[i] = 0.0; + } + efx->out(smpsl, smpsr); - REALTYPE volume=efx->volume; + REALTYPE volume = efx->volume; - if (nefx==7) {//this is need only for the EQ effect + if(nefx == 7) { //this is need only for the EQ effect /**\todo figure out why*/ - for (i=0;ioutvolume); + if(efx == NULL) + return 1.0; + else + return efx->outvolume; } @@ -268,65 +284,72 @@ REALTYPE EffectMgr::sysefxgetvolume() */ REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq) { - if (nefx==7) return(efx->getfreqresponse(freq)); - else return(0.0); + if(nefx == 7) + return efx->getfreqresponse(freq); + else + return 0.0; } void EffectMgr::setdryonly(bool value) { - dryonly=value; + dryonly = value; } void EffectMgr::add2XML(XMLwrapper *xml) { - xml->addpar("type",geteffect()); + xml->addpar("type", geteffect()); - if ((efx==NULL)||(geteffect()==0)) return; - xml->addpar("preset",efx->Ppreset); + if((efx == NULL) || (geteffect() == 0)) + return; + xml->addpar("preset", efx->Ppreset); xml->beginbranch("EFFECT_PARAMETERS"); - for (int n=0;n<128;n++) { /**\todo evaluate who should oversee saving - * and loading of parameters*/ - int par=geteffectpar(n); - if (par==0) continue; - xml->beginbranch("par_no",n); - xml->addpar("par",par); + for(int n = 0; n < 128; n++) { + /**\todo evaluate who should oversee saving + * and loading of parameters*/ + int par = geteffectpar(n); + if(par == 0) + continue; + xml->beginbranch("par_no", n); + xml->addpar("par", par); xml->endbranch(); - }; - if (filterpars!=NULL) { + } + if(filterpars != NULL) { xml->beginbranch("FILTER"); filterpars->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); } void EffectMgr::getfromXML(XMLwrapper *xml) { - changeeffect(xml->getpar127("type",geteffect())); + changeeffect(xml->getpar127("type", geteffect())); - if ((efx==NULL)||(geteffect()==0)) return; + if((efx == NULL) || (geteffect() == 0)) + return; - efx->Ppreset=xml->getpar127("preset",efx->Ppreset); + efx->Ppreset = xml->getpar127("preset", efx->Ppreset); - if (xml->enterbranch("EFFECT_PARAMETERS")) { - for (int n=0;n<128;n++) { - seteffectpar_nolock(n,0);//erase effect parameter - if (xml->enterbranch("par_no",n)==0) continue; + if(xml->enterbranch("EFFECT_PARAMETERS")) { + for(int n = 0; n < 128; n++) { + seteffectpar_nolock(n, 0); //erase effect parameter + if(xml->enterbranch("par_no", n) == 0) + continue; - int par=geteffectpar(n); - seteffectpar_nolock(n,xml->getpar127("par",par)); + int par = geteffectpar(n); + seteffectpar_nolock(n, xml->getpar127("par", par)); xml->exitbranch(); - }; - if (filterpars!=NULL) { - if (xml->enterbranch("FILTER")) { + } + if(filterpars != NULL) { + if(xml->enterbranch("FILTER")) { filterpars->getfromXML(xml); xml->exitbranch(); - }; - }; + } + } xml->exitbranch(); - }; + } cleanup(); } diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.h b/plugins/zynaddsubfx/src/Effects/EffectMgr.h index dd5d52ce6..2a1257707 100644 --- a/plugins/zynaddsubfx/src/Effects/EffectMgr.h +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.h @@ -41,62 +41,62 @@ /**Effect manager, an interface betwen the program and effects*/ class EffectMgr:public Presets { -public: - EffectMgr(int insertion_,pthread_mutex_t *mutex_); - ~EffectMgr(); + public: + EffectMgr(int insertion_, pthread_mutex_t *mutex_); + ~EffectMgr(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - void out(REALTYPE *smpsl,REALTYPE *smpsr); + void out(REALTYPE *smpsl, REALTYPE *smpsr); - void setdryonly(bool value); + void setdryonly(bool value); - /**get the output(to speakers) volume of the systemeffect*/ - REALTYPE sysefxgetvolume(); + /**get the output(to speakers) volume of the systemeffect*/ + REALTYPE sysefxgetvolume(); - void cleanup();/** -#include "Phaser.h" -#define PHASER_LFO_SHAPE 2 - -Phaser::Phaser(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),old(1),oldgain(0.0) -{ - setpreset(Ppreset); - cleanup(); -}; - -Phaser::~Phaser() -{ -}; - - -/* - * Effect output - */ -void Phaser::out(REALTYPE *smpsl,REALTYPE *smpsr) -{ - int i,j; - REALTYPE lfol,lfor,lgain,rgain,tmp; - - lfo.effectlfoout(&lfol,&lfor); - lgain=lfol; - rgain=lfor; - lgain=(exp(lgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - rgain=(exp(rgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); - - - lgain=1.0-phase*(1.0-depth)-(1.0-phase)*lgain*depth; - rgain=1.0-phase*(1.0-depth)-(1.0-phase)*rgain*depth; - - if (lgain>1.0) lgain=1.0; - else if (lgain<0.0) lgain=0.0; - if (rgain>1.0) rgain=1.0; - else if (rgain<0.0) rgain=0.0; - - for (i=0;i(lgain,rgain); - - if (Poutsub!=0) - for (i=0;i(0.0); - old.l().clear(); - old.r().clear(); -}; - -/* - * Parameter control - */ -void Phaser::setdepth(const unsigned char &Pdepth) -{ - this->Pdepth=Pdepth; - depth=(Pdepth/127.0); -}; - - -void Phaser::setfb(const unsigned char &Pfb) -{ - this->Pfb=Pfb; - fb=(Pfb-64.0)/64.1; -}; - -void Phaser::setvolume(const unsigned char &Pvolume) -{ - this->Pvolume=Pvolume; - outvolume=Pvolume/127.0; - if (insertion==0) volume=1.0; - else volume=outvolume; -}; - -void Phaser::setpanning(const unsigned char &Ppanning) -{ - this->Ppanning=Ppanning; - panning=Ppanning/127.0; -}; - -void Phaser::setlrcross(const unsigned char &Plrcross) -{ - this->Plrcross=Plrcross; - lrcross=Plrcross/127.0; -}; - -void Phaser::setstages(const unsigned char &Pstages) -{ - if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1; - else this->Pstages=Pstages; - old=Stereo(Pstages*2); - cleanup(); -}; - -void Phaser::setphase(const unsigned char &Pphase) -{ - this->Pphase=Pphase; - phase=(Pphase/127.0); -}; - - -void Phaser::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=12; - const int NUM_PRESETS=6; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Phaser1 - {64,64,36,0,0,64,110,64,1,0,0,20}, - //Phaser2 - {64,64,35,0,0,88,40,64,3,0,0,20}, - //Phaser3 - {64,64,31,0,0,66,68,107,2,0,0,20}, - //Phaser4 - {39,64,22,0,0,66,67,10,5,0,1,20}, - //Phaser5 - {64,64,20,0,1,110,67,78,10,0,0,20}, - //Phaser6 - {64,64,53,100,0,58,37,78,3,0,0,20} - }; - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n1) Poutsub=1; - else Poutsub=value; - break; - case 11: - setphase(value); - break; - }; -}; - -unsigned char Phaser::getpar(const int &npar)const -{ - switch (npar) { - case 0: - return(Pvolume); - break; - case 1: - return(Ppanning); - break; - case 2: - return(lfo.Pfreq); - break; - case 3: - return(lfo.Prandomness); - break; - case 4: - return(lfo.PLFOtype); - break; - case 5: - return(lfo.Pstereo); - break; - case 6: - return(Pdepth); - break; - case 7: - return(Pfb); - break; - case 8: - return(Pstages); - break; - case 9: - return(Plrcross); - break; - case 10: - return(Poutsub); - break; - case 11: - return(Pphase); - break; - default: - return (0); - }; - -}; - +/* + ZynAddSubFX - a software synthesizer + + Phaser.C - Phaser effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Phaser.h" +#define PHASER_LFO_SHAPE 2 + +Phaser::Phaser(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), old(1), oldgain(0.0) +{ + setpreset(Ppreset); + cleanup(); +} + +Phaser::~Phaser() +{} + + +/* + * Effect output + */ +void Phaser::out(REALTYPE *smpsl, REALTYPE *smpsr) +{ + int i, j; + REALTYPE lfol, lfor, lgain, rgain, tmp; + + lfo.effectlfoout(&lfol, &lfor); + lgain = lfol; + rgain = lfor; + lgain = (exp(lgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + rgain = (exp(rgain * PHASER_LFO_SHAPE) - 1) / (exp(PHASER_LFO_SHAPE) - 1.0); + + + lgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * lgain * depth; + rgain = 1.0 - phase * (1.0 - depth) - (1.0 - phase) * rgain * depth; + + if(lgain > 1.0) + lgain = 1.0; + else + if(lgain < 0.0) + lgain = 0.0; + if(rgain > 1.0) + rgain = 1.0; + else + if(rgain < 0.0) + rgain = 0.0; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE x = (REALTYPE) i / SOUND_BUFFER_SIZE; + REALTYPE x1 = 1.0 - x; + REALTYPE gl = lgain * x + oldgain.left() * x1; + REALTYPE gr = rgain * x + oldgain.right() * x1; + REALTYPE inl = smpsl[i] * panning + fbl; + REALTYPE inr = smpsr[i] * (1.0 - panning) + fbr; + + //Left channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.left()[j]; + old.left()[j] = gl * tmp + inl; + inl = tmp - gl *old.left()[j]; + } + //Right channel + for(j = 0; j < Pstages * 2; j++) { //Phasing routine + tmp = old.right()[j]; + old.right()[j] = gr * tmp + inr; + inr = tmp - gr *old.right()[j]; + } + //Left/Right crossing + REALTYPE l = inl; + REALTYPE r = inr; + inl = l * (1.0 - lrcross) + r * lrcross; + inr = r * (1.0 - lrcross) + l * lrcross; + + fbl = inl * fb; + fbr = inr * fb; + efxoutl[i] = inl; + efxoutr[i] = inr; + } + + oldgain = Stereo(lgain, rgain); + + if(Poutsub != 0) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= -1.0; + efxoutr[i] *= -1.0; + } + ; +} + +/* + * Cleanup the effect + */ +void Phaser::cleanup() +{ + fbl = 0.0; + fbr = 0.0; + oldgain = Stereo(0.0); + old.l().clear(); + old.r().clear(); +} + +/* + * Parameter control + */ +void Phaser::setdepth(const unsigned char &Pdepth) +{ + this->Pdepth = Pdepth; + depth = (Pdepth / 127.0); +} + + +void Phaser::setfb(const unsigned char &Pfb) +{ + this->Pfb = Pfb; + fb = (Pfb - 64.0) / 64.1; +} + +void Phaser::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + outvolume = Pvolume / 127.0; + if(insertion == 0) + volume = 1.0; + else + volume = outvolume; +} + +void Phaser::setpanning(const unsigned char &Ppanning) +{ + this->Ppanning = Ppanning; + panning = Ppanning / 127.0; +} + +void Phaser::setlrcross(const unsigned char &Plrcross) +{ + this->Plrcross = Plrcross; + lrcross = Plrcross / 127.0; +} + +void Phaser::setstages(const unsigned char &Pstages) +{ + if(Pstages >= MAX_PHASER_STAGES) + this->Pstages = MAX_PHASER_STAGES - 1; + else + this->Pstages = Pstages; + old = Stereo(Pstages * 2); + cleanup(); +} + +void Phaser::setphase(const unsigned char &Pphase) +{ + this->Pphase = Pphase; + phase = (Pphase / 127.0); +} + + +void Phaser::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 12; + const int NUM_PRESETS = 6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Phaser1 + {64, 64, 36, 0, 0, 64, 110, 64, 1, 0, 0, 20}, + //Phaser2 + {64, 64, 35, 0, 0, 88, 40, 64, 3, 0, 0, 20}, + //Phaser3 + {64, 64, 31, 0, 0, 66, 68, 107, 2, 0, 0, 20}, + //Phaser4 + {39, 64, 22, 0, 0, 66, 67, 10, 5, 0, 1, 20}, + //Phaser5 + {64, 64, 20, 0, 1, 110, 67, 78, 10, 0, 0, 20}, + //Phaser6 + {64, 64, 53, 100, 0, 58, 37, 78, 3, 0, 0, 20} + }; + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + Ppreset = npreset; +} + + +void Phaser::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpanning(value); + break; + case 2: + lfo.Pfreq = value; + lfo.updateparams(); + break; + case 3: + lfo.Prandomness = value; + lfo.updateparams(); + break; + case 4: + lfo.PLFOtype = value; + lfo.updateparams(); + break; + case 5: + lfo.Pstereo = value; + lfo.updateparams(); + break; + case 6: + setdepth(value); + break; + case 7: + setfb(value); + break; + case 8: + setstages(value); + break; + case 9: + setlrcross(value); + break; + case 10: + if(value > 1) + Poutsub = 1; + else + Poutsub = value; + break; + case 11: + setphase(value); + break; + } +} + +unsigned char Phaser::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppanning; + break; + case 2: + return lfo.Pfreq; + break; + case 3: + return lfo.Prandomness; + break; + case 4: + return lfo.PLFOtype; + break; + case 5: + return lfo.Pstereo; + break; + case 6: + return Pdepth; + break; + case 7: + return Pfb; + break; + case 8: + return Pstages; + break; + case 9: + return Plrcross; + break; + case 10: + return Poutsub; + break; + case 11: + return Pphase; + break; + default: + return 0; + } +} + diff --git a/plugins/zynaddsubfx/src/Effects/Phaser.h b/plugins/zynaddsubfx/src/Effects/Phaser.h index 700af3dfc..30370a8c6 100644 --- a/plugins/zynaddsubfx/src/Effects/Phaser.h +++ b/plugins/zynaddsubfx/src/Effects/Phaser.h @@ -1,76 +1,76 @@ -/* - ZynAddSubFX - a software synthesizer - - Phaser.h - Phaser effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef PHASER_H -#define PHASER_H -#include "../globals.h" -#include "../Misc/Stereo.h" -#include "../Samples/AuSample.h" -#include "Effect.h" -#include "EffectLFO.h" - -#define MAX_PHASER_STAGES 12 -/**Phaser Effect*/ -class Phaser:public Effect -{ -public: - Phaser(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Phaser(); - void out(REALTYPE *smpsl,REALTYPE *smpsr); - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - void cleanup(); - void setdryonly(); - -private: - //Parametrii Phaser - EffectLFO lfo;/** old; - //REALTYPE oldlgain,oldrgain; - Stereo oldgain; -}; - -#endif - +/* + ZynAddSubFX - a software synthesizer + + Phaser.h - Phaser effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PHASER_H +#define PHASER_H +#include "../globals.h" +#include "../Misc/Stereo.h" +#include "../Samples/AuSample.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_PHASER_STAGES 12 +/**Phaser Effect*/ +class Phaser:public Effect +{ + public: + Phaser(const int &insetion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Phaser(); + void out(REALTYPE *smpsl, REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + void cleanup(); + void setdryonly(); + + private: + //Parametrii Phaser + EffectLFO lfo; /** old; + //REALTYPE oldlgain,oldrgain; + Stereo oldgain; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.cpp b/plugins/zynaddsubfx/src/Effects/Reverb.cpp index 943439716..27b0a554b 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.cpp +++ b/plugins/zynaddsubfx/src/Effects/Reverb.cpp @@ -1,471 +1,557 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.C - Reverberation effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#include -#include "Reverb.h" - -/**\todo: EarlyReflections,Prdelay,Perbalance */ - -Reverb::Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) - :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) -{ - inputbuf=new REALTYPE[SOUND_BUFFER_SIZE]; - - //defaults - Pvolume=48; - Ppan=64; - Ptime=64; - Pidelay=40; - Pidelayfb=0; - Prdelay=0; - Plpf=127; - Phpf=0; - Perbalance=64; - Plohidamp=80; - Ptype=1; - Proomsize=64; - roomsize=1.0; - rs=1.0; - - for (int i=0;icleanup(); - if (lpf!=NULL) lpf->cleanup(); - -}; - -/* - * Process one channel; 0=left,1=right - */ -void Reverb::processmono(int ch,REALTYPE *output) -{ - int i,j; - REALTYPE fbout,tmp; - /**\todo: implement the high part from lohidamp*/ - - for (j=REV_COMBS*ch;j=comblength) ck=0; - }; - - combk[j]=ck; - lpcomb[j]=lpcombj; - }; - - for (j=REV_APS*ch;j=aplength) ak=0; - }; - apk[j]=ak; - }; -}; - -/* - * Effect output - */ -void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) -{ - int i; - if ((Pvolume==0)&&(insertion!=0)) return; - - for (i=0;i=idelaylen) idelayk=0; - }; - }; - - if (lpf!=NULL) lpf->filterout(inputbuf); - if (hpf!=NULL) hpf->filterout(inputbuf); - - processmono(0,efxoutl);//left - processmono(1,efxoutr);//right - - REALTYPE lvol=rs/REV_COMBS*pan; - REALTYPE rvol=rs/REV_COMBS*(1.0-pan); - if (insertion!=0) { - lvol*=2; - rvol*=2; - }; - for (int i=0;iPvolume=Pvolume; - if (insertion==0) { - outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; - volume=1.0; - } else { - volume=outvolume=Pvolume/127.0; - if (Pvolume==0) cleanup(); - }; -}; - -void Reverb::setpan(const unsigned char &Ppan) -{ - this->Ppan=Ppan; - pan=(REALTYPE)Ppan/127.0; -}; - -void Reverb::settime(const unsigned char &Ptime) -{ - int i; - REALTYPE t; - this->Ptime=Ptime; - t=pow(60.0,(REALTYPE)Ptime/127.0)-0.97; - - for (i=0;iPlohidamp=Plohidamp; - if (Plohidamp==64) { - lohidamptype=0; - lohifb=0.0; - } else { - if (Plohidamp<64) lohidamptype=1; - if (Plohidamp>64) lohidamptype=2; - x=fabs((REALTYPE)(Plohidamp-64)/64.1); - lohifb=x*x; - }; -}; - -void Reverb::setidelay(const unsigned char &Pidelay) -{ - REALTYPE delay; - this->Pidelay=Pidelay; - delay=pow(50*Pidelay/127.0,2)-1.0; - - if (idelay!=NULL) delete []idelay; - idelay=NULL; - - idelaylen=(int) (SAMPLE_RATE*delay/1000); - if (idelaylen>1) { - idelayk=0; - idelay=new REALTYPE[idelaylen]; - for (int i=0;iPidelayfb=Pidelayfb; - idelayfb=Pidelayfb/128.0; -}; - -void Reverb::sethpf(const unsigned char &Phpf) -{ - this->Phpf=Phpf; - if (Phpf==0) {//No HighPass - if (hpf!=NULL) delete hpf; - hpf=NULL; - } else { - REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(10000.0))+20.0; - if (hpf==NULL) hpf=new AnalogFilter(3,fr,1,0); - else hpf->setfreq(fr); - }; -}; - -void Reverb::setlpf(const unsigned char &Plpf) -{ - this->Plpf=Plpf; - if (Plpf==127) {//No LowPass - if (lpf!=NULL) delete lpf; - lpf=NULL; - } else { - REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; - if (lpf==NULL) lpf=new AnalogFilter(2,fr,1,0); - else lpf->setfreq(fr); - }; -}; - -void Reverb::settype(unsigned char Ptype) -{ - const int NUM_TYPES=2; - int combtunings[NUM_TYPES][REV_COMBS]={ - //this is unused (for random) - {0,0,0,0,0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {1116,1188,1277,1356,1422,1491,1557,1617} - }; - int aptunings[NUM_TYPES][REV_APS]={ - //this is unused (for random) - {0,0,0,0}, - //Freeverb by Jezar at Dreampoint - {225,341,441,556} - }; - - if (Ptype>=NUM_TYPES) Ptype=NUM_TYPES-1; - this->Ptype=Ptype; - - REALTYPE tmp; - for (int i=0;iREV_COMBS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - - comblen[i]=(int) tmp; - combk[i]=0; - lpcomb[i]=0; - if (comb[i]!=NULL) delete []comb[i]; - comb[i]=new REALTYPE[comblen[i]]; - }; - - for (int i=0;iREV_APS) tmp+=23.0; - tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate - if (tmp<10) tmp=10; - aplen[i]=(int) tmp; - apk[i]=0; - if (ap[i]!=NULL) delete []ap[i]; - ap[i]=new REALTYPE[aplen[i]]; - }; - settime(Ptime); - cleanup(); -}; - -void Reverb::setroomsize(const unsigned char &Proomsize) -{ - this->Proomsize=Proomsize; - if (Proomsize==0) this->Proomsize=64;//this is because the older versions consider roomsize=0 - roomsize=(this->Proomsize-64.0)/64.0; - if (roomsize>0.0) roomsize*=2.0; - roomsize=pow(10.0,roomsize); - rs=sqrt(roomsize); - settype(Ptype); -}; - -void Reverb::setpreset(unsigned char npreset) -{ - const int PRESET_SIZE=12; - const int NUM_PRESETS=13; - unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ - //Cathedral1 - {80,64,63,24,0,0,0,85,5,83,1,64}, - //Cathedral2 - {80,64,69,35,0,0,0,127,0,71,0,64}, - //Cathedral3 - {80,64,69,24,0,0,0,127,75,78,1,85}, - //Hall1 - {90,64,51,10,0,0,0,127,21,78,1,64}, - //Hall2 - {90,64,53,20,0,0,0,127,75,71,1,64}, - //Room1 - {100,64,33,0,0,0,0,127,0,106,0,30}, - //Room2 - {100,64,21,26,0,0,0,62,0,77,1,45}, - //Basement - {110,64,14,0,0,0,0,127,5,71,0,25}, - //Tunnel - {85,80,84,20,42,0,0,51,0,78,1,105}, - //Echoed1 - {95,64,26,60,71,0,0,114,0,64,1,64}, - //Echoed2 - {90,64,40,88,71,0,0,114,0,88,1,64}, - //VeryLong1 - {90,64,93,15,0,0,0,114,0,77,0,95}, - //VeryLong2 - {90,64,111,30,0,0,0,114,90,74,1,80} - }; - - if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; - for (int n=0;n +#include "Reverb.h" + +/**\todo: EarlyReflections,Prdelay,Perbalance */ + +Reverb::Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_) + :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0) +{ + inputbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + + bandwidth = NULL; + + //defaults + Pvolume = 48; + Ppan = 64; + Ptime = 64; + Pidelay = 40; + Pidelayfb = 0; + Prdelay = 0; + Plpf = 127; + Phpf = 0; + Perbalance = 64; + Plohidamp = 80; + Ptype = 1; + Proomsize = 64; + Pbandwidth = 30; + roomsize = 1.0; + rs = 1.0; + + for(int i = 0; i < REV_COMBS * 2; i++) { + comblen[i] = 800 + (int)(RND * 1400); + combk[i] = 0; + lpcomb[i] = 0; + combfb[i] = -0.97; + comb[i] = NULL; + } + + for(int i = 0; i < REV_APS * 2; i++) { + aplen[i] = 500 + (int)(RND * 500); + apk[i] = 0; + ap[i] = NULL; + } + + lpf = NULL; + hpf = NULL; //no filter + idelay = NULL; + + setpreset(Ppreset); + cleanup(); //do not call this before the comb initialisation +} + + +Reverb::~Reverb() +{ + int i; + if(idelay != NULL) + delete [] idelay; + if(hpf != NULL) + delete hpf; + if(lpf != NULL) + delete lpf; + + for(i = 0; i < REV_APS * 2; i++) + delete [] ap[i]; + for(i = 0; i < REV_COMBS * 2; i++) + delete [] comb[i]; + + delete [] inputbuf; + if(bandwidth) + delete bandwidth; +} + +/* + * Cleanup the effect + */ +void Reverb::cleanup() +{ + int i, j; + for(i = 0; i < REV_COMBS * 2; i++) { + lpcomb[i] = 0.0; + for(j = 0; j < comblen[i]; j++) + comb[i][j] = 0.0; + } + + for(i = 0; i < REV_APS * 2; i++) + for(j = 0; j < aplen[i]; j++) + ap[i][j] = 0.0; + + if(idelay != NULL) + for(i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + + if(hpf != NULL) + hpf->cleanup(); + if(lpf != NULL) + lpf->cleanup(); +} + +/* + * Process one channel; 0=left,1=right + */ +void Reverb::processmono(int ch, REALTYPE *output) +{ + int i, j; + REALTYPE fbout, tmp; + /**\todo: implement the high part from lohidamp*/ + + for(j = REV_COMBS * ch; j < REV_COMBS * (ch + 1); j++) { + int ck = combk[j]; + int comblength = comblen[j]; + REALTYPE lpcombj = lpcomb[j]; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + fbout = comb[j][ck] * combfb[j]; + fbout = fbout * (1.0 - lohifb) + lpcombj * lohifb; + lpcombj = fbout; + + comb[j][ck] = inputbuf[i] + fbout; + output[i] += fbout; + + if((++ck) >= comblength) + ck = 0; + } + + combk[j] = ck; + lpcomb[j] = lpcombj; + } + + for(j = REV_APS * ch; j < REV_APS * (1 + ch); j++) { + int ak = apk[j]; + int aplength = aplen[j]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = ap[j][ak]; + ap[j][ak] = 0.7 * tmp + output[i]; + output[i] = tmp - 0.7 * ap[j][ak]; + if((++ak) >= aplength) + ak = 0; + } + apk[j] = ak; + } +} + +/* + * Effect output + */ +void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r) +{ + int i; + if((Pvolume == 0) && (insertion != 0)) + return; + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + inputbuf[i] = (smps_l[i] + smps_r[i]) / 2.0; + ; + + if(idelay != NULL) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + //Initial delay r + REALTYPE tmp = inputbuf[i] + idelay[idelayk] * idelayfb; + inputbuf[i] = idelay[idelayk]; + idelay[idelayk] = tmp; + idelayk++; + if(idelayk >= idelaylen) + idelayk = 0; + ; + } + } + + if(bandwidth) + bandwidth->process(SOUND_BUFFER_SIZE, inputbuf); + + if(lpf != NULL) + lpf->filterout(inputbuf); + if(hpf != NULL) + hpf->filterout(inputbuf); + + processmono(0, efxoutl); //left + processmono(1, efxoutr); //right + + REALTYPE lvol = rs / REV_COMBS * pan; + REALTYPE rvol = rs / REV_COMBS * (1.0 - pan); + if(insertion != 0) { + lvol *= 2; + rvol *= 2; + } + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + efxoutl[i] *= lvol; + efxoutr[i] *= rvol; + } +} + + +/* + * Parameter control + */ +void Reverb::setvolume(const unsigned char &Pvolume) +{ + this->Pvolume = Pvolume; + if(insertion == 0) { + outvolume = pow(0.01, (1.0 - Pvolume / 127.0)) * 4.0; + volume = 1.0; + } + else { + volume = outvolume = Pvolume / 127.0; + if(Pvolume == 0) + cleanup(); + } +} + +void Reverb::setpan(const unsigned char &Ppan) +{ + this->Ppan = Ppan; + pan = (REALTYPE)Ppan / 127.0; +} + +void Reverb::settime(const unsigned char &Ptime) +{ + int i; + REALTYPE t; + this->Ptime = Ptime; + t = pow(60.0, (REALTYPE)Ptime / 127.0) - 0.97; + + for(i = 0; i < REV_COMBS * 2; i++) + combfb[i] = + -exp((REALTYPE)comblen[i] / (REALTYPE)SAMPLE_RATE * log(0.001) / t); + //the feedback is negative because it removes the DC + ; +} + +void Reverb::setlohidamp(unsigned char Plohidamp) +{ + REALTYPE x; + + if(Plohidamp < 64) + Plohidamp = 64; //remove this when the high part from lohidamp will be added + + this->Plohidamp = Plohidamp; + if(Plohidamp == 64) { + lohidamptype = 0; + lohifb = 0.0; + } + else { + if(Plohidamp < 64) + lohidamptype = 1; + if(Plohidamp > 64) + lohidamptype = 2; + x = fabs((REALTYPE)(Plohidamp - 64) / 64.1); + lohifb = x * x; + } +} + +void Reverb::setidelay(const unsigned char &Pidelay) +{ + REALTYPE delay; + this->Pidelay = Pidelay; + delay = pow(50 * Pidelay / 127.0, 2) - 1.0; + + if(idelay != NULL) + delete [] idelay; + idelay = NULL; + + idelaylen = (int) (SAMPLE_RATE * delay / 1000); + if(idelaylen > 1) { + idelayk = 0; + idelay = new REALTYPE[idelaylen]; + for(int i = 0; i < idelaylen; i++) + idelay[i] = 0.0; + } +} + +void Reverb::setidelayfb(const unsigned char &Pidelayfb) +{ + this->Pidelayfb = Pidelayfb; + idelayfb = Pidelayfb / 128.0; +} + +void Reverb::sethpf(const unsigned char &Phpf) +{ + this->Phpf = Phpf; + if(Phpf == 0) { //No HighPass + if(hpf != NULL) + delete hpf; + hpf = NULL; + } + else { + REALTYPE fr = exp(pow(Phpf / 127.0, 0.5) * log(10000.0)) + 20.0; + if(hpf == NULL) + hpf = new AnalogFilter(3, fr, 1, 0); + else + hpf->setfreq(fr); + } +} + +void Reverb::setlpf(const unsigned char &Plpf) +{ + this->Plpf = Plpf; + if(Plpf == 127) { //No LowPass + if(lpf != NULL) + delete lpf; + lpf = NULL; + } + else { + REALTYPE fr = exp(pow(Plpf / 127.0, 0.5) * log(25000.0)) + 40; + if(lpf == NULL) + lpf = new AnalogFilter(2, fr, 1, 0); + else + lpf->setfreq(fr); + } +} + +void Reverb::settype(unsigned char Ptype) +{ + const int NUM_TYPES = 3; + int combtunings[NUM_TYPES][REV_COMBS] = { + //this is unused (for random) + {0, 0, 0, 0, 0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 }, + //Freeverb by Jezar at Dreampoint //duplicate + {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 } + }; + int aptunings[NUM_TYPES][REV_APS] = { + //this is unused (for random) + {0, 0, 0, 0 }, + //Freeverb by Jezar at Dreampoint + {225, 341, 441, 556 }, + //Freeverb by Jezar at Dreampoint (duplicate) + {225, 341, 441, 556 } + }; + + if(Ptype >= NUM_TYPES) + Ptype = NUM_TYPES - 1; + this->Ptype = Ptype; + + REALTYPE tmp; + for(int i = 0; i < REV_COMBS * 2; i++) { + if(Ptype == 0) + tmp = 800.0 + (int)(RND * 1400.0); + else + tmp = combtunings[Ptype][i % REV_COMBS]; + tmp *= roomsize; + if(i > REV_COMBS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + + comblen[i] = (int) tmp; + combk[i] = 0; + lpcomb[i] = 0; + if(comb[i] != NULL) + delete [] comb[i]; + comb[i] = new REALTYPE[comblen[i]]; + } + + for(int i = 0; i < REV_APS * 2; i++) { + if(Ptype == 0) + tmp = 500 + (int)(RND * 500); + else + tmp = aptunings[Ptype][i % REV_APS]; + tmp *= roomsize; + if(i > REV_APS) + tmp += 23.0; + tmp *= SAMPLE_RATE / 44100.0; //adjust the combs according to the samplerate + if(tmp < 10) + tmp = 10; + aplen[i] = (int) tmp; + apk[i] = 0; + if(ap[i] != NULL) + delete [] ap[i]; + ap[i] = new REALTYPE[aplen[i]]; + } + settime(Ptime); + cleanup(); + if(bandwidth) + delete bandwidth; + bandwidth = NULL; + if(Ptype == 2) { //bandwidth + bandwidth = new Unison(SOUND_BUFFER_SIZE / 4 + 1, 2.0); + bandwidth->set_size(50); + bandwidth->set_base_frequency(1.0); +#warning sa schimb size-ul + } +} + +void Reverb::setroomsize(const unsigned char &Proomsize) +{ + this->Proomsize = Proomsize; + if(Proomsize == 0) + this->Proomsize = 64; //this is because the older versions consider roomsize=0 + roomsize = (this->Proomsize - 64.0) / 64.0; + if(roomsize > 0.0) + roomsize *= 2.0; + roomsize = pow(10.0, roomsize); + rs = sqrt(roomsize); + settype(Ptype); +} + +void Reverb::setbandwidth(const unsigned char &Pbandwidth) { + this->Pbandwidth = Pbandwidth; + REALTYPE v = Pbandwidth / 127.0; + if(bandwidth) + bandwidth->set_bandwidth(pow(v, 2.0) * 200.0); +} + +void Reverb::setpreset(unsigned char npreset) +{ + const int PRESET_SIZE = 13; + const int NUM_PRESETS = 13; + unsigned char presets[NUM_PRESETS][PRESET_SIZE] = { + //Cathedral1 + {80, 64, 63, 24, 0, 0, 0, 85, 5, 83, 1, 64, 20 }, + //Cathedral2 + {80, 64, 69, 35, 0, 0, 0, 127, 0, 71, 0, 64, 20 }, + //Cathedral3 + {80, 64, 69, 24, 0, 0, 0, 127, 75, 78, 1, 85, 20 }, + //Hall1 + {90, 64, 51, 10, 0, 0, 0, 127, 21, 78, 1, 64, 20 }, + //Hall2 + {90, 64, 53, 20, 0, 0, 0, 127, 75, 71, 1, 64, 20 }, + //Room1 + {100, 64, 33, 0, 0, 0, 0, 127, 0, 106, 0, 30, 20 }, + //Room2 + {100, 64, 21, 26, 0, 0, 0, 62, 0, 77, 1, 45, 20 }, + //Basement + {110, 64, 14, 0, 0, 0, 0, 127, 5, 71, 0, 25, 20 }, + //Tunnel + {85, 80, 84, 20, 42, 0, 0, 51, 0, 78, 1, 105, 20 }, + //Echoed1 + {95, 64, 26, 60, 71, 0, 0, 114, 0, 64, 1, 64, 20 }, + //Echoed2 + {90, 64, 40, 88, 71, 0, 0, 114, 0, 88, 1, 64, 20 }, + //VeryLong1 + {90, 64, 93, 15, 0, 0, 0, 114, 0, 77, 0, 95, 20 }, + //VeryLong2 + {90, 64, 111, 30, 0, 0, 0, 114, 90, 74, 1, 80, 20 } + }; + + if(npreset >= NUM_PRESETS) + npreset = NUM_PRESETS - 1; + for(int n = 0; n < PRESET_SIZE; n++) + changepar(n, presets[npreset][n]); + if(insertion != 0) + changepar(0, presets[npreset][0] / 2); //lower the volume if reverb is insertion effect + Ppreset = npreset; +} + + +void Reverb::changepar(const int &npar, const unsigned char &value) +{ + switch(npar) { + case 0: + setvolume(value); + break; + case 1: + setpan(value); + break; + case 2: + settime(value); + break; + case 3: + setidelay(value); + break; + case 4: + setidelayfb(value); + break; +// case 5: setrdelay(value); +// break; +// case 6: seterbalance(value); +// break; + case 7: + setlpf(value); + break; + case 8: + sethpf(value); + break; + case 9: + setlohidamp(value); + break; + case 10: + settype(value); + break; + case 11: + setroomsize(value); + break; + case 12: + setbandwidth(value); + break; + } +} + +unsigned char Reverb::getpar(const int &npar) const +{ + switch(npar) { + case 0: + return Pvolume; + break; + case 1: + return Ppan; + break; + case 2: + return Ptime; + break; + case 3: + return Pidelay; + break; + case 4: + return Pidelayfb; + break; +// case 5: return(Prdelay); +// break; +// case 6: return(Perbalance); +// break; + case 7: + return Plpf; + break; + case 8: + return Phpf; + break; + case 9: + return Plohidamp; + break; + case 10: + return Ptype; + break; + case 11: + return Proomsize; + break; + case 12: + return Pbandwidth; + break; + } + return 0; //in case of bogus "parameter" +} + diff --git a/plugins/zynaddsubfx/src/Effects/Reverb.h b/plugins/zynaddsubfx/src/Effects/Reverb.h index ddf5900f6..d94f0bcef 100644 --- a/plugins/zynaddsubfx/src/Effects/Reverb.h +++ b/plugins/zynaddsubfx/src/Effects/Reverb.h @@ -1,127 +1,135 @@ -/* - ZynAddSubFX - a software synthesizer - - Reverb.h - Reverberation effect - Copyright (C) 2002-2005 Nasca Octavian Paul - Author: Nasca Octavian Paul - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ - -#ifndef REVERB_H -#define REVERB_H - - -#include "../globals.h" -#include "../DSP/AnalogFilter.h" -#include "Effect.h" - -#define REV_COMBS 8 -#define REV_APS 4 - -/**Creates Reverberation Effects*/ -class Reverb:public Effect -{ -public: - Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); - ~Reverb(); - void out(REALTYPE *smps_l,REALTYPE *smps_r); - void cleanup(); - - void setpreset(unsigned char npreset); - void changepar(const int &npar,const unsigned char &value); - unsigned char getpar(const int &npar)const; - -private: - //Parametrii - /**Amount of the reverb*/ - unsigned char Pvolume; - - /**Left/Right Panning*/ - unsigned char Ppan; - - /**duration of reverb*/ - unsigned char Ptime; - - /**Initial delay*/ - unsigned char Pidelay; - - /**Initial delay feedback*/ - unsigned char Pidelayfb; - - /**delay between ER/Reverbs*/ - unsigned char Prdelay; - - /**EarlyReflections/Reverb Balance*/ - unsigned char Perbalance; - - /**HighPassFilter*/ - unsigned char Plpf; - - /**LowPassFilter*/ - unsigned char Phpf; - - /**Low/HighFrequency Damping - * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ - unsigned char Plohidamp; - - /**Reverb type*/ - unsigned char Ptype; - - /**Room Size*/ - unsigned char Proomsize; - - //parameter control - void setvolume(const unsigned char &Pvolume); - void setpan(const unsigned char &Ppan); - void settime(const unsigned char &Ptime); - void setlohidamp(unsigned char Plohidamp); - void setidelay(const unsigned char &Pidelay); - void setidelayfb(const unsigned char &Pidelayfb); - void sethpf(const unsigned char &Phpf); - void setlpf(const unsigned char &Plpf); - void settype( unsigned char Ptype); - void setroomsize(const unsigned char &Proomsize); - - REALTYPE pan,erbalance; - //Parametrii 2 - int lohidamptype;/**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ - int idelaylen,rdelaylen; - int idelayk; - REALTYPE lohifb,idelayfb,roomsize,rs;//rs is used to "normalise" the volume according to the roomsize - int comblen[REV_COMBS*2]; - int aplen[REV_APS*2]; - - //Internal Variables - - REALTYPE *comb[REV_COMBS*2]; - - int combk[REV_COMBS*2]; - REALTYPE combfb[REV_COMBS*2];/** +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "../DSP/FFTwrapper.h" +#include "../DSP/Unison.h" +#include "Effect.h" + +#define REV_COMBS 8 +#define REV_APS 4 + +/**Creates Reverberation Effects*/ + +class Reverb:public Effect +{ + public: + Reverb(const int &insertion_, REALTYPE *efxoutl_, REALTYPE *efxoutr_); + ~Reverb(); + void out(REALTYPE *smps_l, REALTYPE *smps_r); + void cleanup(); + + void setpreset(unsigned char npreset); + void changepar(const int &npar, const unsigned char &value); + unsigned char getpar(const int &npar) const; + + private: + //Parametrii + /**Amount of the reverb*/ + unsigned char Pvolume; + + /**Left/Right Panning*/ + unsigned char Ppan; + + /**duration of reverb*/ + unsigned char Ptime; + + /**Initial delay*/ + unsigned char Pidelay; + + /**Initial delay feedback*/ + unsigned char Pidelayfb; + + /**delay between ER/Reverbs*/ + unsigned char Prdelay; + + /**EarlyReflections/Reverb Balance*/ + unsigned char Perbalance; + + /**HighPassFilter*/ + unsigned char Plpf; + + /**LowPassFilter*/ + unsigned char Phpf; + + /**Low/HighFrequency Damping + * \todo 0..63 lpf,64=off,65..127=hpf(TODO)*/ + unsigned char Plohidamp; + + /**Reverb type*/ + unsigned char Ptype; + + /**Room Size*/ + unsigned char Proomsize; + + /**Bandwidth */ + unsigned char Pbandwidth; + + //parameter control + void setvolume(const unsigned char &Pvolume); + void setpan(const unsigned char &Ppan); + void settime(const unsigned char &Ptime); + void setlohidamp(unsigned char Plohidamp); + void setidelay(const unsigned char &Pidelay); + void setidelayfb(const unsigned char &Pidelayfb); + void sethpf(const unsigned char &Phpf); + void setlpf(const unsigned char &Plpf); + void settype(unsigned char Ptype); + void setroomsize(const unsigned char &Proomsize); + void setbandwidth(const unsigned char &Pbandwidth); + + REALTYPE pan, erbalance; + //Parameters + int lohidamptype; /**<0=disable,1=highdamp(lowpass),2=lowdamp(highpass)*/ + int idelaylen, rdelaylen; + int idelayk; + REALTYPE lohifb, idelayfb, roomsize, rs; //rs is used to "normalise" the volume according to the roomsize + int comblen[REV_COMBS * 2]; + int aplen[REV_APS * 2]; + Unison *bandwidth; + + //Internal Variables + + REALTYPE *comb[REV_COMBS * 2]; + + int combk[REV_COMBS * 2]; + REALTYPE combfb[REV_COMBS * 2]; /**type) { + if(midievent == NULL) + return; + switch(midievent->type) { case SND_SEQ_EVENT_NOTEON: - cmdtype=MidiNoteON; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; - cmdparams[1]=midievent->data.note.velocity; + cmdtype = MidiNoteON; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; + cmdparams[1] = midievent->data.note.velocity; break; case SND_SEQ_EVENT_NOTEOFF: - cmdtype=MidiNoteOFF; - cmdchan=midievent->data.note.channel; - cmdparams[0]=midievent->data.note.note; + cmdtype = MidiNoteOFF; + cmdchan = midievent->data.note.channel; + cmdparams[0] = midievent->data.note.note; break; case SND_SEQ_EVENT_PITCHBEND: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=C_pitchwheel;//Pitch Bend - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = C_pitchwheel; //Pitch Bend + cmdparams[1] = midievent->data.control.value; break; case SND_SEQ_EVENT_CONTROLLER: - cmdtype=MidiController; - cmdchan=midievent->data.control.channel; - cmdparams[0]=getcontroller(midievent->data.control.param); - cmdparams[1]=midievent->data.control.value; + cmdtype = MidiController; + cmdchan = midievent->data.control.channel; + cmdparams[0] = getcontroller(midievent->data.control.param); + cmdparams[1] = midievent->data.control.value; //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); break; - - }; -}; + } +} int ALSAMidiIn::getalsaid() { - if (midi_handle) { - snd_seq_client_info_t* seq_info; + if(midi_handle) { + snd_seq_client_info_t *seq_info; snd_seq_client_info_malloc(&seq_info); snd_seq_get_client_info(midi_handle, seq_info); int id = snd_seq_client_info_get_client(seq_info); diff --git a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h index e4671014f..cea61fb36 100644 --- a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h @@ -30,19 +30,21 @@ /**Midi input for ALSA (this creates an ALSA virtual port)*/ class ALSAMidiIn:public MidiIn { -public: - /**Constructor*/ - ALSAMidiIn(); - /**Destructor*/ - ~ALSAMidiIn(); + public: + /**Constructor*/ + ALSAMidiIn(); + /**Destructor*/ + ~ALSAMidiIn(); - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - /**Get the ALSA id - * @return ALSA id*/ - int getalsaid(); + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + /**Get the ALSA id + * @return ALSA id*/ + int getalsaid(); -private: - snd_seq_t *midi_handle; + private: + snd_seq_t *midi_handle; }; #endif diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.cpp b/plugins/zynaddsubfx/src/Input/MidiIn.cpp index 2355b3a64..90df75d95 100644 --- a/plugins/zynaddsubfx/src/Input/MidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/MidiIn.cpp @@ -26,70 +26,71 @@ int MidiIn::getcontroller(unsigned char b) { /**\todo there might be a better way to do this*/ - int ctl=C_NULL; - switch (b) { + int ctl = C_NULL; + switch(b) { case 1: - ctl=C_modwheel;//Modulation Wheel + ctl = C_modwheel; //Modulation Wheel break; case 7: - ctl=C_volume;//Volume + ctl = C_volume; //Volume break; case 10: - ctl=C_panning;//Panning + ctl = C_panning; //Panning break; case 11: - ctl=C_expression;//Expression + ctl = C_expression; //Expression break; case 64: - ctl=C_sustain;//Sustain pedal + ctl = C_sustain; //Sustain pedal break; case 65: - ctl=C_portamento;//Portamento + ctl = C_portamento; //Portamento break; case 71: - ctl=C_filterq;//Filter Q (Sound Timbre) + ctl = C_filterq; //Filter Q (Sound Timbre) break; case 74: - ctl=C_filtercutoff;//Filter Cutoff (Brightness) + ctl = C_filtercutoff; //Filter Cutoff (Brightness) break; case 75: - ctl=C_bandwidth;//BandWidth + ctl = C_bandwidth; //BandWidth break; case 76: - ctl=C_fmamp;//FM amplitude + ctl = C_fmamp; //FM amplitude break; case 77: - ctl=C_resonance_center;//Resonance Center Frequency + ctl = C_resonance_center; //Resonance Center Frequency break; case 78: - ctl=C_resonance_bandwidth;//Resonance Bandwith + ctl = C_resonance_bandwidth; //Resonance Bandwith break; case 120: - ctl=C_allsoundsoff;//All Sounds OFF + ctl = C_allsoundsoff; //All Sounds OFF break; case 121: - ctl=C_resetallcontrollers;//Reset All Controllers + ctl = C_resetallcontrollers; //Reset All Controllers break; case 123: - ctl=C_allnotesoff;//All Notes OFF + ctl = C_allnotesoff; //All Notes OFF break; - //RPN and NRPN + //RPN and NRPN case 0x06: - ctl=C_dataentryhi;//Data Entry (Coarse) + ctl = C_dataentryhi; //Data Entry (Coarse) break; case 0x26: - ctl=C_dataentrylo;//Data Entry (Fine) + ctl = C_dataentrylo; //Data Entry (Fine) break; case 99: - ctl=C_nrpnhi;//NRPN (Coarse) + ctl = C_nrpnhi; //NRPN (Coarse) break; case 98: - ctl=C_nrpnlo;//NRPN (Fine) + ctl = C_nrpnlo; //NRPN (Fine) break; default: - ctl=C_NULL;//unknown controller + ctl = C_NULL; //unknown controller //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]); break; - }; - return(ctl); -}; + } + return ctl; +} + diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.h b/plugins/zynaddsubfx/src/Input/MidiIn.h index f02d10e76..5d978eaeb 100644 --- a/plugins/zynaddsubfx/src/Input/MidiIn.h +++ b/plugins/zynaddsubfx/src/Input/MidiIn.h @@ -25,23 +25,27 @@ #include "../globals.h" -enum MidiCmdType {MidiNull,MidiNoteOFF,MidiNoteON,MidiController}; +enum MidiCmdType { + MidiNull, MidiNoteOFF, MidiNoteON, MidiController +}; #define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes /**This class is inherited by all the Midi input classes*/ class MidiIn { -public: - /**Get the command,channel and parameters of the MIDI - * - * \todo make pure virtual - * @param cmdtype the referece to the variable that will store the type - * @param cmdchan the channel for the event - * @param parameters for the event*/ - virtual void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams)=0; - int getcontroller(unsigned char b); -protected: - bool inputok;/**<1 if I can read midi bytes from input ports*/ + public: + /**Get the command,channel and parameters of the MIDI + * + * \todo make pure virtual + * @param cmdtype the referece to the variable that will store the type + * @param cmdchan the channel for the event + * @param parameters for the event*/ + virtual void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) = 0; + int getcontroller(unsigned char b); + protected: + bool inputok; /**<1 if I can read midi bytes from input ports*/ }; #endif diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp index 2a727ac7e..22ee76d75 100644 --- a/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.cpp @@ -23,19 +23,19 @@ #include "NULLMidiIn.h" NULLMidiIn::NULLMidiIn() -{ -}; +{} NULLMidiIn::~NULLMidiIn() -{ -}; +{} /* * Get the midi command,channel and parameters * It returns MidiNull because it is a dummy driver */ -void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - cmdtype=MidiNull; -}; + cmdtype = MidiNull; +} diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.h b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h index 636302c57..72cef4ad0 100644 --- a/plugins/zynaddsubfx/src/Input/NULLMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h @@ -29,19 +29,21 @@ /**a dummy Midi port*/ class NULLMidiIn:public MidiIn { -public: - /**Dummy Constructor - * \todo see if the default constructor would work here*/ - NULLMidiIn(); - /**Dummy Destructor - * \todo see if the default destructor would work here*/ - ~NULLMidiIn(); - /**Get the midi command,channel and parameters - * It returns MidiNull because it is a dummy driver - */ - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); + public: + /**Dummy Constructor + * \todo see if the default constructor would work here*/ + NULLMidiIn(); + /**Dummy Destructor + * \todo see if the default destructor would work here*/ + ~NULLMidiIn(); + /**Get the midi command,channel and parameters + * It returns MidiNull because it is a dummy driver + */ + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); -private: + private: }; #endif diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp index 440775abd..b278ae6bf 100644 --- a/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.cpp @@ -33,88 +33,91 @@ OSSMidiIn::OSSMidiIn() { - inputok=false; - midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0); - if (midi_handle!=-1) inputok=true; + inputok = false; + midi_handle = open(config.cfg.LinuxOSSSeqInDev, O_RDONLY, 0); + if(midi_handle != -1) + inputok = true; - lastmidicmd=0; - cmdtype=0; - cmdchan=0; - -}; + lastmidicmd = 0; + cmdtype = 0; + cmdchan = 0; +} OSSMidiIn::~OSSMidiIn() { close(midi_handle); -}; +} unsigned char OSSMidiIn::readbyte() { unsigned char tmp[4]; - read(midi_handle,&tmp[0],1); - while (tmp[0]!=SEQ_MIDIPUTC) { - read(midi_handle,&tmp[0],4); + read(midi_handle, &tmp[0], 1); + while(tmp[0] != SEQ_MIDIPUTC) { + read(midi_handle, &tmp[0], 4); } - return(tmp[1]); -}; + return tmp[1]; +} unsigned char OSSMidiIn::getmidibyte() { unsigned char b; do { - b=readbyte(); - } while (b==0xfe);//drops the Active Sense Messages - return(b); -}; + b = readbyte(); + } while(b == 0xfe); //drops the Active Sense Messages + return b; +} /* * Get the midi command,channel and parameters */ -void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams) +void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams) { - unsigned char tmp,i; - if (inputok==false) { - cmdtype=MidiNull; + unsigned char tmp, i; + if(inputok == false) { + cmdtype = MidiNull; return; } - i=0; - if (lastmidicmd==0) {//asteapta prima data pana cand vine prima comanda midi - while (tmp<0x80) tmp=getmidibyte(); - lastmidicmd=tmp; + i = 0; + if(lastmidicmd == 0) { //asteapta prima data pana cand vine prima comanda midi + while(tmp < 0x80) + tmp = getmidibyte(); + lastmidicmd = tmp; } - tmp=getmidibyte(); + tmp = getmidibyte(); - if (tmp>=0x80) { - lastmidicmd=tmp; - tmp=getmidibyte(); + if(tmp >= 0x80) { + lastmidicmd = tmp; + tmp = getmidibyte(); } - if ((lastmidicmd>=0x80)&&(lastmidicmd<=0x8f)) {//Note OFF - cmdtype=MidiNoteOFF; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number + if((lastmidicmd >= 0x80) && (lastmidicmd <= 0x8f)) { //Note OFF + cmdtype = MidiNoteOFF; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number } - if ((lastmidicmd>=0x90)&&(lastmidicmd<=0x9f)) {//Note ON - cmdtype=MidiNoteON; - cmdchan=lastmidicmd%16; - cmdparams[0]=tmp;//note number - cmdparams[1]=getmidibyte();//velocity - if (cmdparams[1]==0) cmdtype=MidiNoteOFF;//if velocity==0 then is note off + if((lastmidicmd >= 0x90) && (lastmidicmd <= 0x9f)) { //Note ON + cmdtype = MidiNoteON; + cmdchan = lastmidicmd % 16; + cmdparams[0] = tmp; //note number + cmdparams[1] = getmidibyte(); //velocity + if(cmdparams[1] == 0) + cmdtype = MidiNoteOFF; //if velocity==0 then is note off } - if ((lastmidicmd>=0xB0)&&(lastmidicmd<=0xBF)) {//Controllers - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=getcontroller(tmp); - cmdparams[1]=getmidibyte(); + if((lastmidicmd >= 0xB0) && (lastmidicmd <= 0xBF)) { //Controllers + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = getcontroller(tmp); + cmdparams[1] = getmidibyte(); } - if ((lastmidicmd>=0xE0)&&(lastmidicmd<=0xEF)) {//Pitch Wheel - cmdtype=MidiController; - cmdchan=lastmidicmd%16; - cmdparams[0]=C_pitchwheel; - cmdparams[1]=(tmp+getmidibyte()*(int) 128)-8192;//hope this is correct + if((lastmidicmd >= 0xE0) && (lastmidicmd <= 0xEF)) { //Pitch Wheel + cmdtype = MidiController; + cmdchan = lastmidicmd % 16; + cmdparams[0] = C_pitchwheel; + cmdparams[1] = (tmp + getmidibyte() * (int) 128) - 8192; //hope this is correct } -}; - +} diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.h b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h index 7626950ed..a3b56f51b 100644 --- a/plugins/zynaddsubfx/src/Input/OSSMidiIn.h +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h @@ -27,21 +27,22 @@ class OSSMidiIn:public MidiIn { -public: - OSSMidiIn(); - ~OSSMidiIn(); - unsigned char getmidibyte(); - unsigned char readbyte(); + public: + OSSMidiIn(); + ~OSSMidiIn(); + unsigned char getmidibyte(); + unsigned char readbyte(); - //Midi parser - void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); - unsigned char cmdtype;//the Message Type (noteon,noteof,sysex..) - unsigned char cmdchan;//the channel number - -private: - int midi_handle; - unsigned char lastmidicmd;//last byte (>=80) received from the Midi + //Midi parser + void getmidicmd(MidiCmdType &cmdtype, + unsigned char &cmdchan, + int *cmdparams); + unsigned char cmdtype; //the Message Type (noteon,noteof,sysex..) + unsigned char cmdchan; //the channel number + private: + int midi_handle; + unsigned char lastmidicmd; //last byte (>=80) received from the Midi }; diff --git a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp index 155aa7375..e8462457d 100644 --- a/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp +++ b/plugins/zynaddsubfx/src/Input/WINMidiIn.cpp @@ -32,56 +32,63 @@ Master *winmaster; HMIDIIN winmidiinhandle; -MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers +MidiIn midictl; //used to convert the controllers to ZynAddSubFX controllers -void CALLBACK WinMidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance, - DWORD dwParam1,DWORD dwParam2) +void CALLBACK WinMidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, + DWORD dwParam1, DWORD dwParam2) { - int midicommand=MidiNull; - if (wMsg==MIM_DATA) { - int cmd,par1,par2; - cmd=dwParam1&0xff; - if (cmd==0xfe) return; - par1=(dwParam1>>8)&0xff; - par2=dwParam1>>16; + int midicommand = MidiNull; + if(wMsg == MIM_DATA) { + int cmd, par1, par2; + cmd = dwParam1 & 0xff; + if(cmd == 0xfe) + return; + par1 = (dwParam1 >> 8) & 0xff; + par2 = dwParam1 >> 16; //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout); - int cmdchan=cmd&0x0f; - int cmdtype=(cmd>>4)&0x0f; + int cmdchan = cmd & 0x0f; + int cmdtype = (cmd >> 4) & 0x0f; - int tmp=0; + int tmp = 0; pthread_mutex_lock(&winmaster->mutex); - switch (cmdtype) { - case(0x8)://noteon - winmaster->NoteOff(cmdchan,par1); + switch(cmdtype) { + case (0x8): //noteon + winmaster->NoteOff(cmdchan, par1); break; - case(0x9)://noteoff - winmaster->NoteOn(cmdchan,par1,par2&0xff); + case (0x9): //noteoff + winmaster->NoteOn(cmdchan, par1, par2 & 0xff); break; - case(0xb)://controller - winmaster->SetController(cmdchan,midictl.getcontroller(par1),par2&0xff); + case (0xb): //controller + winmaster->SetController(cmdchan, midictl.getcontroller( + par1), par2 & 0xff); break; - case(0xe)://pitch wheel - tmp=(par1+par2*(long int) 128)-8192; - winmaster->SetController(cmdchan,C_pitchwheel,tmp); + case (0xe): //pitch wheel + tmp = (par1 + par2 * (long int) 128) - 8192; + winmaster->SetController(cmdchan, C_pitchwheel, tmp); break; default: break; - }; + } pthread_mutex_unlock(&winmaster->mutex); - - }; -}; + } +} void InitWinMidi(Master *master_) { - winmaster=master_; + winmaster = master_; - long int result=midiInOpen(&winmidiinhandle,config.cfg.WindowsMidiInId,(DWORD)WinMidiInProc,0,CALLBACK_FUNCTION); - result=midiInStart(winmidiinhandle); -}; + long int result = + midiInOpen(&winmidiinhandle, + config.cfg.WindowsMidiInId, + (DWORD)WinMidiInProc, + 0, + CALLBACK_FUNCTION); + result = midiInStart(winmidiinhandle); +} void StopWinMidi() { midiInStop(winmidiinhandle); midiInClose(winmidiinhandle); -}; +} + diff --git a/plugins/zynaddsubfx/src/Misc/Bank.cpp b/plugins/zynaddsubfx/src/Misc/Bank.cpp index 4c1b27a96..256184736 100644 --- a/plugins/zynaddsubfx/src/Misc/Bank.cpp +++ b/plugins/zynaddsubfx/src/Misc/Bank.cpp @@ -41,183 +41,213 @@ Bank::Bank() { + ZERO(defaultinsname, PART_MAX_NAME_LEN); + snprintf(defaultinsname, PART_MAX_NAME_LEN, "%s", " "); - - ZERO(defaultinsname,PART_MAX_NAME_LEN); - snprintf(defaultinsname,PART_MAX_NAME_LEN,"%s"," "); - - for (int i=0;i=0) snprintf(tmpfilename,100,"%4d-%s",newslot+1,newname); - else snprintf(tmpfilename,100,"%4d-%s",ninstrument+1,newname); + ZERO(newfilename, 1001); + ZERO(tmpfilename, 101); + if(newslot >= 0) + snprintf(tmpfilename, 100, "%4d-%s", newslot + 1, newname); + else + snprintf(tmpfilename, 100, "%4d-%s", ninstrument + 1, newname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int) strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; - tmpfilename[i]='_'; - }; + tmpfilename[i] = '_'; + } - snprintf(newfilename,1000,"%s/%s.xiz",dirname,tmpfilename); + snprintf(newfilename, 1000, "%s/%s.xiz", dirname, tmpfilename); // printf("rename %s -> %s\n",ins[ninstrument].filename,newfilename);////////////// - rename(ins[ninstrument].filename,newfilename); - if (ins[ninstrument].filename) delete []ins[ninstrument].filename; - ins[ninstrument].filename=new char[strlen(newfilename)+5]; - snprintf(ins[ninstrument].filename,strlen(newfilename)+1,"%s",newfilename); - snprintf(ins[ninstrument].name,PART_MAX_NAME_LEN,"%s",&tmpfilename[5]); - -}; + rename(ins[ninstrument].filename, newfilename); + if(ins[ninstrument].filename) + delete [] ins[ninstrument].filename; + ins[ninstrument].filename = new char[strlen(newfilename) + 5]; + snprintf(ins[ninstrument].filename, strlen( + newfilename) + 1, "%s", newfilename); + snprintf(ins[ninstrument].name, PART_MAX_NAME_LEN, "%s", &tmpfilename[5]); +} /* * Check if there is no instrument on a slot from the bank */ int Bank::emptyslot(unsigned int ninstrument) { - if (ninstrument>=BANK_SIZE) return (1); - if (ins[ninstrument].filename==NULL) return(1); + if(ninstrument >= BANK_SIZE) + return 1; + if(ins[ninstrument].filename == NULL) + return 1; - if (ins[ninstrument].used) return (0); - else return(1); -}; + if(ins[ninstrument].used) + return 0; + else + return 1; +} /* * Removes the instrument from the bank */ void Bank::clearslot(unsigned int ninstrument) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; // printf("remove %s \n",ins[ninstrument].filename);//////////////////////// remove(ins[ninstrument].filename); deletefrombank(ninstrument); -}; +} /* * Save the instrument to a slot */ -void Bank::savetoslot(unsigned int ninstrument,Part *part) +void Bank::savetoslot(unsigned int ninstrument, Part *part) { clearslot(ninstrument); - const int maxfilename=200; - char tmpfilename[maxfilename+20]; - ZERO(tmpfilename,maxfilename+20); + const int maxfilename = 200; + char tmpfilename[maxfilename + 20]; + ZERO(tmpfilename, maxfilename + 20); - snprintf(tmpfilename,maxfilename,"%4d-%s",ninstrument+1,(char *)part->Pname); + snprintf(tmpfilename, + maxfilename, + "%4d-%s", + ninstrument + 1, + (char *)part->Pname); //add the zeroes at the start of filename - for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + for(int i = 0; i < 4; i++) + if(tmpfilename[i] == ' ') + tmpfilename[i] = '0'; //make the filenames legal - for (int i=0;i<(int)strlen(tmpfilename);i++) { - char c=tmpfilename[i]; - if ((c>='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; + for(int i = 0; i < (int)strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; - tmpfilename[i]='_'; - }; + tmpfilename[i] = '_'; + } - strncat(tmpfilename,".xiz",maxfilename+10); + strncat(tmpfilename, ".xiz", maxfilename + 10); - int fnsize=strlen(dirname)+strlen(tmpfilename)+10; - char *filename=new char[fnsize+4]; - ZERO(filename,fnsize+2); + int fnsize = strlen(dirname) + strlen(tmpfilename) + 10; + char *filename = new char[fnsize + 4]; + ZERO(filename, fnsize + 2); - snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename); + snprintf(filename, fnsize, "%s/%s", dirname, tmpfilename); remove(filename); part->saveXML(filename); - addtobank(ninstrument,tmpfilename,(char *) part->Pname); + addtobank(ninstrument, tmpfilename, (char *) part->Pname); - delete[]filename; -}; + delete[] filename; +} /* * Loads the instrument from the bank */ -void Bank::loadfromslot(unsigned int ninstrument,Part *part) +void Bank::loadfromslot(unsigned int ninstrument, Part *part) { - if (emptyslot(ninstrument)) return; + if(emptyslot(ninstrument)) + return; part->defaultsinstrument(); // printf("load: %s\n",ins[ninstrument].filename); part->loadXMLinstrument(ins[ninstrument].filename); - -}; +} /* @@ -225,160 +255,173 @@ void Bank::loadfromslot(unsigned int ninstrument,Part *part) */ int Bank::loadbank(const char *bankdirname) { - DIR *dir=opendir(bankdirname); + DIR *dir = opendir(bankdirname); clearbank(); - if (dir==NULL) return(-1); + if(dir == NULL) + return -1; - if (dirname!=NULL) delete[]dirname; - dirname=new char[strlen(bankdirname)+1]; - snprintf(dirname,strlen(bankdirname)+1,"%s",bankdirname); + if(dirname != NULL) + delete[] dirname; + dirname = new char[strlen(bankdirname) + 1]; + snprintf(dirname, strlen(bankdirname) + 1, "%s", bankdirname); - bankfiletitle=dirname; + bankfiletitle = dirname; // printf("loadbank %s/\n",bankdirname); struct dirent *fn; - while ((fn=readdir(dir))) { - const char *filename= fn->d_name; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; //sa verific daca e si extensia dorita - if (strstr(filename,INSTRUMENT_EXTENSION)==NULL) continue; + if(strstr(filename, INSTRUMENT_EXTENSION) == NULL) + continue; //verify if the name is like this NNNN-name (where N is a digit) - int no=0; - unsigned int startname=0; + int no = 0; + unsigned int startname = 0; - for (unsigned int i=0;i<4;i++) { - if (strlen(filename)<=i) break; + for(unsigned int i = 0; i < 4; i++) { + if(strlen(filename) <= i) + break; - if ((filename[i]>='0')&&(filename[i]<='9')) { - no=no*10+(filename[i]-'0'); + if((filename[i] >= '0') && (filename[i] <= '9')) { + no = no * 10 + (filename[i] - '0'); startname++; - }; - }; + } + } - if ((startname+1)=2;i--) { - if (name[i]=='.') { - name[i]='\0'; + for(int i = strlen(name) - 1; i >= 2; i--) { + if(name[i] == '.') { + name[i] = '\0'; break; - }; - }; + } + } - if (no!=0) {//the instrument position in the bank is found - addtobank(no-1,filename,&name[startname]); - } else { - addtobank(-1,filename,name); - }; - - }; + if(no != 0) //the instrument position in the bank is found + addtobank(no - 1, filename, &name[startname]); + else + addtobank(-1, filename, name); + ; + } closedir(dir); - if (dirname!=NULL) { - sprintf(config.cfg.currentBankDir,"%s",dirname); - }; + if(dirname != NULL) + sprintf(config.cfg.currentBankDir, "%s", dirname); + ; - return(0); -}; + return 0; +} /* * Makes a new bank, put it on a file and makes it current bank */ int Bank::newbank(const char *newbankdirname) { - int result; + int result; char tmpfilename[MAX_STRING_SIZE]; char bankdir[MAX_STRING_SIZE]; - snprintf(bankdir,MAX_STRING_SIZE,"%s",config.cfg.bankRootDirList[0]); + snprintf(bankdir, MAX_STRING_SIZE, "%s", config.cfg.bankRootDirList[0]); - if (((bankdir[strlen(bankdir)-1])!='/')&&((bankdir[strlen(bankdir)-1])!='\\')) { - strncat(bankdir,"/",MAX_STRING_SIZE); - }; - strncat(bankdir,newbankdirname,MAX_STRING_SIZE); + if(((bankdir[strlen(bankdir) - 1]) != '/') + && ((bankdir[strlen(bankdir) - 1]) != '\\')) + strncat(bankdir, "/", MAX_STRING_SIZE); + ; + strncat(bankdir, newbankdirname, MAX_STRING_SIZE); #ifdef OS_WINDOWS - result=mkdir(bankdir); + result = mkdir(bankdir); #else - result=mkdir(bankdir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + result = mkdir(bankdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif - if (result<0) return(-1); + if(result < 0) + return -1; - snprintf(tmpfilename,MAX_STRING_SIZE,"%s/%s",bankdir,FORCE_BANK_DIR_FILE); + snprintf(tmpfilename, + MAX_STRING_SIZE, + "%s/%s", + bankdir, + FORCE_BANK_DIR_FILE); // printf("%s\n",tmpfilename); - FILE *tmpfile=fopen(tmpfilename,"w+"); + FILE *tmpfile = fopen(tmpfilename, "w+"); fclose(tmpfile); - return(loadbank(bankdir)); -}; + return loadbank(bankdir); +} /* * Check if the bank is locked (i.e. the file opened was readonly) */ int Bank::locked() { - return(dirname==NULL); -}; + return dirname == NULL; +} /* * Swaps a slot with another */ void Bank::swapslot(unsigned int n1, unsigned int n2) { - if ((n1==n2)||(locked())) return; - if (emptyslot(n1)&&(emptyslot(n2))) return; - if (emptyslot(n1)) {//change n1 to n2 in order to make - int tmp=n2; - n2=n1; - n1=tmp; - }; + if((n1 == n2) || (locked())) + return; + if(emptyslot(n1) && (emptyslot(n2))) + return; + if(emptyslot(n1)) { //change n1 to n2 in order to make + int tmp = n2; + n2 = n1; + n1 = tmp; + } - if (emptyslot(n2)) {//this is just a movement from slot1 to slot2 - setname(n1,getname(n1),n2); - ins[n2]=ins[n1]; - ins[n1].used=false; - ins[n1].name[0]='\0'; - ins[n1].filename=NULL; - ins[n1].info.PADsynth_used=0; - } else {//if both slots are used - if (strcmp(ins[n1].name,ins[n2].name)==0) {//change the name of the second instrument if the name are equal - strncat(ins[n2].name,"2",PART_MAX_NAME_LEN); - }; - setname(n1,getname(n1),n2); - setname(n2,getname(n2),n1); + if(emptyslot(n2)) { //this is just a movement from slot1 to slot2 + setname(n1, getname(n1), n2); + ins[n2] = ins[n1]; + ins[n1].used = false; + ins[n1].name[0] = '\0'; + ins[n1].filename = NULL; + ins[n1].info.PADsynth_used = 0; + } + else { //if both slots are used + if(strcmp(ins[n1].name, ins[n2].name) == 0) //change the name of the second instrument if the name are equal + strncat(ins[n2].name, "2", PART_MAX_NAME_LEN); + ; + setname(n1, getname(n1), n2); + setname(n2, getname(n2), n1); ins_t tmp; - tmp.used=true; - strcpy(tmp.name,ins[n2].name); - char *tmpfilename=ins[n2].filename; - bool padsynth_used=ins[n2].info.PADsynth_used; + tmp.used = true; + strcpy(tmp.name, ins[n2].name); + char *tmpfilename = ins[n2].filename; + bool padsynth_used = ins[n2].info.PADsynth_used; - ins[n2]=ins[n1]; - strcpy(ins[n1].name,tmp.name); - ins[n1].filename=tmpfilename; - ins[n1].info.PADsynth_used=padsynth_used; - }; - -}; + ins[n2] = ins[n1]; + strcpy(ins[n1].name, tmp.name); + ins[n1].filename = tmpfilename; + ins[n1].info.PADsynth_used = padsynth_used; + } +} //a helper function that compares 2 banks[] arrays -int Bank_compar(const void *a,const void *b) +int Bank_compar(const void *a, const void *b) { - struct Bank::bankstruct *bank1= (Bank::bankstruct *)a; - struct Bank::bankstruct *bank2= (Bank::bankstruct *)b; - if (((bank1->name)==NULL)||((bank2->name)==NULL)) return(0); + struct Bank::bankstruct *bank1 = (Bank::bankstruct *)a; + struct Bank::bankstruct *bank2 = (Bank::bankstruct *)b; + if(((bank1->name) == NULL) || ((bank2->name) == NULL)) + return 0; - int result=strcasecmp(bank1->name,bank2->name); - return(result<0); -}; + int result = strcasecmp(bank1->name, bank2->name); + return result < 0; +} /* @@ -387,56 +430,61 @@ int Bank_compar(const void *a,const void *b) void Bank::rescanforbanks() { - for (int i=0;id_name; - if (dirname[0]=='.') continue; + while((fn = readdir(dir))) { + const char *dirname = fn->d_name; + if(dirname[0] == '.') + continue; - snprintf(bank.dir,maxdirsize,"%s%s%s/",rootdir,separator,dirname); - snprintf(bank.name,maxdirsize,"%s",dirname); + snprintf(bank.dir, maxdirsize, "%s%s%s/", rootdir, separator, dirname); + snprintf(bank.name, maxdirsize, "%s", dirname); //find out if the directory contains at least 1 instrument - bool isbank=false; + bool isbank = false; - DIR *d=opendir(bank.dir); - if (d==NULL) continue; + DIR *d = opendir(bank.dir); + if(d == NULL) + continue; struct dirent *fname; - while ((fname=readdir(d))) { - if ((strstr(fname->d_name,INSTRUMENT_EXTENSION)!=NULL)|| - (strstr(fname->d_name,FORCE_BANK_DIR_FILE)!=NULL)) { - isbank=true; - break;//aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank - }; - }; + while((fname = readdir(d))) { + if((strstr(fname->d_name, INSTRUMENT_EXTENSION) != NULL) + || (strstr(fname->d_name, FORCE_BANK_DIR_FILE) != NULL)) { + isbank = true; + break; //aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank + } + } closedir(d); - if (isbank) { - int pos=-1; - for (int i=1;i=0) { - banks[pos].name=new char[maxdirsize]; - banks[pos].dir=new char[maxdirsize]; - snprintf(banks[pos].name,maxdirsize,"%s",bank.name); - snprintf(banks[pos].dir,maxdirsize,"%s",bank.dir); - }; - - }; - - }; + if(pos >= 0) { + banks[pos].name = new char[maxdirsize]; + banks[pos].dir = new char[maxdirsize]; + snprintf(banks[pos].name, maxdirsize, "%s", bank.name); + snprintf(banks[pos].dir, maxdirsize, "%s", bank.dir); + } + } + } closedir(dir); - -}; +} void Bank::clearbank() { - for (int i=0;i=0)&&(pos=BANK_SIZE) pos=-1; + if((pos >= 0) && (pos < BANK_SIZE)) { + if(ins[pos].used) + pos = -1; //force it to find a new free position + } + else + if(pos >= BANK_SIZE) + pos = -1; - if (pos<0) {//find a free position - for (int i=BANK_SIZE-1;i>=0;i--) - if (!ins[i].used) { - pos=i; + if(pos < 0) { //find a free position + for(int i = BANK_SIZE - 1; i >= 0; i--) + if(!ins[i].used) { + pos = i; break; - }; + } + ; + } - }; - - if (pos<0) return (-1);//the bank is full + if(pos < 0) + return -1; //the bank is full // printf("%s %d\n",filename,pos); deletefrombank(pos); - ins[pos].used=true; - snprintf(ins[pos].name,PART_MAX_NAME_LEN,"%s",name); + ins[pos].used = true; + snprintf(ins[pos].name, PART_MAX_NAME_LEN, "%s", name); - snprintf(tmpinsname[pos],PART_MAX_NAME_LEN+10," "); + snprintf(tmpinsname[pos], PART_MAX_NAME_LEN + 10, " "); - int len=strlen(filename)+1+strlen(dirname); - ins[pos].filename=new char[len+2]; - ins[pos].filename[len+1]=0; - snprintf(ins[pos].filename,len+1,"%s/%s",dirname,filename); + int len = strlen(filename) + 1 + strlen(dirname); + ins[pos].filename = new char[len + 2]; + ins[pos].filename[len + 1] = 0; + snprintf(ins[pos].filename, len + 1, "%s/%s", dirname, filename); //see if PADsynth is used - if (config.cfg.CheckPADsynth) { - XMLwrapper *xml=new XMLwrapper(); - xml->checkfileinformation(ins[pos].filename); + if(config.cfg.CheckPADsynth) { + XMLwrapper *xml = new XMLwrapper(); + xml->loadXMLfile(ins[pos].filename); - ins[pos].info.PADsynth_used=xml->information.PADsynth_used; + ins[pos].info.PADsynth_used = xml->hasPadSynth(); delete xml; - } else ins[pos].info.PADsynth_used=false; + } + else + ins[pos].info.PADsynth_used = false; - return(0); -}; + return 0; +} bool Bank::isPADsynth_used(unsigned int ninstrument) { - if (config.cfg.CheckPADsynth==0) return(0); - else return(ins[ninstrument].info.PADsynth_used); -}; + if(config.cfg.CheckPADsynth == 0) + return 0; + else + return ins[ninstrument].info.PADsynth_used; +} void Bank::deletefrombank(int pos) { - if ((pos<0)||(pos>=BANK_SIZE)) return; - ins[pos].used=false; - ZERO(ins[pos].name,PART_MAX_NAME_LEN+1); - if (ins[pos].filename!=NULL) { - delete []ins[pos].filename; - ins[pos].filename=NULL; - }; + if((pos < 0) || (pos >= BANK_SIZE)) + return; + ins[pos].used = false; + ZERO(ins[pos].name, PART_MAX_NAME_LEN + 1); + if(ins[pos].filename != NULL) { + delete [] ins[pos].filename; + ins[pos].filename = NULL; + } - ZERO(tmpinsname[pos],PART_MAX_NAME_LEN+20); - -}; + ZERO(tmpinsname[pos], PART_MAX_NAME_LEN + 20); +} diff --git a/plugins/zynaddsubfx/src/Misc/Bank.h b/plugins/zynaddsubfx/src/Misc/Bank.h index 8359b541b..81acc3dec 100644 --- a/plugins/zynaddsubfx/src/Misc/Bank.h +++ b/plugins/zynaddsubfx/src/Misc/Bank.h @@ -38,70 +38,70 @@ * \todo add in strings to replace char* */ class Bank { -public: - /**Constructor*/ - Bank(); - ~Bank(); - char *getname(unsigned int ninstrument); - char *getnamenumbered(unsigned int ninstrument); - void setname(unsigned int ninstrument,const char *newname,int newslot);//if newslot==-1 then this is ignored, else it will be put on that slot - bool isPADsynth_used(unsigned int ninstrument); + public: + /**Constructor*/ + Bank(); + ~Bank(); + char *getname(unsigned int ninstrument); + char *getnamenumbered(unsigned int ninstrument); + void setname(unsigned int ninstrument, const char *newname, int newslot); //if newslot==-1 then this is ignored, else it will be put on that slot + bool isPADsynth_used(unsigned int ninstrument); - /**returns 0 if the slot is not empty or 1 if the slot is empty - * \todo start using bool before facepalm*/ - int emptyslot(unsigned int ninstrument); + /**returns 0 if the slot is not empty or 1 if the slot is empty + * \todo start using bool before facepalm*/ + int emptyslot(unsigned int ninstrument); - /**Empties out the selected slot*/ - void clearslot(unsigned int ninstrument); - /**Saves the given Part to slot*/ - void savetoslot(unsigned int ninstrument,Part *part); - /**Loads the given slot into a Part*/ - void loadfromslot(unsigned int ninstrument,Part *part); + /**Empties out the selected slot*/ + void clearslot(unsigned int ninstrument); + /**Saves the given Part to slot*/ + void savetoslot(unsigned int ninstrument, Part *part); + /**Loads the given slot into a Part*/ + void loadfromslot(unsigned int ninstrument, Part *part); - /**Swaps Slots*/ - void swapslot(unsigned int n1,unsigned int n2); + /**Swaps Slots*/ + void swapslot(unsigned int n1, unsigned int n2); - int loadbank(const char *bankdirname); - int newbank(const char *newbankdirname); + int loadbank(const char *bankdirname); + int newbank(const char *newbankdirname); - char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) - int locked(); + char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) + int locked(); - void rescanforbanks(); + void rescanforbanks(); - struct bankstruct { - char *dir; - char *name; - }; + struct bankstruct { + char *dir; + char *name; + }; - bankstruct banks[MAX_NUM_BANKS]; + bankstruct banks[MAX_NUM_BANKS]; -private: + private: - //it adds a filename to the bank - //if pos is -1 it try to find a position - //returns -1 if the bank is full, or 0 if the instrument was added - int addtobank(int pos,const char* filename,const char* name); + //it adds a filename to the bank + //if pos is -1 it try to find a position + //returns -1 if the bank is full, or 0 if the instrument was added + int addtobank(int pos, const char *filename, const char *name); - void deletefrombank(int pos); + void deletefrombank(int pos); - void clearbank(); + void clearbank(); - char defaultinsname[PART_MAX_NAME_LEN]; - char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN+20];//this keeps the numbered names + char defaultinsname[PART_MAX_NAME_LEN]; + char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN + 20]; //this keeps the numbered names - struct ins_t { - bool used; - char name[PART_MAX_NAME_LEN+1]; - char *filename; - struct { - bool PADsynth_used; - } info; - }ins[BANK_SIZE]; + struct ins_t { + bool used; + char name[PART_MAX_NAME_LEN + 1]; + char *filename; + struct { + bool PADsynth_used; + } info; + } ins[BANK_SIZE]; - char *dirname; + char *dirname; - void scanrootdir(char *rootdir);//scans a root dir for banks + void scanrootdir(char *rootdir); //scans a root dir for banks }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Config.cpp b/plugins/zynaddsubfx/src/Misc/Config.cpp index 9a290158c..94966e4af 100644 --- a/plugins/zynaddsubfx/src/Misc/Config.cpp +++ b/plugins/zynaddsubfx/src/Misc/Config.cpp @@ -33,309 +33,369 @@ #include "XMLwrapper.h" Config::Config() -{ -}; +{} void Config::init() { - maxstringsize=MAX_STRING_SIZE;//for ui + maxstringsize = MAX_STRING_SIZE; //for ui //defaults - cfg.SampleRate=44100; - cfg.SoundBufferSize=256; - cfg.OscilSize=1024; - cfg.SwapStereo=0; + cfg.SampleRate = 44100; + cfg.SoundBufferSize = 256; + cfg.OscilSize = 1024; + cfg.SwapStereo = 0; - cfg.LinuxOSSWaveOutDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE,"/dev/dsp"); - cfg.LinuxOSSSeqInDev=new char[MAX_STRING_SIZE]; - snprintf(cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE,"/dev/sequencer"); + cfg.LinuxOSSWaveOutDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSWaveOutDev, MAX_STRING_SIZE, "/dev/dsp"); + cfg.LinuxOSSSeqInDev = new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSSeqInDev, MAX_STRING_SIZE, "/dev/sequencer"); - cfg.DumpFile=new char[MAX_STRING_SIZE]; - snprintf(cfg.DumpFile,MAX_STRING_SIZE,"zynaddsubfx_dump.txt"); + cfg.DumpFile = new char[MAX_STRING_SIZE]; + snprintf(cfg.DumpFile, MAX_STRING_SIZE, "zynaddsubfx_dump.txt"); - cfg.WindowsWaveOutId=0; - cfg.WindowsMidiInId=0; + cfg.WindowsWaveOutId = 0; + cfg.WindowsMidiInId = 0; - cfg.BankUIAutoClose=0; - cfg.DumpNotesToFile=0; - cfg.DumpAppend=1; + cfg.BankUIAutoClose = 0; + cfg.DumpNotesToFile = 0; + cfg.DumpAppend = 1; - cfg.GzipCompression=3; + cfg.GzipCompression = 3; - cfg.Interpolation=0; - cfg.CheckPADsynth=1; + cfg.Interpolation = 0; + cfg.CheckPADsynth = 1; - cfg.UserInterfaceMode=0; - cfg.VirKeybLayout=1; - winwavemax=1; - winmidimax=1; + cfg.UserInterfaceMode = 0; + cfg.VirKeybLayout = 1; + winwavemax = 1; + winmidimax = 1; //try to find out how many input midi devices are there #ifdef WINMIDIIN - winmidimax=midiInGetNumDevs(); - if (winmidimax==0) winmidimax=1; + winmidimax = midiInGetNumDevs(); + if(winmidimax == 0) + winmidimax = 1; #endif - winmididevices=new winmidionedevice[winmidimax]; - for (int i=0;iloadXMLfile(filename)<0) return; - if (xmlcfg->enterbranch("CONFIGURATION")) { - cfg.SampleRate=xmlcfg->getpar("sample_rate",cfg.SampleRate,4000,1024000); - cfg.SoundBufferSize=xmlcfg->getpar("sound_buffer_size",cfg.SoundBufferSize,16,8192); - cfg.OscilSize=xmlcfg->getpar("oscil_size",cfg.OscilSize,MAX_AD_HARMONICS*2,131072); - cfg.SwapStereo=xmlcfg->getpar("swap_stereo",cfg.SwapStereo,0,1); - cfg.BankUIAutoClose=xmlcfg->getpar("bank_window_auto_close",cfg.BankUIAutoClose,0,1); + XMLwrapper *xmlcfg = new XMLwrapper(); + if(xmlcfg->loadXMLfile(filename) < 0) + return; + if(xmlcfg->enterbranch("CONFIGURATION")) { + cfg.SampleRate = xmlcfg->getpar("sample_rate", + cfg.SampleRate, + 4000, + 1024000); + cfg.SoundBufferSize = xmlcfg->getpar("sound_buffer_size", + cfg.SoundBufferSize, + 16, + 8192); + cfg.OscilSize = xmlcfg->getpar("oscil_size", + cfg.OscilSize, + MAX_AD_HARMONICS * 2, + 131072); + cfg.SwapStereo = xmlcfg->getpar("swap_stereo", + cfg.SwapStereo, + 0, + 1); + cfg.BankUIAutoClose = xmlcfg->getpar("bank_window_auto_close", + cfg.BankUIAutoClose, + 0, + 1); - cfg.DumpNotesToFile=xmlcfg->getpar("dump_notes_to_file",cfg.DumpNotesToFile,0,1); - cfg.DumpAppend=xmlcfg->getpar("dump_append",cfg.DumpAppend,0,1); - xmlcfg->getparstr("dump_file",cfg.DumpFile,MAX_STRING_SIZE); + cfg.DumpNotesToFile = xmlcfg->getpar("dump_notes_to_file", + cfg.DumpNotesToFile, + 0, + 1); + cfg.DumpAppend = xmlcfg->getpar("dump_append", + cfg.DumpAppend, + 0, + 1); + xmlcfg->getparstr("dump_file", cfg.DumpFile, MAX_STRING_SIZE); - cfg.GzipCompression=xmlcfg->getpar("gzip_compression",cfg.GzipCompression,0,9); + cfg.GzipCompression = xmlcfg->getpar("gzip_compression", + cfg.GzipCompression, + 0, + 9); - xmlcfg->getparstr("bank_current",cfg.currentBankDir,MAX_STRING_SIZE); - cfg.Interpolation=xmlcfg->getpar("interpolation",cfg.Interpolation,0,1); + xmlcfg->getparstr("bank_current", cfg.currentBankDir, MAX_STRING_SIZE); + cfg.Interpolation = xmlcfg->getpar("interpolation", + cfg.Interpolation, + 0, + 1); - cfg.CheckPADsynth=xmlcfg->getpar("check_pad_synth",cfg.CheckPADsynth,0,1); + cfg.CheckPADsynth = xmlcfg->getpar("check_pad_synth", + cfg.CheckPADsynth, + 0, + 1); - cfg.UserInterfaceMode=xmlcfg->getpar("user_interface_mode",cfg.UserInterfaceMode,0,2); - cfg.VirKeybLayout=xmlcfg->getpar("virtual_keyboard_layout",cfg.VirKeybLayout,0,10); + cfg.UserInterfaceMode = xmlcfg->getpar("user_interface_mode", + cfg.UserInterfaceMode, + 0, + 2); + cfg.VirKeybLayout = xmlcfg->getpar("virtual_keyboard_layout", + cfg.VirKeybLayout, + 0, + 10); //get bankroot dirs - for (int i=0;ienterbranch("BANKROOT",i)) { - cfg.bankRootDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("bank_root",cfg.bankRootDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("BANKROOT", i)) { + cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("bank_root", + cfg.bankRootDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //get preset root dirs - for (int i=0;ienterbranch("PRESETSROOT",i)) { - cfg.presetsDirList[i]=new char[MAX_STRING_SIZE]; - xmlcfg->getparstr("presets_root",cfg.presetsDirList[i],MAX_STRING_SIZE); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) { + if(xmlcfg->enterbranch("PRESETSROOT", i)) { + cfg.presetsDirList[i] = new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("presets_root", + cfg.presetsDirList[i], + MAX_STRING_SIZE); xmlcfg->exitbranch(); - }; - }; + } + } //linux stuff - xmlcfg->getparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE); - xmlcfg->getparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_wave_out_dev", + cfg.LinuxOSSWaveOutDev, + MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_seq_in_dev", + cfg.LinuxOSSSeqInDev, + MAX_STRING_SIZE); //windows stuff - cfg.WindowsWaveOutId=xmlcfg->getpar("windows_wave_out_id",cfg.WindowsWaveOutId,0,winwavemax); - cfg.WindowsMidiInId=xmlcfg->getpar("windows_midi_in_id",cfg.WindowsMidiInId,0,winmidimax); + cfg.WindowsWaveOutId = xmlcfg->getpar("windows_wave_out_id", + cfg.WindowsWaveOutId, + 0, + winwavemax); + cfg.WindowsMidiInId = xmlcfg->getpar("windows_midi_in_id", + cfg.WindowsMidiInId, + 0, + winmidimax); xmlcfg->exitbranch(); - }; - delete(xmlcfg); + } + delete (xmlcfg); - cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0))); - -}; + cfg.OscilSize = (int) pow(2, ceil(log(cfg.OscilSize - 1.0) / log(2.0))); +} void Config::saveConfig(const char *filename) { - XMLwrapper *xmlcfg=new XMLwrapper(); + XMLwrapper *xmlcfg = new XMLwrapper(); xmlcfg->beginbranch("CONFIGURATION"); - xmlcfg->addpar("sample_rate",cfg.SampleRate); - xmlcfg->addpar("sound_buffer_size",cfg.SoundBufferSize); - xmlcfg->addpar("oscil_size",cfg.OscilSize); - xmlcfg->addpar("swap_stereo",cfg.SwapStereo); - xmlcfg->addpar("bank_window_auto_close",cfg.BankUIAutoClose); + xmlcfg->addpar("sample_rate", cfg.SampleRate); + xmlcfg->addpar("sound_buffer_size", cfg.SoundBufferSize); + xmlcfg->addpar("oscil_size", cfg.OscilSize); + xmlcfg->addpar("swap_stereo", cfg.SwapStereo); + xmlcfg->addpar("bank_window_auto_close", cfg.BankUIAutoClose); - xmlcfg->addpar("dump_notes_to_file",cfg.DumpNotesToFile); - xmlcfg->addpar("dump_append",cfg.DumpAppend); - xmlcfg->addparstr("dump_file",cfg.DumpFile); + xmlcfg->addpar("dump_notes_to_file", cfg.DumpNotesToFile); + xmlcfg->addpar("dump_append", cfg.DumpAppend); + xmlcfg->addparstr("dump_file", cfg.DumpFile); - xmlcfg->addpar("gzip_compression",cfg.GzipCompression); + xmlcfg->addpar("gzip_compression", cfg.GzipCompression); - xmlcfg->addpar("check_pad_synth",cfg.CheckPADsynth); + xmlcfg->addpar("check_pad_synth", cfg.CheckPADsynth); - xmlcfg->addparstr("bank_current",cfg.currentBankDir); + xmlcfg->addparstr("bank_current", cfg.currentBankDir); - xmlcfg->addpar("user_interface_mode",cfg.UserInterfaceMode); - xmlcfg->addpar("virtual_keyboard_layout",cfg.VirKeybLayout); + xmlcfg->addpar("user_interface_mode", cfg.UserInterfaceMode); + xmlcfg->addpar("virtual_keyboard_layout", cfg.VirKeybLayout); - for (int i=0;ibeginbranch("BANKROOT",i); - xmlcfg->addparstr("bank_root",cfg.bankRootDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.bankRootDirList[i] != NULL) { + xmlcfg->beginbranch("BANKROOT", i); + xmlcfg->addparstr("bank_root", cfg.bankRootDirList[i]); xmlcfg->endbranch(); - }; + } + ; - for (int i=0;ibeginbranch("PRESETSROOT",i); - xmlcfg->addparstr("presets_root",cfg.presetsDirList[i]); + for(int i = 0; i < MAX_BANK_ROOT_DIRS; i++) + if(cfg.presetsDirList[i] != NULL) { + xmlcfg->beginbranch("PRESETSROOT", i); + xmlcfg->addparstr("presets_root", cfg.presetsDirList[i]); xmlcfg->endbranch(); - }; + } + ; - xmlcfg->addpar("interpolation",cfg.Interpolation); + xmlcfg->addpar("interpolation", cfg.Interpolation); //linux stuff - xmlcfg->addparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev); - xmlcfg->addparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev); + xmlcfg->addparstr("linux_oss_wave_out_dev", cfg.LinuxOSSWaveOutDev); + xmlcfg->addparstr("linux_oss_seq_in_dev", cfg.LinuxOSSSeqInDev); //windows stuff - xmlcfg->addpar("windows_wave_out_id",cfg.WindowsWaveOutId); - xmlcfg->addpar("windows_midi_in_id",cfg.WindowsMidiInId); + xmlcfg->addpar("windows_wave_out_id", cfg.WindowsWaveOutId); + xmlcfg->addpar("windows_midi_in_id", cfg.WindowsMidiInId); xmlcfg->endbranch(); - int tmp=cfg.GzipCompression; - cfg.GzipCompression=0; + int tmp = cfg.GzipCompression; + cfg.GzipCompression = 0; xmlcfg->saveXMLfile(filename); - cfg.GzipCompression=tmp; + cfg.GzipCompression = tmp; - delete(xmlcfg); -}; + delete (xmlcfg); +} void Config::getConfigFileName(char *name, int namesize) { - name[0]=0; + name[0] = 0; #ifdef OS_LINUX - snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s%s", getenv("HOME"), "/.zynaddsubfxXML.cfg"); #else - snprintf(name,namesize,"%s","zynaddsubfxXML.cfg"); + snprintf(name, namesize, "%s", "zynaddsubfxXML.cfg"); #endif - -}; +} diff --git a/plugins/zynaddsubfx/src/Misc/Config.h b/plugins/zynaddsubfx/src/Misc/Config.h index 9d4fef615..f08505d80 100644 --- a/plugins/zynaddsubfx/src/Misc/Config.h +++ b/plugins/zynaddsubfx/src/Misc/Config.h @@ -29,43 +29,43 @@ /**Configuration file functions*/ class Config { -public: - /** Constructor*/ - Config(); - /** Destructor*/ - ~Config(); - struct { - char *LinuxOSSWaveOutDev,*LinuxOSSSeqInDev; - int SampleRate,SoundBufferSize,OscilSize,SwapStereo; - int WindowsWaveOutId,WindowsMidiInId; - int BankUIAutoClose; - int DumpNotesToFile,DumpAppend; - int GzipCompression; - int Interpolation; - char *DumpFile; - char *bankRootDirList[MAX_BANK_ROOT_DIRS],*currentBankDir; - char *presetsDirList[MAX_BANK_ROOT_DIRS]; - int CheckPADsynth; - int UserInterfaceMode; - int VirKeybLayout; - } cfg; - int winwavemax,winmidimax;//number of wave/midi devices on Windows - int maxstringsize; + public: + /** Constructor*/ + Config(); + /** Destructor*/ + ~Config(); + struct { + char *LinuxOSSWaveOutDev, *LinuxOSSSeqInDev; + int SampleRate, SoundBufferSize, OscilSize, SwapStereo; + int WindowsWaveOutId, WindowsMidiInId; + int BankUIAutoClose; + int DumpNotesToFile, DumpAppend; + int GzipCompression; + int Interpolation; + char *DumpFile; + char *bankRootDirList[MAX_BANK_ROOT_DIRS], *currentBankDir; + char *presetsDirList[MAX_BANK_ROOT_DIRS]; + int CheckPADsynth; + int UserInterfaceMode; + int VirKeybLayout; + } cfg; + int winwavemax, winmidimax; //number of wave/midi devices on Windows + int maxstringsize; - struct winmidionedevice { - char *name; - }; - winmidionedevice *winmididevices; + struct winmidionedevice { + char *name; + }; + winmidionedevice *winmididevices; - void clearbankrootdirlist(); - void clearpresetsdirlist(); - void init(); - void save(); + void clearbankrootdirlist(); + void clearpresetsdirlist(); + void init(); + void save(); -private: - void readConfig(const char *filename); - void saveConfig(const char *filename); - void getConfigFileName(char *name,int namesize); + private: + void readConfig(const char *filename); + void saveConfig(const char *filename); + void getConfigFileName(char *name, int namesize); }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Control.h b/plugins/zynaddsubfx/src/Misc/Control.h index 780d4b9e6..297e6f0da 100644 --- a/plugins/zynaddsubfx/src/Misc/Control.h +++ b/plugins/zynaddsubfx/src/Misc/Control.h @@ -27,74 +27,74 @@ class Control { -public: - /** - * The parent is the logical owner of this control. Parent should only - * be null for the root node. - * The id is a string uniquely identifying this control within the - * context of the parent control. No spaces or dots are allowed in this - * id. - * Children id's are denoted by ., so that one - * can refer to any control in the hierarchy by separating them with - * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude - */ - Control(Control *parent, string id); + public: + /** + * The parent is the logical owner of this control. Parent should only + * be null for the root node. + * The id is a string uniquely identifying this control within the + * context of the parent control. No spaces or dots are allowed in this + * id. + * Children id's are denoted by ., so that one + * can refer to any control in the hierarchy by separating them with + * dots. Example: Main.AddSynth.FrequencyLFO.Amplitude + */ + Control(Control *parent, string id); - /** - * Will recursively get the XML representation for all the subcontrols. - * Used for saving to file and copy-pasting settings - */ - string getXMLRepresentation(); + /** + * Will recursively get the XML representation for all the subcontrols. + * Used for saving to file and copy-pasting settings + */ + string getXMLRepresentation(); - /** - * Set the value of this (and possibly subcomponents as well) based on - * a xml description. - */ - void restoreFromXML(string xml); + /** + * Set the value of this (and possibly subcomponents as well) based on + * a xml description. + */ + void restoreFromXML(string xml); - /** - * Register a controluser. This will cause this user to be notified - * whenever the contents of the control changes. - */ - void registerControlUser(ControlUser *user); - - /** - * This should return a string representation of the controls internal - * value - */ - virtual string getStringRepresentation() = 0; + /** + * Register a controluser. This will cause this user to be notified + * whenever the contents of the control changes. + */ + void registerControlUser(ControlUser *user); + /** + * This should return a string representation of the controls internal + * value + */ + virtual string getStringRepresentation() = 0; }; -class FloatControl : public Control +class FloatControl:public Control { -public: - /** - * Set the value of this control. If the ControlUser variable is set, - * then this user will not be updated with the new value. This is to - * avoid setting a value being set back to the source that set it - * (which would be redundant, or possibly causing infinite setValue - * loops). - * NOTE: this function is thread-safe (using a mutex internally) - */ - void setValue(float value, ControlUser *user = NULL); + public: + /** + * Set the value of this control. If the ControlUser variable is set, + * then this user will not be updated with the new value. This is to + * avoid setting a value being set back to the source that set it + * (which would be redundant, or possibly causing infinite setValue + * loops). + * NOTE: this function is thread-safe (using a mutex internally) + */ + void setValue(float value, ControlUser *user = NULL); - /** - * Reimplemented from Control - */ - virtual string getStringRepresentation(); + /** + * Reimplemented from Control + */ + virtual string getStringRepresentation(); - float value(); + float value(); }; class ControlUser { -public: - /** - * Pure virtual method, to notify the controluser that the value has - * been changed internally, and needs to be read again. - */ - virtual void controlUpdated(Control *control) = 0; + public: + /** + * Pure virtual method, to notify the controluser that the value has + * been changed internally, and needs to be read again. + */ + virtual void controlUpdated(Control *control) = 0; }; #endif /* _CONTROL_H_ */ + diff --git a/plugins/zynaddsubfx/src/Misc/Dump.cpp b/plugins/zynaddsubfx/src/Misc/Dump.cpp index cb1728ec6..4c13c9464 100644 --- a/plugins/zynaddsubfx/src/Misc/Dump.cpp +++ b/plugins/zynaddsubfx/src/Misc/Dump.cpp @@ -28,80 +28,97 @@ Dump dump; Dump::Dump() { - file=NULL; - tick=0; - k=0; - keyspressed=0; -}; + file = NULL; + tick = 0; + k = 0; + keyspressed = 0; +} Dump::~Dump() { - if (file!=NULL) { - double duration=(double)tick*(double) SOUND_BUFFER_SIZE/(double) SAMPLE_RATE; - fprintf(file,"\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n",(int) duration,keyspressed); + if(file != NULL) { + double duration = (double)tick * (double) SOUND_BUFFER_SIZE + / (double) SAMPLE_RATE; + fprintf( + file, + "\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n", + (int) duration, + keyspressed); fclose(file); - }; -}; + } +} void Dump::startnow() { - if (file!=NULL) return;//the file is already open + if(file != NULL) + return; //the file is already open - if (config.cfg.DumpNotesToFile!=0) { - if (config.cfg.DumpAppend!=0) file=fopen(config.cfg.DumpFile,"a"); - else file=fopen(config.cfg.DumpFile,"w"); - if (file==NULL) return; - if (config.cfg.DumpAppend!=0) fprintf(file,"%s","#************************************\n"); + if(config.cfg.DumpNotesToFile != 0) { + if(config.cfg.DumpAppend != 0) + file = fopen(config.cfg.DumpFile, "a"); + else + file = fopen(config.cfg.DumpFile, "w"); + if(file == NULL) + return; + if(config.cfg.DumpAppend != 0) + fprintf(file, "%s", "#************************************\n"); - time_t tm=time(NULL); + time_t tm = time(NULL); - fprintf(file,"#date/time = %s\n",ctime(&tm)); - fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE); - fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE); - fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE); - fprintf(file,"\n\nSTART\n"); - }; -}; + fprintf(file, "#date/time = %s\n", ctime(&tm)); + fprintf(file, + "#1 tick = %g milliseconds\n", + SOUND_BUFFER_SIZE * 1000.0 / SAMPLE_RATE); + fprintf(file, "SAMPLERATE = %d\n", SAMPLE_RATE); + fprintf(file, "TICKSIZE = %d #samples\n", SOUND_BUFFER_SIZE); + fprintf(file, "\n\nSTART\n"); + } +} void Dump::inctick() { tick++; -}; +} -void Dump::dumpnote(char chan,char note, char vel) +void Dump::dumpnote(char chan, char note, char vel) { - if (file==NULL) return; - if (note==0) return; - if (vel==0) fprintf(file,"n %d -> %d %d \n",tick,chan,note);//note off - else fprintf(file,"N %d -> %d %d %d \n",tick,chan,note,vel);//note on + if(file == NULL) + return; + if(note == 0) + return; + if(vel == 0) + fprintf(file, "n %d -> %d %d \n", tick, chan, note); //note off + else + fprintf(file, "N %d -> %d %d %d \n", tick, chan, note, vel); //note on - if (vel!=0) keyspressed++; + if(vel != 0) + keyspressed++; #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; +} -void Dump::dumpcontroller(char chan,unsigned int type,int par) +void Dump::dumpcontroller(char chan, unsigned int type, int par) { - if (file==NULL) return; - switch (type) { + if(file == NULL) + return; + switch(type) { case C_pitchwheel: - fprintf(file,"P %d -> %d %d\n",tick,chan,par); + fprintf(file, "P %d -> %d %d\n", tick, chan, par); break; default: - fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par); + fprintf(file, "C %d -> %d %d %d\n", tick, chan, type, par); break; - }; + } #ifndef JACKAUDIOOUT - if (k++>25) { + if(k++ > 25) { fflush(file); - k=0; - }; + k = 0; + } #endif -}; - +} diff --git a/plugins/zynaddsubfx/src/Misc/Dump.h b/plugins/zynaddsubfx/src/Misc/Dump.h index d285eb936..392fd407b 100644 --- a/plugins/zynaddsubfx/src/Misc/Dump.h +++ b/plugins/zynaddsubfx/src/Misc/Dump.h @@ -30,34 +30,35 @@ * \todo upgrade from stdio to iostream*/ class Dump { -public: - /**Constructor*/ - Dump(); - /**Destructor - * Closes the dumpfile*/ - ~Dump(); - /**Open dumpfile and prepare it for dumps - * \todo see if this fits better in the constructor*/ - void startnow(); - /**Tick the timestamp*/ - void inctick(); - /**Dump Note to dumpfile - * @param chan The channel of the note - * @param note The note - * @param vel The velocity of the note*/ - void dumpnote(char chan,char note, char vel); - /** Dump the Controller - * @param chan The channel of the Controller - * @param type The type - * @param par The value of the controller - * \todo figure out what type is exactly meaning*/ - void dumpcontroller(char chan,unsigned int type,int par); + public: + /**Constructor*/ + Dump(); + /**Destructor + * Closes the dumpfile*/ + ~Dump(); + /**Open dumpfile and prepare it for dumps + * \todo see if this fits better in the constructor*/ + void startnow(); + /**Tick the timestamp*/ + void inctick(); + /**Dump Note to dumpfile + * @param chan The channel of the note + * @param note The note + * @param vel The velocity of the note*/ + void dumpnote(char chan, char note, char vel); + /** Dump the Controller + * @param chan The channel of the Controller + * @param type The type + * @param par The value of the controller + * \todo figure out what type is exactly meaning*/ + void dumpcontroller(char chan, unsigned int type, int par); -private: - FILE *file; - int tick; - int k;//This appears to be a constant used to flush the file - //periodically when JACK is used - int keyspressed; + private: + FILE *file; + int tick; + int k; //This appears to be a constant used to flush the file + //periodically when JACK is used + int keyspressed; }; #endif + diff --git a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp index 3434a05fb..a21461f29 100644 --- a/plugins/zynaddsubfx/src/Misc/LASHClient.cpp +++ b/plugins/zynaddsubfx/src/Misc/LASHClient.cpp @@ -26,7 +26,7 @@ #include "LASHClient.h" -LASHClient::LASHClient(int* argc, char*** argv) +LASHClient::LASHClient(int *argc, char ***argv) { client = lash_init(lash_extract_args(argc, argv), "ZynAddSubFX", LASH_Config_File, LASH_PROTOCOL(2, 0)); @@ -35,56 +35,54 @@ LASHClient::LASHClient(int* argc, char*** argv) void LASHClient::setalsaid(int id) { - if (lash_enabled(client)) { - if (id != -1) + if(lash_enabled(client)) + if(id != -1) lash_alsa_client_id(client, id); - } } -void LASHClient::setjackname(const char* name) +void LASHClient::setjackname(const char *name) { - if (lash_enabled(client)) { - if (name != NULL) { + if(lash_enabled(client)) + if(name != NULL) { lash_jack_client_name(client, name); lash_event_t *event = lash_event_new_with_type(LASH_Client_Name); lash_event_set_string(event, name); lash_send_event(client, event); } - } } -LASHClient::Event LASHClient::checkevents(std::string& filename) +LASHClient::Event LASHClient::checkevents(std::string &filename) { - - if (!lash_enabled(client)) + if(!lash_enabled(client)) return NoEvent; Event received = NoEvent; - lash_event_t* event; - while (event = lash_get_event(client)) { - + lash_event_t *event; + while(event = lash_get_event(client)) { // save - if (lash_event_get_type(event) == LASH_Save_File) { - std::cerr<<"LASH event: LASH_Save_File"<defaults(); - part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; - }; + part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS; + } - partonoff(0,1);//enable the first part + partonoff(0, 1); //enable the first part - for (int nefx=0;nefxdefaults(); - Pinsparts[nefx]=-1; - }; + Pinsparts[nefx] = -1; + } //System Effects init - for (int nefx=0;nefxdefaults(); - for (int npart=0;npartchangeeffect(1); microtonal.defaults(); ShutUp(); -}; +} /* * Note On Messages (velocity=0 for NoteOff) */ -void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity) { - dump.dumpnote(chan,note,velocity); + dump.dumpnote(chan, note, velocity); - noteon(chan,note,velocity); -}; + noteon(chan, note, velocity); +} /* * Internal Note On (velocity=0 for NoteOff) */ -void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity) +void Master::noteon(unsigned char chan, + unsigned char note, + unsigned char velocity) { int npart; - if (velocity!=0) { - for (npart=0;npartPrcvchn) { - fakepeakpart[npart]=velocity*2; - if (part[npart]->Penabled!=0) part[npart]->NoteOn(note,velocity,keyshift); - }; - }; - } else { - this->NoteOff(chan,note); - }; + if(velocity != 0) { + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(chan == part[npart]->Prcvchn) { + fakepeakpart[npart] = velocity * 2; + if(part[npart]->Penabled != 0) + part[npart]->NoteOn(note, velocity, keyshift); + } + } + } + else + this->NoteOff(chan, note); + ; HDDRecorder.triggernow(); -}; +} /* * Note Off Messages */ -void Master::NoteOff(unsigned char chan,unsigned char note) +void Master::NoteOff(unsigned char chan, unsigned char note) { - dump.dumpnote(chan,note,0); + dump.dumpnote(chan, note, 0); - noteoff(chan,note); -}; + noteoff(chan, note); +} /* * Internal Note Off */ -void Master::noteoff(unsigned char chan,unsigned char note) +void Master::noteoff(unsigned char chan, unsigned char note) { int npart; - for (npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) part[npart]->NoteOff(note); - }; -}; + ; +} /* * Controllers */ -void Master::SetController(unsigned char chan,unsigned int type,int par) +void Master::SetController(unsigned char chan, unsigned int type, int par) { - dump.dumpcontroller(chan,type,par); + dump.dumpcontroller(chan, type, par); - setcontroller(chan,type,par); -}; + setcontroller(chan, type, par); +} /* * Internal Controllers */ -void Master::setcontroller(unsigned char chan,unsigned int type,int par) +void Master::setcontroller(unsigned char chan, unsigned int type, int par) { - if ((type==C_dataentryhi)||(type==C_dataentrylo)|| - (type==C_nrpnhi)||(type==C_nrpnlo)) {//Process RPN and NRPN by the Master (ignore the chan) - ctl.setparameternumber(type,par); + if((type == C_dataentryhi) || (type == C_dataentrylo) + || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan) + ctl.setparameternumber(type, par); - int parhi=-1,parlo=-1,valhi=-1,vallo=-1; - if (ctl.getnrpn(&parhi,&parlo,&valhi,&vallo)==0) {//this is NRPN + int parhi = -1, parlo = -1, valhi = -1, vallo = -1; + if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) //this is NRPN //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo); - switch (parhi) { - case 0x04://System Effects - if (parloseteffectpar_nolock(valhi,vallo); - }; + switch(parhi) { + case 0x04: //System Effects + if(parlo < NUM_SYS_EFX) + sysefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; - case 0x08://Insertion Effects - if (parloseteffectpar_nolock(valhi,vallo); - }; + case 0x08: //Insertion Effects + if(parlo < NUM_INS_EFX) + insefx[parlo]->seteffectpar_nolock(valhi, vallo); + ; break; + } + ; + } + else { //other controllers + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) //Send the controller to all part assigned to the channel + if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0)) + part[npart]->SetController(type, par); + ; - }; - }; - } else {//other controllers - for (int npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) - part[npart]->SetController(type,par); - }; - - if (type==C_allsoundsoff) { //cleanup insertion/system FX - for (int nefx=0;nefxcleanup(); - } - for (int nefx=0;nefxcleanup(); - } } - }; -}; + } +} /* * Enable/Disable a part */ -void Master::partonoff(int npart,int what) +void Master::partonoff(int npart, int what) { - if (npart>=NUM_MIDI_PARTS) return; - if (what==0) {//disable part - fakepeakpart[npart]=0; - part[npart]->Penabled=0; + if(npart >= NUM_MIDI_PARTS) + return; + if(what == 0) { //disable part + fakepeakpart[npart] = 0; + part[npart]->Penabled = 0; part[npart]->cleanup(); - for (int nefx=0;nefxcleanup(); - }; - }; - } else {//enabled - part[npart]->Penabled=1; - fakepeakpart[npart]=0; - }; -}; + ; + } + } + else { //enabled + part[npart]->Penabled = 1; + fakepeakpart[npart] = 0; + } +} /* * Master audio out (the final sound) */ -void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) +void Master::AudioOut(REALTYPE *outl, REALTYPE *outr) { - int i,npart,nefx; + int i, npart, nefx; /* //test!!!!!!!!!!!!! se poate bloca aici (mutex) if (seq.play){ - int type,par1,par2,again,midichan; - int ntrack=1; + int type,par1,par2,again,midichan; + int ntrack=1; // do{ - again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); - if (type>0) { + again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); + if (type>0) { // printf("aaa\n"); - if (type==1){//note_on or note_off - if (par2!=0) NoteOn(midichan,par1,par2); - else NoteOff(midichan,par1); - }; - }; + if (type==1){//note_on or note_off + if (par2!=0) NoteOn(midichan,par1,par2); + else NoteOff(midichan,par1); + }; + }; // } while (again); }; */ @@ -265,250 +271,287 @@ void Master::AudioOut(REALTYPE *outl,REALTYPE *outr) //Swaps the Left channel with Right Channel (if it is asked for) - if (swaplr!=0) { - REALTYPE *tmp=outl; - outl=outr; - outr=tmp; - }; + if(swaplr != 0) { + REALTYPE *tmp = outl; + outl = outr; + outr = tmp; + } //clean up the output samples - for (i=0;ipartoutl,partoutr - for (npart=0;npartPenabled!=0) part[npart]->ComputePartSmps(); + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) + if(part[npart]->Penabled != 0) + part[npart]->ComputePartSmps(); //Insertion effects - for (nefx=0;nefx=0) { - int efxpart=Pinsparts[nefx]; - if (part[efxpart]->Penabled!=0) - insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr); - }; - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(Pinsparts[nefx] >= 0) { + int efxpart = Pinsparts[nefx]; + if(part[efxpart]->Penabled != 0) + insefx[nefx]->out(part[efxpart]->partoutl, + part[efxpart]->partoutr); + } + } //Apply the part volumes and pannings (after insertion effects) - for (npart=0;npartPenabled==0) continue; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(part[npart]->Penabled == 0) + continue; - REALTYPE newvol_l=part[npart]->volume; - REALTYPE newvol_r=part[npart]->volume; - REALTYPE oldvol_l=part[npart]->oldvolumel; - REALTYPE oldvol_r=part[npart]->oldvolumer; - REALTYPE pan=part[npart]->panning; - if (pan<0.5) newvol_l*=pan*2.0; - else newvol_r*=(1.0-pan)*2.0; + REALTYPE newvol_l = part[npart]->volume; + REALTYPE newvol_r = part[npart]->volume; + REALTYPE oldvol_l = part[npart]->oldvolumel; + REALTYPE oldvol_r = part[npart]->oldvolumer; + REALTYPE pan = part[npart]->panning; + if(pan < 0.5) + newvol_l *= pan * 2.0; + else + newvol_r *= (1.0 - pan) * 2.0; - if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)|| - ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)) {//the volume or the panning has changed and needs interpolation - - for (i=0;ipartoutl[i]*=vol_l; - part[npart]->partoutr[i]*=vol_r; - }; - part[npart]->oldvolumel=newvol_l; - part[npart]->oldvolumer=newvol_r; - - } else { - for (i=0;ipartoutl[i]*=newvol_l; - part[npart]->partoutr[i]*=newvol_r; - }; - }; - }; + if(ABOVE_AMPLITUDE_THRESHOLD(oldvol_l, newvol_l) + || ABOVE_AMPLITUDE_THRESHOLD(oldvol_r, newvol_r)) { //the volume or the panning has changed and needs interpolation + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE vol_l = INTERPOLATE_AMPLITUDE(oldvol_l, + newvol_l, + i, + SOUND_BUFFER_SIZE); + REALTYPE vol_r = INTERPOLATE_AMPLITUDE(oldvol_r, + newvol_r, + i, + SOUND_BUFFER_SIZE); + part[npart]->partoutl[i] *= vol_l; + part[npart]->partoutr[i] *= vol_r; + } + part[npart]->oldvolumel = newvol_l; + part[npart]->oldvolumer = newvol_r; + } + else { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + part[npart]->partoutl[i] *= newvol_l; + part[npart]->partoutr[i] *= newvol_r; + } + } + } //System effects - for (nefx=0;nefxgeteffect()==0) continue;//the effect is disabled + for(nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(sysefx[nefx]->geteffect() == 0) + continue; //the effect is disabled //Clean up the samples used by the system effects - for (i=0;iPenabled==0) continue; + if(part[npart]->Penabled == 0) + continue; //the output volume of each part to system effect - REALTYPE vol=sysefxvol[nefx][npart]; - for (i=0;ipartoutl[i]*vol; - tmpmixr[i]+=part[npart]->partoutr[i]*vol; - }; - }; + REALTYPE vol = sysefxvol[nefx][npart]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += part[npart]->partoutl[i] * vol; + tmpmixr[i] += part[npart]->partoutr[i] * vol; + } + } // system effect send to next ones - for (int nefxfrom=0;nefxfromefxoutl[i]*v; - tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v; - }; - }; - }; + for(int nefxfrom = 0; nefxfrom < nefx; nefxfrom++) { + if(Psysefxsend[nefxfrom][nefx] != 0) { + REALTYPE v = sysefxsend[nefxfrom][nefx]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * v; + tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * v; + } + } + } - sysefx[nefx]->out(tmpmixl,tmpmixr); + sysefx[nefx]->out(tmpmixl, tmpmixr); //Add the System Effect to sound output - REALTYPE outvol=sysefx[nefx]->sysefxgetvolume(); - for (i=0;isysefxgetvolume(); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] += tmpmixl[i] * outvol; + outr[i] += tmpmixr[i] * outvol; + } + } //Mix all parts - for (npart=0;npartpartoutl[i]; - outr[i]+=part[npart]->partoutr[i]; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //the volume did not changed + outl[i] += part[npart]->partoutl[i]; + outr[i] += part[npart]->partoutr[i]; + } + } //Insertion effects for Master Out - for (nefx=0;nefxout(outl,outr); - }; + for(nefx = 0; nefx < NUM_INS_EFX; nefx++) + if(Pinsparts[nefx] == -2) + insefx[nefx]->out(outl, outr); + ; //Master Volume - for (i=0;ivuoutpeakl) vuoutpeakl=fabs(outl[i]); - if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]); - }; - if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1; - if (vumaxoutpeakl vuoutpeakl) + vuoutpeakl = fabs(outl[i]); + if(fabs(outr[i]) > vuoutpeakr) + vuoutpeakr = fabs(outr[i]); + } + if((vuoutpeakl > 1.0) || (vuoutpeakr > 1.0)) + vuclipped = 1; + if(vumaxoutpeakl < vuoutpeakl) + vumaxoutpeakl = vuoutpeakl; + if(vumaxoutpeakr < vuoutpeakr) + vumaxoutpeakr = vuoutpeakr; //RMS Peak computation (for vumeters) - vurmspeakl=1e-12; - vurmspeakr=1e-12; - for (i=0;iPenabled!=0) { - REALTYPE *outl=part[npart]->partoutl, - *outr=part[npart]->partoutr; - for (i=0;ivuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp; - }; - vuoutpeakpart[npart]*=volume; - } else { - if (fakepeakpart[npart]>1) fakepeakpart[npart]--; - }; - }; + for(npart = 0; npart < NUM_MIDI_PARTS; npart++) { + vuoutpeakpart[npart] = 1.0e-12; + if(part[npart]->Penabled != 0) { + REALTYPE *outl = part[npart]->partoutl, + *outr = part[npart]->partoutr; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + REALTYPE tmp = fabs(outl[i] + outr[i]); + if(tmp > vuoutpeakpart[npart]) + vuoutpeakpart[npart] = tmp; + } + vuoutpeakpart[npart] *= volume; + } + else + if(fakepeakpart[npart] > 1) + fakepeakpart[npart]--; + ; + } //Shutup if it is asked (with fade-out) - if (shutup!=0) { - for (i=0;i=SOUND_BUFFER_SIZE) { - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - } else {//Resample - int ksample=0; - REALTYPE srinc=SAMPLE_RATE/(REALTYPE)samplerate; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } + else { //Resample + int ksample = 0; + REALTYPE srinc = SAMPLE_RATE / (REALTYPE)samplerate; - while (ksample=1.0) { - ksoundbuffersample+=(int) floor(ksoundbuffersamplelow); - ksoundbuffersamplelow=ksoundbuffersamplelow-floor(ksoundbuffersamplelow); - }; + ksoundbuffersamplelow += srinc; + if(ksoundbuffersamplelow >= 1.0) { + ksoundbuffersample += (int) floor(ksoundbuffersamplelow); + ksoundbuffersamplelow = ksoundbuffersamplelow - floor( + ksoundbuffersamplelow); + } - if (ksoundbuffersample>=SOUND_BUFFER_SIZE) { - oldsamplel=audiooutl[SOUND_BUFFER_SIZE-1]; - oldsampler=audiooutr[SOUND_BUFFER_SIZE-1]; - AudioOut(&audiooutl[0],&audiooutr[0]); - ksoundbuffersample=0; - }; - }; - }; -}; + if(ksoundbuffersample >= SOUND_BUFFER_SIZE) { + oldsamplel = audiooutl[SOUND_BUFFER_SIZE - 1]; + oldsampler = audiooutr[SOUND_BUFFER_SIZE - 1]; + AudioOut(&audiooutl[0], &audiooutr[0]); + ksoundbuffersample = 0; + } + } + } +} Master::~Master() { - for (int npart=0;npartcleanup(); - fakepeakpart[npart]=0; - }; - for (int nefx=0;nefxcleanup(); - for (int nefx=0;nefxcleanup(); + fakepeakpart[npart] = 0; + } + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) + insefx[nefx]->cleanup(); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) + sysefx[nefx]->cleanup(); vuresetpeaks(); - shutup=0; -}; + shutup = 0; +} /* @@ -570,81 +615,80 @@ void Master::ShutUp() */ void Master::vuresetpeaks() { - vuoutpeakl=1e-9; - vuoutpeakr=1e-9; - vumaxoutpeakl=1e-9; - vumaxoutpeakr=1e-9; - vuclipped=0; -}; + vuoutpeakl = 1e-9; + vuoutpeakr = 1e-9; + vumaxoutpeakl = 1e-9; + vumaxoutpeakr = 1e-9; + vuclipped = 0; +} void Master::applyparameters() { - for (int npart=0;npartapplyparameters(); - }; -}; + ; +} void Master::add2XML(XMLwrapper *xml) { - xml->addpar("volume",Pvolume); - xml->addpar("key_shift",Pkeyshift); - xml->addparbool("nrpn_receive",ctl.NRPN.receive); + xml->addpar("volume", Pvolume); + xml->addpar("key_shift", Pkeyshift); + xml->addparbool("nrpn_receive", ctl.NRPN.receive); xml->beginbranch("MICROTONAL"); microtonal.add2XML(xml); xml->endbranch(); - for (int npart=0;npartbeginbranch("PART",npart); + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + xml->beginbranch("PART", npart); part[npart]->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("SYSTEM_EFFECTS"); - for (int nefx=0;nefxbeginbranch("SYSTEM_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + xml->beginbranch("SYSTEM_EFFECT", nefx); xml->beginbranch("EFFECT"); sysefx[nefx]->add2XML(xml); xml->endbranch(); - for (int pefx=0;pefxbeginbranch("VOLUME",pefx); - xml->addpar("vol",Psysefxvol[nefx][pefx]); + for(int pefx = 0; pefx < NUM_MIDI_PARTS; pefx++) { + xml->beginbranch("VOLUME", pefx); + xml->addpar("vol", Psysefxvol[nefx][pefx]); xml->endbranch(); - }; + } - for (int tonefx=nefx+1;tonefxbeginbranch("SENDTO",tonefx); - xml->addpar("send_vol",Psysefxsend[nefx][tonefx]); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + xml->beginbranch("SENDTO", tonefx); + xml->addpar("send_vol", Psysefxsend[nefx][tonefx]); xml->endbranch(); - }; + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSERTION_EFFECTS"); - for (int nefx=0;nefxbeginbranch("INSERTION_EFFECT",nefx); - xml->addpar("part",Pinsparts[nefx]); + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + xml->beginbranch("INSERTION_EFFECT", nefx); + xml->addpar("part", Pinsparts[nefx]); xml->beginbranch("EFFECT"); insefx[nefx]->add2XML(xml); xml->endbranch(); xml->endbranch(); - }; + } xml->endbranch(); - -}; +} int Master::getalldata(char **data) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); @@ -654,20 +698,21 @@ int Master::getalldata(char **data) xml->endbranch(); - *data=xml->getXMLdata(); + *data = xml->getXMLdata(); delete (xml); - return(strlen(*data)+1); -}; + return strlen(*data) + 1; +} -void Master::putalldata(char *data,int size) +void Master::putalldata(char *data, int size) { - XMLwrapper *xml=new XMLwrapper(); - if (!xml->putXMLdata(data)) { - delete(xml); + XMLwrapper *xml = new XMLwrapper(); + if(!xml->putXMLdata(data)) { + delete (xml); return; - }; + } - if (xml->enterbranch("MASTER")==0) return; + if(xml->enterbranch("MASTER") == 0) + return; pthread_mutex_lock(&mutex); getfromXML(xml); @@ -675,104 +720,109 @@ void Master::putalldata(char *data,int size) xml->exitbranch(); - delete(xml); -}; + delete (xml); +} int Master::saveXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MASTER"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Master::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("MASTER")==0) return(-10); + if(xml->enterbranch("MASTER") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Master::getfromXML(XMLwrapper *xml) { - setPvolume(xml->getpar127("volume",Pvolume)); - setPkeyshift(xml->getpar127("key_shift",Pkeyshift)); - ctl.NRPN.receive=xml->getparbool("nrpn_receive",ctl.NRPN.receive); + setPvolume(xml->getpar127("volume", Pvolume)); + setPkeyshift(xml->getpar127("key_shift", Pkeyshift)); + ctl.NRPN.receive = xml->getparbool("nrpn_receive", ctl.NRPN.receive); - part[0]->Penabled=0; - for (int npart=0;npartenterbranch("PART",npart)==0) continue; + part[0]->Penabled = 0; + for(int npart = 0; npart < NUM_MIDI_PARTS; npart++) { + if(xml->enterbranch("PART", npart) == 0) + continue; part[npart]->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("MICROTONAL")) { + if(xml->enterbranch("MICROTONAL")) { microtonal.getfromXML(xml); xml->exitbranch(); - }; + } sysefx[0]->changeeffect(0); - if (xml->enterbranch("SYSTEM_EFFECTS")) { - for (int nefx=0;nefxenterbranch("SYSTEM_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("SYSTEM_EFFECTS")) { + for(int nefx = 0; nefx < NUM_SYS_EFX; nefx++) { + if(xml->enterbranch("SYSTEM_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { sysefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - for (int partefx=0;partefxenterbranch("VOLUME",partefx)==0) continue; - setPsysefxvol(partefx,nefx,xml->getpar127("vol",Psysefxvol[partefx][nefx])); + for(int partefx = 0; partefx < NUM_MIDI_PARTS; partefx++) { + if(xml->enterbranch("VOLUME", partefx) == 0) + continue; + setPsysefxvol(partefx, nefx, + xml->getpar127("vol", Psysefxvol[partefx][nefx])); xml->exitbranch(); - }; + } - for (int tonefx=nefx+1;tonefxenterbranch("SENDTO",tonefx)==0) continue; - setPsysefxsend(nefx,tonefx,xml->getpar127("send_vol",Psysefxsend[nefx][tonefx])); + for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; tonefx++) { + if(xml->enterbranch("SENDTO", tonefx) == 0) + continue; + setPsysefxsend(nefx, tonefx, + xml->getpar127("send_vol", + Psysefxsend[nefx][tonefx])); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("INSERTION_EFFECTS")) { - for (int nefx=0;nefxenterbranch("INSERTION_EFFECT",nefx)==0) continue; - Pinsparts[nefx]=xml->getpar("part",Pinsparts[nefx],-2,NUM_MIDI_PARTS); - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("INSERTION_EFFECTS")) { + for(int nefx = 0; nefx < NUM_INS_EFX; nefx++) { + if(xml->enterbranch("INSERTION_EFFECT", nefx) == 0) + continue; + Pinsparts[nefx] = xml->getpar("part", + Pinsparts[nefx], + -2, + NUM_MIDI_PARTS); + if(xml->enterbranch("EFFECT")) { insefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - - }; + } xml->exitbranch(); - }; - - -}; - - - + } +} diff --git a/plugins/zynaddsubfx/src/Misc/Master.h b/plugins/zynaddsubfx/src/Misc/Master.h index 69f1a1ec2..eb4752245 100644 --- a/plugins/zynaddsubfx/src/Misc/Master.h +++ b/plugins/zynaddsubfx/src/Misc/Master.h @@ -40,129 +40,136 @@ extern Dump dump; * process them with system/insertion effects and mix them */ class Master { -public: - /** Constructor*/ - Master(); - /** Destructor*/ - ~Master(); + public: + /** Constructor*/ + Master(); + /** Destructor*/ + ~Master(); - /**Saves all settings to a XML file - * @return 0 for ok or <0 if there is an error*/ - int saveXML(const char *filename); + /**Saves all settings to a XML file + * @return 0 for ok or <0 if there is an error*/ + int saveXML(const char *filename); - /**This adds the parameters to the XML data*/ - void add2XML(XMLwrapper *xml); + /**This adds the parameters to the XML data*/ + void add2XML(XMLwrapper *xml); - void defaults(); + void defaults(); - /**loads all settings from a XML file - * @return 0 for ok or -1 if there is an error*/ - int loadXML(const char *filename); - void applyparameters(); + /**loads all settings from a XML file + * @return 0 for ok or -1 if there is an error*/ + int loadXML(const char *filename); + void applyparameters(); - void getfromXML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - /**get all data to a newly allocated array (used for VST) - * @return the datasize*/ - int getalldata(char **data); - /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ - void putalldata(char *data,int size); + /**get all data to a newly allocated array (used for VST) + * @return the datasize*/ + int getalldata(char **data); + /**put all data from the *data array to zynaddsubfx parameters (used for VST)*/ + void putalldata(char *data, int size); - //Midi IN - void NoteOn(unsigned char chan,unsigned char note,unsigned char velocity); - void NoteOff(unsigned char chan,unsigned char note); - void SetController(unsigned char chan,unsigned int type,int par); - //void NRPN... + //Midi IN + void NoteOn(unsigned char chan, + unsigned char note, + unsigned char velocity); + void NoteOff(unsigned char chan, unsigned char note); + void SetController(unsigned char chan, unsigned int type, int par); + //void NRPN... - void ShutUp(); - int shutup; + void ShutUp(); + int shutup; - /**Audio Output*/ - void AudioOut(REALTYPE *outl,REALTYPE *outr); - /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ - void GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr); + /**Audio Output*/ + void AudioOut(REALTYPE *outl, REALTYPE *outr); + /**Audio Output (for callback mode). This allows the program to be controled by an external program*/ + void GetAudioOutSamples(int nsamples, + int samplerate, + REALTYPE *outl, + REALTYPE *outr); - void partonoff(int npart,int what); + void partonoff(int npart, int what); - /**parts \todo see if this can be made to be dynamic*/ - Part *part[NUM_MIDI_PARTS]; + /**parts \todo see if this can be made to be dynamic*/ + Part *part[NUM_MIDI_PARTS]; - //parameters - unsigned char Pvolume; - unsigned char Pkeyshift; - unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + //parameters + unsigned char Pvolume; + unsigned char Pkeyshift; + unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //parameters control - void setPvolume(char Pvolume_); - void setPkeyshift(char Pkeyshift_); - void setPsysefxvol(int Ppart,int Pefx,char Pvol); - void setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol); + //parameters control + void setPvolume(char Pvolume_); + void setPkeyshift(char Pkeyshift_); + void setPsysefxvol(int Ppart, int Pefx, char Pvol); + void setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol); - //effects - EffectMgr *sysefx[NUM_SYS_EFX];//system - EffectMgr *insefx[NUM_INS_EFX];//insertion + //effects + EffectMgr *sysefx[NUM_SYS_EFX]; //system + EffectMgr *insefx[NUM_INS_EFX]; //insertion // void swapcopyeffects(int what,int type,int neff1,int neff2); - //HDD recorder - Recorder HDDRecorder; + //HDD recorder + Recorder HDDRecorder; - //part that's apply the insertion effect; -1 to disable - short int Pinsparts[NUM_INS_EFX]; + //part that's apply the insertion effect; -1 to disable + short int Pinsparts[NUM_INS_EFX]; - //peaks for VU-meter - void vuresetpeaks(); - REALTYPE vuoutpeakl,vuoutpeakr,vumaxoutpeakl,vumaxoutpeakr,vurmspeakl,vurmspeakr; - int vuclipped; + //peaks for VU-meter + void vuresetpeaks(); + REALTYPE vuoutpeakl, vuoutpeakr, vumaxoutpeakl, vumaxoutpeakr, + vurmspeakl, vurmspeakr; + int vuclipped; - //peaks for part VU-meters - REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; - unsigned char fakepeakpart[NUM_MIDI_PARTS];//this is used to compute the "peak" when the part is disabled + //peaks for part VU-meters + REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; + unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled - Controller ctl; - int swaplr;//1 if L and R are swapped + Controller ctl; + int swaplr; //1 if L and R are swapped - //Sequencer - Sequencer seq; + //Sequencer + Sequencer seq; - //other objects - Microtonal microtonal; - Bank bank; + //other objects + Microtonal microtonal; + Bank bank; - FFTwrapper *fft; - pthread_mutex_t mutex; + FFTwrapper *fft; + pthread_mutex_t mutex; -private: - REALTYPE volume; - REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; - REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + private: + REALTYPE volume; + REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; - //Temporary mixing samples for part samples which is sent to system effect - REALTYPE *tmpmixl; - REALTYPE *tmpmixr; + //Temporary mixing samples for part samples which is sent to system effect + REALTYPE *tmpmixl; + REALTYPE *tmpmixr; - int keyshift; + int keyshift; - //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) - REALTYPE *audiooutl; - REALTYPE *audiooutr; + //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) + REALTYPE *audiooutl; + REALTYPE *audiooutr; - int ksoundbuffersample;//this is used to know if there is need to call AudioOut by GetAudioOutSamples method - REALTYPE ksoundbuffersamplelow;//this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) - REALTYPE oldsamplel,oldsampler;//this is used for resampling - - //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) - //and are called by internal parts of the program (like sequencer) - void noteon(unsigned char chan,unsigned char note,unsigned char velocity); - void noteoff(unsigned char chan,unsigned char note); - void setcontroller(unsigned char chan,unsigned int type,int par); + int ksoundbuffersample; //this is used to know if there is need to call AudioOut by GetAudioOutSamples method + REALTYPE ksoundbuffersamplelow; //this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) + REALTYPE oldsamplel, oldsampler; //this is used for resampling + //These are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) + //and are called by internal parts of the program (like sequencer) + void noteon(unsigned char chan, + unsigned char note, + unsigned char velocity); + void noteoff(unsigned char chan, unsigned char note); + void setcontroller(unsigned char chan, unsigned int type, int par); }; diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp index b389059c8..e84ee8e64 100644 --- a/plugins/zynaddsubfx/src/Misc/Microtonal.cpp +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.cpp @@ -28,158 +28,190 @@ Microtonal::Microtonal() { - Pname=new unsigned char[MICROTONAL_MAX_NAME_LEN]; - Pcomment=new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pname = new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pcomment = new unsigned char[MICROTONAL_MAX_NAME_LEN]; defaults(); -}; +} void Microtonal::defaults() { - Pinvertupdown=0; - Pinvertupdowncenter=60; - octavesize=12; - Penabled=0; - PAnote=69; - PAfreq=440.0; - Pscaleshift=64; + Pinvertupdown = 0; + Pinvertupdowncenter = 60; + octavesize = 12; + Penabled = 0; + PAnote = 69; + PAfreq = 440.0; + Pscaleshift = 64; - Pfirstkey=0; - Plastkey=127; - Pmiddlenote=60; - Pmapsize=12; - Pmappingenabled=0; + Pfirstkey = 0; + Plastkey = 127; + Pmiddlenote = 60; + Pmapsize = 12; + Pmappingenabled = 0; - for (int i=0;i<128;i++) Pmapping[i]=i; + for(int i = 0; i < 128; i++) + Pmapping[i] = i; - for (int i=0;iPlastkey)) return (-1.0); + if(Pmappingenabled != 0) { + if((note < Pfirstkey) || (note > Plastkey)) + return -1.0; //Compute how many mapped keys are from middle note to reference note //and find out the proportion between the freq. of middle note and "A" note - int tmp=PAnote-Pmiddlenote,minus=0; - if (tmp<0) { - tmp=-tmp; - minus=1; - }; - int deltanote=0; - for (int i=0;i=0) deltanote++; - REALTYPE rap_anote_middlenote=(deltanote==0) ? (1.0) : (octave[(deltanote-1)%octavesize].tuning); - if (deltanote!=0) rap_anote_middlenote*=pow(octave[octavesize-1].tuning,(deltanote-1)/octavesize); - if (minus!=0) rap_anote_middlenote=1.0/rap_anote_middlenote; + int tmp = PAnote - Pmiddlenote, minus = 0; + if(tmp < 0) { + tmp = -tmp; + minus = 1; + } + int deltanote = 0; + for(int i = 0; i < tmp; i++) + if(Pmapping[i % Pmapsize] >= 0) + deltanote++; + REALTYPE rap_anote_middlenote = + (deltanote == + 0) ? (1.0) : (octave[(deltanote - 1) % octavesize].tuning); + if(deltanote != 0) + rap_anote_middlenote *= + pow(octave[octavesize - 1].tuning, (deltanote - 1) / octavesize); + if(minus != 0) + rap_anote_middlenote = 1.0 / rap_anote_middlenote; //Convert from note (midi) to degree (note from the tunning) - int degoct=(note-(int)Pmiddlenote+(int) Pmapsize*200)/(int)Pmapsize-200; - int degkey=(note-Pmiddlenote+(int)Pmapsize*100)%Pmapsize; - degkey=Pmapping[degkey]; - if (degkey<0) return(-1.0);//this key is not mapped + int degoct = + (note - (int)Pmiddlenote + (int) Pmapsize + * 200) / (int)Pmapsize - 200; + int degkey = (note - Pmiddlenote + (int)Pmapsize * 100) % Pmapsize; + degkey = Pmapping[degkey]; + if(degkey < 0) + return -1.0; //this key is not mapped //invert the keyboard upside-down if it is asked for //TODO: do the right way by using Pinvertupdowncenter - if (Pinvertupdown!=0) { - degkey=octavesize-degkey-1; - degoct=-degoct; - }; + if(Pinvertupdown != 0) { + degkey = octavesize - degkey - 1; + degoct = -degoct; + } //compute the frequency of the note - degkey=degkey+scaleshift; - degoct+=degkey/octavesize; - degkey%=octavesize; + degkey = degkey + scaleshift; + degoct += degkey / octavesize; + degkey %= octavesize; - REALTYPE freq=(degkey==0) ? (1.0):octave[degkey-1].tuning; - freq*=pow(octave[octavesize-1].tuning,degoct); - freq*=PAfreq/rap_anote_middlenote; - freq*=globalfinedetunerap; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; - return(freq*rap_keyshift); - } else {//if the mapping is disabled - int nt=note-PAnote+scaleshift; - int ntkey=(nt+(int)octavesize*100)%octavesize; - int ntoct=(nt-ntkey)/octavesize; + REALTYPE freq = (degkey == 0) ? (1.0) : octave[degkey - 1].tuning; + freq *= pow(octave[octavesize - 1].tuning, degoct); + freq *= PAfreq / rap_anote_middlenote; + freq *= globalfinedetunerap; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; + return freq * rap_keyshift; + } + else { //if the mapping is disabled + int nt = note - PAnote + scaleshift; + int ntkey = (nt + (int)octavesize * 100) % octavesize; + int ntoct = (nt - ntkey) / octavesize; - REALTYPE oct=octave[octavesize-1].tuning; - REALTYPE freq=octave[(ntkey+octavesize-1)%octavesize].tuning*pow(oct,ntoct)*PAfreq; - if (ntkey==0) freq/=oct; - if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; + REALTYPE oct = octave[octavesize - 1].tuning; + REALTYPE freq = + octave[(ntkey + octavesize - 1) % octavesize].tuning *pow(oct, + ntoct) + * PAfreq; + if(ntkey == 0) + freq /= oct; + if(scaleshift != 0) + freq /= octave[scaleshift - 1].tuning; // fprintf(stderr,"note=%d freq=%.3f cents=%d\n",note,freq,(int)floor(log(freq/PAfreq)/log(2.0)*1200.0+0.5)); - freq*=globalfinedetunerap; - return(freq*rap_keyshift); - }; -}; + freq *= globalfinedetunerap; + return freq * rap_keyshift; + } +} bool Microtonal::operator==(const Microtonal µ) const { - return(!(*this!=micro)); + return !(*this != micro); } bool Microtonal::operator!=(const Microtonal µ) const { - //A simple macro to test equality MiCRotonal EQuals (not the perfect //approach, but good enough) -#define MCREQ( x ) if(x!=micro.x)return true; +#define MCREQ(x) if(x != micro.x) \ + return true; //for floats -#define FMCREQ( x ) if(!((xmicro.x-0.0001)))return true; +#define FMCREQ(x) if(!((x < micro.x + 0.0001) && (x > micro.x - 0.0001))) \ + return true; MCREQ(Pinvertupdown); MCREQ(Pinvertupdowncenter); @@ -195,18 +227,18 @@ bool Microtonal::operator!=(const Microtonal µ) const MCREQ(Pmapsize); MCREQ(Pmappingenabled); - for (int i=0;i<128;i++) + for(int i = 0; i < 128; i++) MCREQ(Pmapping[i]); - for (int i=0;iPname,(const char *)micro.Pname)) + if(strcmp((const char *)this->Pname, (const char *)micro.Pname)) return true; - if(strcmp((const char *)this->Pcomment,(const char *)micro.Pcomment)) + if(strcmp((const char *)this->Pcomment, (const char *)micro.Pcomment)) return true; MCREQ(Pglobalfinedetune); return false; @@ -214,384 +246,442 @@ bool Microtonal::operator!=(const Microtonal µ) const //undefine macros, as they are no longer needed #undef MCREQ #undef FMCREQ - } /* * Convert a line to tunings; returns -1 if it ok */ -int Microtonal::linetotunings(unsigned int nline,const char *line) +int Microtonal::linetotunings(unsigned int nline, const char *line) { - int x1=-1,x2=-1,type=-1; - REALTYPE x=-1.0,tmp,tuning=1.0; - if (strstr(line,"/")==NULL) { - if (strstr(line,".")==NULL) {// M case (M=M/1) - sscanf(line,"%d",&x1); - x2=1; - type=2;//division - } else {// float number case - sscanf(line,"%f",&x); - if (x<0.000001) return(1); - type=1;//float type(cents) - }; - } else {// M/N case - sscanf(line,"%d/%d",&x1,&x2); - if ((x1<0)||(x2<0)) return(1); - if (x2==0) x2=1; - type=2;//division - }; + int x1 = -1, x2 = -1, type = -1; + REALTYPE x = -1.0, tmp, tuning = 1.0; + if(strstr(line, "/") == NULL) { + if(strstr(line, ".") == NULL) { // M case (M=M/1) + sscanf(line, "%d", &x1); + x2 = 1; + type = 2; //division + } + else { // float number case + sscanf(line, "%f", &x); + if(x < 0.000001) + return 1; + type = 1; //float type(cents) + } + } + else { // M/N case + sscanf(line, "%d/%d", &x1, &x2); + if((x1 < 0) || (x2 < 0)) + return 1; + if(x2 == 0) + x2 = 1; + type = 2; //division + } - if (x1<=0) x1=1;//not allow zero frequency sounds (consider 0 as 1) + if(x1 <= 0) + x1 = 1; //not allow zero frequency sounds (consider 0 as 1) //convert to float if the number are too big - if ((type==2)&&((x1>(128*128*128-1))||(x2>(128*128*128-1)))) { - type=1; - x=((REALTYPE) x1)/x2; - }; - switch (type) { + if((type == 2) + && ((x1 > (128 * 128 * 128 - 1)) || (x2 > (128 * 128 * 128 - 1)))) { + type = 1; + x = ((REALTYPE) x1) / x2; + } + switch(type) { case 1: - x1=(int) floor(x); - tmp=fmod(x,1.0); - x2=(int) (floor (tmp*1e6)); - tuning=pow(2.0,x/1200.0); + x1 = (int) floor(x); + tmp = fmod(x, 1.0); + x2 = (int) (floor(tmp * 1e6)); + tuning = pow(2.0, x / 1200.0); break; case 2: - x=((REALTYPE)x1)/x2; - tuning=x; + x = ((REALTYPE)x1) / x2; + tuning = x; break; - }; + } - tmpoctave[nline].tuning=tuning; - tmpoctave[nline].type=type; - tmpoctave[nline].x1=x1; - tmpoctave[nline].x2=x2; + tmpoctave[nline].tuning = tuning; + tmpoctave[nline].type = type; + tmpoctave[nline].x1 = x1; + tmpoctave[nline].x2 = x2; - return(-1);//ok -}; + return -1; //ok +} /* * Convert the text to tunnings */ int Microtonal::texttotunings(const char *text) { - unsigned int i,k=0,nl=0; + unsigned int i, k = 0, nl = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - while (kMAX_OCTAVE_SIZE) nl=MAX_OCTAVE_SIZE; - if (nl==0) return(-2);//the input is empty - octavesize=nl; - for (i=0;i MAX_OCTAVE_SIZE) + nl = MAX_OCTAVE_SIZE; + if(nl == 0) + return -2; //the input is empty + octavesize = nl; + for(i = 0; i < octavesize; i++) { + octave[i].tuning = tmpoctave[i].tuning; + octave[i].type = tmpoctave[i].type; + octave[i].x1 = tmpoctave[i].x1; + octave[i].x2 = tmpoctave[i].x2; + } + return -1; //ok +} /* * Convert the text to mapping */ void Microtonal::texttomapping(const char *text) { - unsigned int i,k=0; + unsigned int i, k = 0; char *lin; - lin=new char[MAX_LINE_SIZE+1]; - for (i=0;i<128;i++) Pmapping[i]=-1; - int tx=0; - while (k127) break; - }; + if((tx++) > 127) + break; + } delete [] lin; - if (tx==0) tx=1; - Pmapsize=tx; -}; + if(tx == 0) + tx = 1; + Pmapsize = tx; +} /* * Convert tunning to text line */ -void Microtonal::tuningtoline(int n,char *line,int maxn) +void Microtonal::tuningtoline(int n, char *line, int maxn) { - if ((n>octavesize) || (n>MAX_OCTAVE_SIZE)) { - line[0]='\0'; + if((n > octavesize) || (n > MAX_OCTAVE_SIZE)) { + line[0] = '\0'; return; - }; - if (octave[n].type==1) snprintf(line,maxn,"%d.%d",octave[n].x1,octave[n].x2); - if (octave[n].type==2) snprintf(line,maxn,"%d/%d",octave[n].x1,octave[n].x2); -}; + } + if(octave[n].type == 1) + snprintf(line, maxn, "%d.%d", octave[n].x1, octave[n].x2); + if(octave[n].type == 2) + snprintf(line, maxn, "%d/%d", octave[n].x1, octave[n].x2); +} -int Microtonal::loadline(FILE *file,char *line) +int Microtonal::loadline(FILE *file, char *line) { do { - if (fgets(line,500,file)==0) return(1); - } while (line[0]=='!'); - return(0); -}; + if(fgets(line, 500, file) == 0) + return 1; + } while(line[0] == '!'); + return 0; +} /* * Loads the tunnings from a scl file */ int Microtonal::loadscl(const char *filename) { - FILE *file=fopen(filename, "r"); - char tmp[500]; - fseek(file,0,SEEK_SET); + FILE *file = fopen(filename, "r"); + char tmp[500]; + fseek(file, 0, SEEK_SET); //loads the short description - if (loadline(file,&tmp[0])!=0) return(2); - for (int i=0;i<500;i++) if (tmp[i]<32) tmp[i]=0; - snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"%s",tmp); - snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",tmp); + if(loadline(file, &tmp[0]) != 0) + return 2; + for(int i = 0; i < 500; i++) + if(tmp[i] < 32) + tmp[i] = 0; + snprintf((char *) Pname, MICROTONAL_MAX_NAME_LEN, "%s", tmp); + snprintf((char *) Pcomment, MICROTONAL_MAX_NAME_LEN, "%s", tmp); //loads the number of the notes - if (loadline(file,&tmp[0])!=0) return(2); - int nnotes=MAX_OCTAVE_SIZE; - sscanf(&tmp[0],"%d",&nnotes); - if (nnotes>MAX_OCTAVE_SIZE) return (2); + if(loadline(file, &tmp[0]) != 0) + return 2; + int nnotes = MAX_OCTAVE_SIZE; + sscanf(&tmp[0], "%d", &nnotes); + if(nnotes > MAX_OCTAVE_SIZE) + return 2; //load the tunnings - for (int nline=0;nline127) x=127;//just in case... - Pmapsize=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmapsize = x; //loads first MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pfirstkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pfirstkey = x; //loads last MIDI note to retune - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Plastkey=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Plastkey = x; //loads last the middle note where scale fro scale degree=0 - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - Pmiddlenote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + Pmiddlenote = x; //loads the reference note - if (loadline(file,&tmp[0])!=0) return(2); - if (sscanf(&tmp[0],"%d",&x)==0) return(2); - if (x<1) x=0; - if (x>127) x=127;//just in case... - PAnote=x; + if(loadline(file, &tmp[0]) != 0) + return 2; + if(sscanf(&tmp[0], "%d", &x) == 0) + return 2; + if(x < 1) + x = 0; + if(x > 127) + x = 127; //just in case... + PAnote = x; //loads the reference freq. - if (loadline(file,&tmp[0])!=0) return(2); - REALTYPE tmpPAfreq=440.0; - if (sscanf(&tmp[0],"%f",&tmpPAfreq)==0) return(2); - PAfreq=tmpPAfreq; + if(loadline(file, &tmp[0]) != 0) + return 2; + REALTYPE tmpPAfreq = 440.0; + if(sscanf(&tmp[0], "%f", &tmpPAfreq) == 0) + return 2; + PAfreq = tmpPAfreq; //the scale degree(which is the octave) is not loaded, it is obtained by the tunnings with getoctavesize() method - if (loadline(file,&tmp[0])!=0) return(2); + if(loadline(file, &tmp[0]) != 0) + return 2; //load the mappings - if (Pmapsize!=0) { - for (int nline=0;nlineaddparstr("name",(char *) Pname); - xml->addparstr("comment",(char *) Pcomment); + xml->addparstr("name", (char *) Pname); + xml->addparstr("comment", (char *) Pcomment); - xml->addparbool("invert_up_down",Pinvertupdown); - xml->addpar("invert_up_down_center",Pinvertupdowncenter); + xml->addparbool("invert_up_down", Pinvertupdown); + xml->addpar("invert_up_down_center", Pinvertupdowncenter); - xml->addparbool("enabled",Penabled); - xml->addpar("global_fine_detune",Pglobalfinedetune); + xml->addparbool("enabled", Penabled); + xml->addpar("global_fine_detune", Pglobalfinedetune); - xml->addpar("a_note",PAnote); - xml->addparreal("a_freq",PAfreq); + xml->addpar("a_note", PAnote); + xml->addparreal("a_freq", PAfreq); - if ((Penabled==0)&&(xml->minimal)) return; + if((Penabled == 0) && (xml->minimal)) + return; xml->beginbranch("SCALE"); - xml->addpar("scale_shift",Pscaleshift); - xml->addpar("first_key",Pfirstkey); - xml->addpar("last_key",Plastkey); - xml->addpar("middle_note",Pmiddlenote); + xml->addpar("scale_shift", Pscaleshift); + xml->addpar("first_key", Pfirstkey); + xml->addpar("last_key", Plastkey); + xml->addpar("middle_note", Pmiddlenote); xml->beginbranch("OCTAVE"); - xml->addpar("octave_size",octavesize); - for (int i=0;ibeginbranch("DEGREE",i); - if (octave[i].type==1) { - xml->addparreal("cents",octave[i].tuning); - }; - if (octave[i].type==2) { - xml->addpar("numerator",octave[i].x1); - xml->addpar("denominator",octave[i].x2); - }; + xml->addpar("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + xml->beginbranch("DEGREE", i); + if(octave[i].type == 1) + xml->addparreal("cents", octave[i].tuning); + ; + if(octave[i].type == 2) { + xml->addpar("numerator", octave[i].x1); + xml->addpar("denominator", octave[i].x2); + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("KEYBOARD_MAPPING"); - xml->addpar("map_size",Pmapsize); - xml->addpar("mapping_enabled",Pmappingenabled); - for (int i=0;ibeginbranch("KEYMAP",i); - xml->addpar("degree",Pmapping[i]); + xml->addpar("map_size", Pmapsize); + xml->addpar("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + xml->beginbranch("KEYMAP", i); + xml->addpar("degree", Pmapping[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->endbranch(); -}; +} void Microtonal::getfromXML(XMLwrapper *xml) { - xml->getparstr("name",(char *) Pname,MICROTONAL_MAX_NAME_LEN); - xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN); + xml->getparstr("name", (char *) Pname, MICROTONAL_MAX_NAME_LEN); + xml->getparstr("comment", (char *) Pcomment, MICROTONAL_MAX_NAME_LEN); - Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); - Pinvertupdowncenter=xml->getpar127("invert_up_down_center",Pinvertupdowncenter); + Pinvertupdown = xml->getparbool("invert_up_down", Pinvertupdown); + Pinvertupdowncenter = xml->getpar127("invert_up_down_center", + Pinvertupdowncenter); - Penabled=xml->getparbool("enabled",Penabled); - Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune); + Penabled = xml->getparbool("enabled", Penabled); + Pglobalfinedetune = xml->getpar127("global_fine_detune", Pglobalfinedetune); - PAnote=xml->getpar127("a_note",PAnote); - PAfreq=xml->getparreal("a_freq",PAfreq,1.0,10000.0); + PAnote = xml->getpar127("a_note", PAnote); + PAfreq = xml->getparreal("a_freq", PAfreq, 1.0, 10000.0); - if (xml->enterbranch("SCALE")) { - Pscaleshift=xml->getpar127("scale_shift",Pscaleshift); - Pfirstkey=xml->getpar127("first_key",Pfirstkey); - Plastkey=xml->getpar127("last_key",Plastkey); - Pmiddlenote=xml->getpar127("middle_note",Pmiddlenote); + if(xml->enterbranch("SCALE")) { + Pscaleshift = xml->getpar127("scale_shift", Pscaleshift); + Pfirstkey = xml->getpar127("first_key", Pfirstkey); + Plastkey = xml->getpar127("last_key", Plastkey); + Pmiddlenote = xml->getpar127("middle_note", Pmiddlenote); - if (xml->enterbranch("OCTAVE")) { - octavesize=xml->getpar127("octave_size",octavesize); - for (int i=0;ienterbranch("DEGREE",i)==0) continue; - octave[i].x2=0; - octave[i].tuning=xml->getparreal("cents",octave[i].tuning); - octave[i].x1=xml->getpar127("numerator",octave[i].x1); - octave[i].x2=xml->getpar127("denominator",octave[i].x2); + if(xml->enterbranch("OCTAVE")) { + octavesize = xml->getpar127("octave_size", octavesize); + for(int i = 0; i < octavesize; i++) { + if(xml->enterbranch("DEGREE", i) == 0) + continue; + octave[i].x2 = 0; + octave[i].tuning = xml->getparreal("cents", octave[i].tuning); + octave[i].x1 = xml->getpar127("numerator", octave[i].x1); + octave[i].x2 = xml->getpar127("denominator", octave[i].x2); - if (octave[i].x2!=0) octave[i].type=2; - else octave[i].type=1; + if(octave[i].x2 != 0) + octave[i].type = 2; + else + octave[i].type = 1; xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("KEYBOARD_MAPPING")) { - Pmapsize=xml->getpar127("map_size",Pmapsize); - Pmappingenabled=xml->getpar127("mapping_enabled",Pmappingenabled); - for (int i=0;ienterbranch("KEYMAP",i)==0) continue; - Pmapping[i]=xml->getpar127("degree",Pmapping[i]); + if(xml->enterbranch("KEYBOARD_MAPPING")) { + Pmapsize = xml->getpar127("map_size", Pmapsize); + Pmappingenabled = xml->getpar127("mapping_enabled", Pmappingenabled); + for(int i = 0; i < Pmapsize; i++) { + if(xml->enterbranch("KEYMAP", i) == 0) + continue; + Pmapping[i] = xml->getpar127("degree", Pmapping[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; + } +} -int Microtonal::saveXML(const char *filename)const +int Microtonal::saveXML(const char *filename) const { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); xml->beginbranch("MICROTONAL"); add2XML(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Microtonal::loadXML(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("MICROTONAL")==0) return(-10); + if(xml->enterbranch("MICROTONAL") == 0) + return -10; getfromXML(xml); xml->exitbranch(); - delete(xml); - return(0); -}; - + delete (xml); + return 0; +} diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.h b/plugins/zynaddsubfx/src/Misc/Microtonal.h index 99d73a24d..c7fd7c200 100644 --- a/plugins/zynaddsubfx/src/Misc/Microtonal.h +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.h @@ -35,102 +35,100 @@ /**Tuning settings and microtonal capabilities*/ class Microtonal { -public: - /**Constructor*/ - Microtonal(); - /**Destructor*/ - ~Microtonal(); - void defaults(); - /**Calculates the frequency for a given note - */ - REALTYPE getnotefreq(int note,int keyshift) const; + public: + /**Constructor*/ + Microtonal(); + /**Destructor*/ + ~Microtonal(); + void defaults(); + /**Calculates the frequency for a given note + */ + REALTYPE getnotefreq(int note, int keyshift) const; - //Parameters - /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ - unsigned char Pinvertupdown; + //Parameters + /**if the keys are inversed (the pitch is lower to keys from the right direction)*/ + unsigned char Pinvertupdown; - /**the central key of the inversion*/ - unsigned char Pinvertupdowncenter; + /**the central key of the inversion*/ + unsigned char Pinvertupdowncenter; - /**0 for 12 key temperate scale, 1 for microtonal*/ - unsigned char Penabled; + /**0 for 12 key temperate scale, 1 for microtonal*/ + unsigned char Penabled; - /**the note of "A" key*/ - unsigned char PAnote; + /**the note of "A" key*/ + unsigned char PAnote; - /**the frequency of the "A" note*/ - REALTYPE PAfreq; + /**the frequency of the "A" note*/ + REALTYPE PAfreq; - /**if the scale is "tuned" to a note, you can tune to other note*/ - unsigned char Pscaleshift; + /**if the scale is "tuned" to a note, you can tune to other note*/ + unsigned char Pscaleshift; - //first and last key (to retune) - unsigned char Pfirstkey; - unsigned char Plastkey; + //first and last key (to retune) + unsigned char Pfirstkey; + unsigned char Plastkey; - /**The middle note where scale degree 0 is mapped to*/ - unsigned char Pmiddlenote; + /**The middle note where scale degree 0 is mapped to*/ + unsigned char Pmiddlenote; - /**Map size*/ - unsigned char Pmapsize; + /**Map size*/ + unsigned char Pmapsize; - /**Mapping ON/OFF*/ - unsigned char Pmappingenabled; - /**Mapping (keys)*/ - short int Pmapping[128]; + /**Mapping ON/OFF*/ + unsigned char Pmappingenabled; + /**Mapping (keys)*/ + short int Pmapping[128]; - /**Fine detune to be applied to all notes*/ - unsigned char Pglobalfinedetune; + /**Fine detune to be applied to all notes*/ + unsigned char Pglobalfinedetune; - // Functions - /** Return the current octave size*/ - unsigned char getoctavesize() const; - /**Convert tunning to string*/ - void tuningtoline(int n,char *line,int maxn); - /**load the tunnings from a .scl file*/ - int loadscl(const char *filename); - /**load the mapping from .kbm file*/ - int loadkbm(const char *filename); - /**Load text into the internal tunings - * - *\todo better description*/ - int texttotunings(const char *text); - /**Load text into the internal mappings - * - *\todo better description*/ - void texttomapping(const char *text); + // Functions + /** Return the current octave size*/ + unsigned char getoctavesize() const; + /**Convert tunning to string*/ + void tuningtoline(int n, char *line, int maxn); + /**load the tunnings from a .scl file*/ + int loadscl(const char *filename); + /**load the mapping from .kbm file*/ + int loadkbm(const char *filename); + /**Load text into the internal tunings + * + *\todo better description*/ + int texttotunings(const char *text); + /**Load text into the internal mappings + * + *\todo better description*/ + void texttomapping(const char *text); - /**Name of Microtonal tuning*/ - unsigned char *Pname; - /**Comment about the tuning*/ - unsigned char *Pcomment; + /**Name of Microtonal tuning*/ + unsigned char *Pname; + /**Comment about the tuning*/ + unsigned char *Pcomment; - void add2XML(XMLwrapper *xml)const; - void getfromXML(XMLwrapper *xml); - int saveXML(const char *filename)const; - int loadXML(const char *filename); + void add2XML(XMLwrapper *xml) const; + void getfromXML(XMLwrapper *xml); + int saveXML(const char *filename) const; + int loadXML(const char *filename); - //simple operators primarily for debug - bool operator==(const Microtonal µ) const; - bool operator!=(const Microtonal µ) const; + //simple operators primarily for debug + bool operator==(const Microtonal µ) const; + bool operator!=(const Microtonal µ) const; -private: - int linetotunings(unsigned int nline,const char *line); - int loadline(FILE *file,char *line);//loads a line from the text file, while ignoring the lines beggining with "!" - unsigned char octavesize; - struct { - unsigned char type;//1 for cents or 2 for division + private: + int linetotunings(unsigned int nline, const char *line); + int loadline(FILE *file, char *line); //loads a line from the text file, while ignoring the lines beggining with "!" + unsigned char octavesize; + struct { + unsigned char type; //1 for cents or 2 for division - // the real tuning (eg. +1.05946 for one halftone) - // or 2.0 for one octave - REALTYPE tuning; - - //the real tunning is x1/x2 - unsigned int x1,x2; - - } octave[MAX_OCTAVE_SIZE],tmpoctave[MAX_OCTAVE_SIZE]; + // the real tuning (eg. +1.05946 for one halftone) + // or 2.0 for one octave + REALTYPE tuning; + //the real tunning is x1/x2 + unsigned int x1, x2; + } octave[MAX_OCTAVE_SIZE], tmpoctave[MAX_OCTAVE_SIZE]; }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Part.cpp b/plugins/zynaddsubfx/src/Misc/Part.cpp index 2adf152d7..2f8dfe7ba 100644 --- a/plugins/zynaddsubfx/src/Misc/Part.cpp +++ b/plugins/zynaddsubfx/src/Misc/Part.cpp @@ -26,122 +26,122 @@ #include #include -Part::Part(Microtonal *microtonal_,FFTwrapper *fft_, pthread_mutex_t *mutex_) +Part::Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_) { - microtonal=microtonal_; - fft=fft_; - mutex=mutex_; - partoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - partoutr=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - tmpoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + microtonal = microtonal_; + fft = fft_; + mutex = mutex_; + partoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + partoutr = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutr = new REALTYPE [SOUND_BUFFER_SIZE]; - for (int n=0;ndefaults(); kit[0].subpars->defaults(); kit[0].padpars->defaults(); - for (int nefx=0;nefxdefaults(); - Pefxroute[nefx]=0;//route to next effect - }; - -}; + Pefxroute[nefx] = 0; //route to next effect + } +} @@ -150,321 +150,515 @@ void Part::defaultsinstrument() */ void Part::cleanup() { - for (int k=0;kcleanup(); - for (int n=0;ncleanup(); + for(int n = 0; n < NUM_PART_EFX + 1; n++) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[n][i] = denormalkillbuf[i]; + partfxinputr[n][i] = denormalkillbuf[i]; + } + } +} Part::~Part() { cleanup(); - for (int n=0;nPmaxkey)) return; + if(Pnoteon == 0) + return; + if((note < Pminkey) || (note > Pmaxkey)) + return; // MonoMem stuff: - if (Ppolymode==0) { // If Poly is off + if(Ppolymode == 0) { // If Poly is off monomemnotes.push_back(note); // Add note to the list. - monomem[note].velocity=velocity; // Store this note's velocity. - monomem[note].mkeyshift=masterkeyshift; /* Store masterkeyshift too, - I'm not sure why though... */ - if ((partnote[lastpos].status!=KEY_PLAYING) - && (partnote[lastpos].status!=KEY_RELASED_AND_SUSTAINED)) { - ismonofirstnote=true; // No other keys are held or sustained. + monomem[note].velocity = velocity; // Store this note's velocity. + monomem[note].mkeyshift = masterkeyshift; /* Store masterkeyshift too, + I'm not sure why though... */ + if((partnote[lastpos].status != KEY_PLAYING) + && (partnote[lastpos].status != KEY_RELASED_AND_SUSTAINED)) + ismonofirstnote = true; // No other keys are held or sustained. + } + else + // Poly mode is On so just make sure the list is empty. + if(not monomemnotes.empty()) + monomemnotes.clear(); + + lastnote = note; + + pos = -1; + for(i = 0; i < POLIPHONY; i++) { + if(partnote[i].status == KEY_OFF) { + pos = i; + break; } - } else { - // Poly mode is On so just make sure the list is empty. - if (not monomemnotes.empty()) monomemnotes.clear(); } - lastnote=note; - - pos=-1; - for (i=0;i POLIPHONY) - (Part.C::NoteOn(..))\n"); - } else { - + fprintf(stderr, + "%s", + "NOTES TOO MANY (> POLIPHONY) - (Part.C::NoteOn(..))\n"); + else { //start the note - partnote[pos].status=KEY_PLAYING; - partnote[pos].note=note; - if (legatomodevalid) { - partnote[posb].status=KEY_PLAYING; - partnote[posb].note=note; + partnote[pos].status = KEY_PLAYING; + partnote[pos].note = note; + if(legatomodevalid) { + partnote[posb].status = KEY_PLAYING; + partnote[posb].note = note; } //this computes the velocity sensing of the part - REALTYPE vel=VelF(velocity/127.0,Pvelsns); + REALTYPE vel = VelF(velocity / 127.0, Pvelsns); //compute the velocity offset - vel+=(Pveloffs-64.0)/64.0; - if (vel<0.0) vel=0.0; - else if (vel>1.0) vel=1.0; + vel += (Pveloffs - 64.0) / 64.0; + if(vel < 0.0) + vel = 0.0; + else + if(vel > 1.0) + vel = 1.0; //compute the keyshift - int partkeyshift=(int)Pkeyshift-64; - int keyshift=masterkeyshift+partkeyshift; + int partkeyshift = (int)Pkeyshift - 64; + int keyshift = masterkeyshift + partkeyshift; //initialise note frequency REALTYPE notebasefreq; - if (Pdrummode==0) { - notebasefreq=microtonal->getnotefreq(note,keyshift); - if (notebasefreq<0.0) return;//the key is no mapped - } else { - notebasefreq=440.0*pow(2.0,(note-69.0)/12.0); - }; + if(Pdrummode == 0) { + notebasefreq = microtonal->getnotefreq(note, keyshift); + if(notebasefreq < 0.0) + return; //the key is no mapped + } + else + notebasefreq = 440.0 * pow(2.0, (note - 69.0) / 12.0); + ; //Portamento - if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + if(oldfreq < 1.0) + oldfreq = notebasefreq; //this is only the first note is played // For Mono/Legato: Force Portamento Off on first // notes. That means it is required that the previous note is // still held down or sustained for the Portamento to activate // (that's like Legato). - int portamento=0; - if ((Ppolymode!=0) || (not ismonofirstnote)) { + int portamento = 0; + if((Ppolymode != 0) || (not ismonofirstnote)) // I added a third argument to the // ctl.initportamento(...) function to be able // to tell it if we're doing a legato note. - portamento=ctl.initportamento(oldfreq,notebasefreq,doinglegato); - } + portamento = ctl.initportamento(oldfreq, notebasefreq, doinglegato); - if (portamento!=0) ctl.portamento.noteusing=pos; - oldfreq=notebasefreq; + if(portamento != 0) + ctl.portamento.noteusing = pos; + oldfreq = notebasefreq; - lastpos=pos; // Keep a trace of used pos. + lastpos = pos; // Keep a trace of used pos. - if (doinglegato) { + if(doinglegato) { // Do Legato note - if (Pkitmode==0) { // "normal mode" legato note - if ((kit[0].Padenabled!=0) - && (partnote[pos].kititem[0].adnote!=NULL) - && (partnote[posb].kititem[0].adnote!=NULL)) { - partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true);//'true' is to tell it it's being called from here. - partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true); + if(Pkitmode == 0) { // "normal mode" legato note + if((kit[0].Padenabled != 0) + && (partnote[pos].kititem[0].adnote != NULL) + && (partnote[posb].kititem[0].adnote != NULL)) { + partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); //'true' is to tell it it's being called from here. + partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Psubenabled!=0) - && (partnote[pos].kititem[0].subnote!=NULL) - && (partnote[posb].kititem[0].subnote!=NULL)) { - partnote[pos].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Psubenabled != 0) + && (partnote[pos].kititem[0].subnote != NULL) + && (partnote[posb].kititem[0].subnote != NULL)) { + partnote[pos].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[0].Ppadenabled!=0) - && (partnote[pos].kititem[0].padnote!=NULL) - && (partnote[posb].kititem[0].padnote!=NULL)) { - partnote[pos].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); - partnote[posb].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); + if((kit[0].Ppadenabled != 0) + && (partnote[pos].kititem[0].padnote != NULL) + && (partnote[posb].kititem[0].padnote != NULL)) { + partnote[pos].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[0].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } + } + else { // "kit mode" legato note + int ci = 0; + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; - } else { // "kit mode" legato note - int ci=0; - for (int item=0;itemkit[item].Pmaxkey)) continue; - - if ((lastnotecopykit[item].Pmaxkey)) + if((lastnotecopy < kit[item].Pminkey) + || (lastnotecopy > kit[item].Pmaxkey)) continue; // We will not perform legato across 2 key regions. - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].PsendtoparteffectADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].adnote->ADlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Padenabled != 0) && (kit[item].adpars != NULL) + && (partnote[pos].kititem[ci].adnote != NULL) + && (partnote[posb].kititem[ci].adnote != NULL)) { + partnote[pos].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].adnote->ADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Psubenabled!=0) && (kit[item].subpars!=NULL) - && (partnote[pos].kititem[ci].subnote!=NULL) - && (partnote[posb].kititem[ci].subnote!=NULL)) { - partnote[pos].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Psubenabled != 0) + && (kit[item].subpars != NULL) + && (partnote[pos].kititem[ci].subnote != NULL) + && (partnote[posb].kititem[ci].subnote != NULL)) { + partnote[pos].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].subnote->SUBlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].Ppadenabled!=0) && (kit[item].padpars!=NULL) - && (partnote[pos].kititem[ci].padnote!=NULL) - && (partnote[posb].kititem[ci].padnote!=NULL)) { - partnote[pos].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); - partnote[posb].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); + if((kit[item].Ppadenabled != 0) + && (kit[item].padpars != NULL) + && (partnote[pos].kititem[ci].padnote != NULL) + && (partnote[posb].kititem[ci].padnote != NULL)) { + partnote[pos].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); + partnote[posb].kititem[ci].padnote->PADlegatonote( + notebasefreq, + vel, + portamento, + note, + true); } - if ((kit[item].adpars!=NULL)||(kit[item].subpars!=NULL)||(kit[item].padpars!=NULL)) { + if((kit[item].adpars != NULL) + || (kit[item].subpars != NULL) + || (kit[item].padpars != NULL)) { ci++; - if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) && (Pkitmode==2) ) break; + if(((kit[item].Padenabled != 0) + || (kit[item].Psubenabled != 0) + || (kit[item].Ppadenabled != 0)) && (Pkitmode == 2)) + break; } } - if (ci==0) { + if(ci == 0) { // No legato were performed at all, so pretend nothing happened: monomemnotes.pop_back(); // Remove last note from the list. - lastnote=lastnotecopy; // Set lastnote back to previous value. + lastnote = lastnotecopy; // Set lastnote back to previous value. } } return; // Ok, Legato note done, return. } - partnote[pos].itemsplaying=0; - if (legatomodevalid) partnote[posb].itemsplaying=0; + partnote[pos].itemsplaying = 0; + if(legatomodevalid) + partnote[posb].itemsplaying = 0; - if (Pkitmode==0) {//init the notes for the "normal mode" - partnote[pos].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[pos].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,false); - if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,false); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].itemsplaying++; + if(Pkitmode == 0) { //init the notes for the "normal mode" + partnote[pos].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[pos].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Psubenabled != 0) + partnote[pos].kititem[0].subnote = new SUBnote(kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if(kit[0].Ppadenabled != 0) + partnote[pos].kititem[0].padnote = new PADnote(kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + false); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[pos].itemsplaying++; // Spawn another note (but silent) if legatomodevalid==true - if (legatomodevalid) { - partnote[posb].kititem[0].sendtoparteffect=0; - if (kit[0].Padenabled!=0) partnote[posb].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,true);//true for silent. - if (kit[0].Psubenabled!=0) partnote[posb].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,true); - if (kit[0].Ppadenabled!=0) partnote[posb].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,true); - if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[posb].itemsplaying++; + if(legatomodevalid) { + partnote[posb].kititem[0].sendtoparteffect = 0; + if(kit[0].Padenabled != 0) + partnote[posb].kititem[0].adnote = new ADnote(kit[0].adpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); //true for silent. + if(kit[0].Psubenabled != 0) + partnote[posb].kititem[0].subnote = new SUBnote( + kit[0].subpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if(kit[0].Ppadenabled != 0) + partnote[posb].kititem[0].padnote = new PADnote( + kit[0].padpars, + &ctl, + notebasefreq, + vel, + portamento, + note, + true); + if((kit[0].Padenabled != 0) || (kit[0].Psubenabled != 0) + || (kit[0].Ppadenabled != 0)) + partnote[posb].itemsplaying++; } + } + else { //init the notes for the "kit mode" + for(int item = 0; item < NUM_KIT_ITEMS; item++) { + if(kit[item].Pmuted != 0) + continue; + if((note < kit[item].Pminkey) || (note > kit[item].Pmaxkey)) + continue; - } else {//init the notes for the "kit mode" - for (int item=0;itemkit[item].Pmaxkey)) continue; + int ci = partnote[pos].itemsplaying; //ci=current item - int ci=partnote[pos].itemsplaying;//ci=current item + partnote[pos].kititem[ci].sendtoparteffect = + (kit[item].Psendtoparteffect < NUM_PART_EFX ? + kit[item]. + Psendtoparteffect : NUM_PART_EFX); //if this parameter is 127 for "unprocessed" - partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect=0;i--) { //first note in, is first out if there are same note multiple times - if ((partnote[i].status==KEY_PLAYING)&&(partnote[i].note==note)) { - if (ctl.sustain.sustain==0) { //the sustain pedal is not pushed - if ((Ppolymode==0) && (not monomemnotes.empty())) { + for(i = POLIPHONY - 1; i >= 0; i--) //first note in, is first out if there are same note multiple times + if((partnote[i].status == KEY_PLAYING) && (partnote[i].note == note)) { + if(ctl.sustain.sustain == 0) { //the sustain pedal is not pushed + if((Ppolymode == 0) && (not monomemnotes.empty())) MonoMemRenote(); // To play most recent still held note. - } else { + else RelaseNotePos(i); /// break; - } - } else {//the sustain pedal is pushed - partnote[i].status=KEY_RELASED_AND_SUSTAINED; } + else //the sustain pedal is pushed + partnote[i].status = KEY_RELASED_AND_SUSTAINED; } - } -}; +} /* * Controllers */ -void Part::SetController(unsigned int type,int par) +void Part::SetController(unsigned int type, int par) { - switch (type) { + switch(type) { case C_pitchwheel: ctl.setpitchwheel(par); break; case C_expression: ctl.setexpression(par); - setPvolume(Pvolume);//update the volume + setPvolume(Pvolume); //update the volume break; case C_portamento: ctl.setportamento(par); break; case C_panning: ctl.setpanning(par); - setPpanning(Ppanning);//update the panning + setPpanning(Ppanning); //update the panning break; case C_filtercutoff: ctl.setfiltercutoff(par); @@ -529,32 +722,38 @@ void Part::SetController(unsigned int type,int par) break; case C_volume: ctl.setvolume(par); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); break; case C_sustain: ctl.setsustain(par); - if (ctl.sustain.sustain==0) RelaseSustainedKeys(); + if(ctl.sustain.sustain == 0) + RelaseSustainedKeys(); break; case C_allsoundsoff: - AllNotesOff();//Panic + AllNotesOff(); //Panic break; case C_resetallcontrollers: ctl.resetall(); RelaseSustainedKeys(); - if (ctl.volume.receive!=0) volume=ctl.volume.volume; - else setPvolume(Pvolume); - setPvolume(Pvolume);//update the volume - setPpanning(Ppanning);//update the panning + if(ctl.volume.receive != 0) + volume = ctl.volume.volume; + else + setPvolume(Pvolume); + setPvolume(Pvolume); //update the volume + setPpanning(Ppanning); //update the panning - for (int item=0;itemGlobalPar.Reson-> - sendcontroller(C_resonance_center,1.0); + sendcontroller(C_resonance_center, 1.0); kit[item].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,1.0); - }; + sendcontroller(C_resonance_bandwidth, 1.0); + } //more update to add here if I add controllers break; case C_allnotesoff: @@ -562,19 +761,20 @@ void Part::SetController(unsigned int type,int par) break; case C_resonance_center: ctl.setresonancecenter(par); - for (int item=0;itemGlobalPar.Reson-> - sendcontroller(C_resonance_center,ctl.resonancecenter.relcenter); - }; + sendcontroller(C_resonance_center, ctl.resonancecenter.relcenter); + } break; case C_resonance_bandwidth: ctl.setresonancebw(par); kit[0].adpars->GlobalPar.Reson-> - sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw); + sendcontroller(C_resonance_bandwidth, ctl.resonancebandwidth.relbw); break; - }; -}; + } +} /* * Relase the sustained keys */ @@ -582,13 +782,14 @@ void Part::SetController(unsigned int type,int par) void Part::RelaseSustainedKeys() { // Let's call MonoMemRenote() on some conditions: - if ((Ppolymode==0) && (not monomemnotes.empty())) - if (monomemnotes.back()!=lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. + if((Ppolymode == 0) && (not monomemnotes.empty())) + if(monomemnotes.back() != lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. MonoMemRenote(); // To play most recent still held note. - for (int i=0;irelasekey(); - if (partnote[pos].kititem[j].subnote!=NULL) - if (partnote[pos].kititem[j].subnote!=NULL) + if(partnote[pos].kititem[j].subnote != NULL) + if(partnote[pos].kititem[j].subnote != NULL) partnote[pos].kititem[j].subnote->relasekey(); - if (partnote[pos].kititem[j].padnote!=NULL) - if (partnote[pos].kititem[j].padnote) + if(partnote[pos].kititem[j].padnote != NULL) + if(partnote[pos].kititem[j].padnote) partnote[pos].kititem[j].padnote->relasekey(); - }; - partnote[pos].status=KEY_RELASED; -}; + } + partnote[pos].status = KEY_RELASED; +} /* @@ -646,30 +844,30 @@ void Part::RelaseNotePos(int pos) */ void Part::KillNotePos(int pos) { - partnote[pos].status=KEY_OFF; - partnote[pos].note=-1; - partnote[pos].time=0; - partnote[pos].itemsplaying=0; + partnote[pos].status = KEY_OFF; + partnote[pos].note = -1; + partnote[pos].time = 0; + partnote[pos].itemsplaying = 0; - for (int j=0;jPkeylimit=Pkeylimit; - int keylimit=Pkeylimit; - if (keylimit==0) keylimit=POLIPHONY-5; + this->Pkeylimit = Pkeylimit; + int keylimit = Pkeylimit; + if(keylimit == 0) + keylimit = POLIPHONY - 5; //release old keys if the number of notes>keylimit - if (Ppolymode!=0) { - int notecount=0; - for (int i=0;ikeylimit) {//find out the oldest note - for (int i=0;imaxtime)) { - maxtime=partnote[i].time; - oldestnotepos=i; - }; - }; - }; - if (oldestnotepos!=-1) RelaseNotePos(oldestnotepos); - }; -}; + ; + int oldestnotepos = -1, maxtime = 0; + if(notecount > keylimit) { //find out the oldest note + for(int i = 0; i < POLIPHONY; i++) { + if(((partnote[i].status == KEY_PLAYING) + || (partnote[i].status == KEY_RELASED_AND_SUSTAINED)) + && (partnote[i].time > maxtime)) { + maxtime = partnote[i].time; + oldestnotepos = i; + } + } + } + if(oldestnotepos != -1) + RelaseNotePos(oldestnotepos); + } +} /* @@ -708,8 +910,8 @@ void Part::setkeylimit(unsigned char Pkeylimit) */ void Part::AllNotesOff() { - killallnotes=1; -}; + killallnotes = 1; +} /* @@ -717,266 +919,287 @@ void Part::AllNotesOff() */ void Part::ComputePartSmps() { - int i,k; - int noteplay;//0 if there is nothing activated - for (int nefx=0;nefxready!=0) adnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;ifinished()!=0) { + if(adnote->ready != 0) + adnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(adnote->finished() != 0) { delete (adnote); - partnote[k].kititem[item].adnote=NULL; - }; - for (i=0;iready!=0) subnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;iready != 0) + subnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; - for (i=0;ifinished()!=0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //add the SUBnote to part(mix) + partfxinputl[sendcurrenttofx][i] += tmpoutl[i]; + partfxinputr[sendcurrenttofx][i] += tmpoutr[i]; + } + if(subnote->finished() != 0) { delete (subnote); - partnote[k].kititem[item].subnote=NULL; - }; - }; + partnote[k].kititem[item].subnote = NULL; + } + } //get from the PADnote - if (padnote!=NULL) { + if(padnote != NULL) { noteplay++; - if (padnote->ready!=0) padnote->noteout(&tmpoutl[0],&tmpoutr[0]); - else for (i=0;ifinished()!=0) { + if(padnote->ready != 0) + padnote->noteout(&tmpoutl[0], &tmpoutr[0]); + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmpoutl[i] = 0.0; + tmpoutr[i] = 0.0; + } + ; + if(padnote->finished() != 0) { delete (padnote); - partnote[k].kititem[item].padnote=NULL; - }; - for (i=0;iout(partfxinputl[nefx],partfxinputr[nefx]); - if (Pefxroute[nefx]==2) { - for (i=0;iefxoutl[i]; - partfxinputr[nefx+1][i]+=partefx[nefx]->efxoutr[i]; - }; - }; - }; - int routeto=((Pefxroute[nefx]==0) ? nefx+1 : NUM_PART_EFX); - for (i=0;iout(partfxinputl[nefx], partfxinputr[nefx]); + if(Pefxroute[nefx] == 2) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[nefx + 1][i] += partefx[nefx]->efxoutl[i]; + partfxinputr[nefx + 1][i] += partefx[nefx]->efxoutr[i]; + } + } + } + int routeto = ((Pefxroute[nefx] == 0) ? nefx + 1 : NUM_PART_EFX); + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partfxinputl[routeto][i] += partfxinputl[nefx][i]; + partfxinputr[routeto][i] += partfxinputr[nefx][i]; + } + } + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + partoutl[i] = partfxinputl[NUM_PART_EFX][i]; + partoutr[i] = partfxinputr[NUM_PART_EFX][i]; + } //Kill All Notes if killallnotes!=0 - if (killallnotes!=0) { - for (i=0;icleanup(); - }; - }; + ; + } ctl.updateportamento(); -}; +} /* * Parameter control */ void Part::setPvolume(char Pvolume_) { - Pvolume=Pvolume_; - volume=dB2rap((Pvolume-96.0)/96.0*40.0)*ctl.expression.relvolume; -}; + Pvolume = Pvolume_; + volume = dB2rap((Pvolume - 96.0) / 96.0 * 40.0) * ctl.expression.relvolume; +} void Part::setPpanning(char Ppanning_) { - Ppanning=Ppanning_; - panning=Ppanning/127.0+ctl.panning.pan; - if (panning<0.0) panning=0.0; - else if (panning>1.0) panning=1.0; - -}; + Ppanning = Ppanning_; + panning = Ppanning / 127.0 + ctl.panning.pan; + if(panning < 0.0) + panning = 0.0; + else + if(panning > 1.0) + panning = 1.0; +} /* * Enable or disable a kit item */ -void Part::setkititemstatus(int kititem,int Penabled_) +void Part::setkititemstatus(int kititem, int Penabled_) { - if ((kititem==0)&&(kititem>=NUM_KIT_ITEMS)) return;//nonexistent kit item and the first kit item is always enabled - kit[kititem].Penabled=Penabled_; + if((kititem == 0) && (kititem >= NUM_KIT_ITEMS)) + return; //nonexistent kit item and the first kit item is always enabled + kit[kititem].Penabled = Penabled_; - bool resetallnotes=false; - if (Penabled_==0) { - if (kit[kititem].adpars!=NULL) delete (kit[kititem].adpars); - if (kit[kititem].subpars!=NULL) delete (kit[kititem].subpars); - if (kit[kititem].padpars!=NULL) { + bool resetallnotes = false; + if(Penabled_ == 0) { + if(kit[kititem].adpars != NULL) + delete (kit[kititem].adpars); + if(kit[kititem].subpars != NULL) + delete (kit[kititem].subpars); + if(kit[kititem].padpars != NULL) { delete (kit[kititem].padpars); - resetallnotes=true; - }; - kit[kititem].adpars=NULL; - kit[kititem].subpars=NULL; - kit[kititem].padpars=NULL; - kit[kititem].Pname[0]='\0'; - } else { - if (kit[kititem].adpars==NULL) kit[kititem].adpars=new ADnoteParameters(fft); - if (kit[kititem].subpars==NULL) kit[kititem].subpars=new SUBnoteParameters(); - if (kit[kititem].padpars==NULL) kit[kititem].padpars=new PADnoteParameters(fft,mutex); - }; + resetallnotes = true; + } + kit[kititem].adpars = NULL; + kit[kititem].subpars = NULL; + kit[kititem].padpars = NULL; + kit[kititem].Pname[0] = '\0'; + } + else { + if(kit[kititem].adpars == NULL) + kit[kititem].adpars = new ADnoteParameters(fft); + if(kit[kititem].subpars == NULL) + kit[kititem].subpars = new SUBnoteParameters(); + if(kit[kititem].padpars == NULL) + kit[kititem].padpars = new PADnoteParameters(fft, mutex); + } - if (resetallnotes) for (int k=0;kbeginbranch("INFO"); - xml->addparstr("name",(char *)Pname); - xml->addparstr("author",(char *)info.Pauthor); - xml->addparstr("comments",(char *)info.Pcomments); - xml->addpar("type",info.Ptype); + xml->addparstr("name", (char *)Pname); + xml->addparstr("author", (char *)info.Pauthor); + xml->addparstr("comments", (char *)info.Pcomments); + xml->addpar("type", info.Ptype); xml->endbranch(); xml->beginbranch("INSTRUMENT_KIT"); - xml->addpar("kit_mode",Pkitmode); - xml->addparbool("drum_mode",Pdrummode); + xml->addpar("kit_mode", Pkitmode); + xml->addparbool("drum_mode", Pdrummode); - for (int i=0;ibeginbranch("INSTRUMENT_KIT_ITEM",i); - xml->addparbool("enabled",kit[i].Penabled); - if (kit[i].Penabled!=0) { - xml->addparstr("name",(char *)kit[i].Pname); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + xml->beginbranch("INSTRUMENT_KIT_ITEM", i); + xml->addparbool("enabled", kit[i].Penabled); + if(kit[i].Penabled != 0) { + xml->addparstr("name", (char *)kit[i].Pname); - xml->addparbool("muted",kit[i].Pmuted); - xml->addpar("min_key",kit[i].Pminkey); - xml->addpar("max_key",kit[i].Pmaxkey); + xml->addparbool("muted", kit[i].Pmuted); + xml->addpar("min_key", kit[i].Pminkey); + xml->addpar("max_key", kit[i].Pmaxkey); - xml->addpar("send_to_instrument_effect",kit[i].Psendtoparteffect); + xml->addpar("send_to_instrument_effect", kit[i].Psendtoparteffect); - xml->addparbool("add_enabled",kit[i].Padenabled); - if ((kit[i].Padenabled!=0)&&(kit[i].adpars!=NULL)) { + xml->addparbool("add_enabled", kit[i].Padenabled); + if((kit[i].Padenabled != 0) && (kit[i].adpars != NULL)) { xml->beginbranch("ADD_SYNTH_PARAMETERS"); kit[i].adpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("sub_enabled",kit[i].Psubenabled); - if ((kit[i].Psubenabled!=0)&&(kit[i].subpars!=NULL)) { + xml->addparbool("sub_enabled", kit[i].Psubenabled); + if((kit[i].Psubenabled != 0) && (kit[i].subpars != NULL)) { xml->beginbranch("SUB_SYNTH_PARAMETERS"); kit[i].subpars->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("pad_enabled",kit[i].Ppadenabled); - if ((kit[i].Ppadenabled!=0)&&(kit[i].padpars!=NULL)) { + xml->addparbool("pad_enabled", kit[i].Ppadenabled); + if((kit[i].Ppadenabled != 0) && (kit[i].padpars != NULL)) { xml->beginbranch("PAD_SYNTH_PARAMETERS"); kit[i].padpars->add2XML(xml); xml->endbranch(); - }; - - }; + } + } xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("INSTRUMENT_EFFECTS"); - for (int nefx=0;nefxbeginbranch("INSTRUMENT_EFFECT",nefx); + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + xml->beginbranch("INSTRUMENT_EFFECT", nefx); xml->beginbranch("EFFECT"); partefx[nefx]->add2XML(xml); xml->endbranch(); - xml->addpar("route",Pefxroute[nefx]); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - xml->addparbool("bypass",Pefxbypass[nefx]); + xml->addpar("route", Pefxroute[nefx]); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + xml->addparbool("bypass", Pefxbypass[nefx]); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void Part::add2XML(XMLwrapper *xml) { //parameters - xml->addparbool("enabled",Penabled); - if ((Penabled==0)&&(xml->minimal)) return; + xml->addparbool("enabled", Penabled); + if((Penabled == 0) && (xml->minimal)) + return; - xml->addpar("volume",Pvolume); - xml->addpar("panning",Ppanning); + xml->addpar("volume", Pvolume); + xml->addpar("panning", Ppanning); - xml->addpar("min_key",Pminkey); - xml->addpar("max_key",Pmaxkey); - xml->addpar("key_shift",Pkeyshift); - xml->addpar("rcv_chn",Prcvchn); + xml->addpar("min_key", Pminkey); + xml->addpar("max_key", Pmaxkey); + xml->addpar("key_shift", Pkeyshift); + xml->addpar("rcv_chn", Prcvchn); - xml->addpar("velocity_sensing",Pvelsns); - xml->addpar("velocity_offset",Pveloffs); + xml->addpar("velocity_sensing", Pvelsns); + xml->addpar("velocity_offset", Pveloffs); - xml->addparbool("note_on",Pnoteon); - xml->addparbool("poly_mode",Ppolymode); - xml->addpar("legato_mode",Plegatomode); - xml->addpar("key_limit",Pkeylimit); + xml->addparbool("note_on", Pnoteon); + xml->addparbool("poly_mode", Ppolymode); + xml->addpar("legato_mode", Plegatomode); + xml->addpar("key_limit", Pkeylimit); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); @@ -985,154 +1208,163 @@ void Part::add2XML(XMLwrapper *xml) xml->beginbranch("CONTROLLER"); ctl.add2XML(xml); xml->endbranch(); -}; +} int Part::saveXML(char *filename) { XMLwrapper *xml; - xml=new XMLwrapper(); + xml = new XMLwrapper(); xml->beginbranch("INSTRUMENT"); add2XMLinstrument(xml); xml->endbranch(); - int result=xml->saveXMLfile(filename); + int result = xml->saveXMLfile(filename); delete (xml); - return(result); -}; + return result; +} int Part::loadXMLinstrument(const char *filename) { - XMLwrapper *xml=new XMLwrapper(); - if (xml->loadXMLfile(filename)<0) { - delete(xml); - return(-1); - }; + XMLwrapper *xml = new XMLwrapper(); + if(xml->loadXMLfile(filename) < 0) { + delete (xml); + return -1; + } - if (xml->enterbranch("INSTRUMENT")==0) return(-10); + if(xml->enterbranch("INSTRUMENT") == 0) + return -10; getfromXMLinstrument(xml); xml->exitbranch(); - delete(xml); - return(0); -}; + delete (xml); + return 0; +} void Part::applyparameters() { - for (int n=0;napplyparameters(true); - }; -}; + for(int n = 0; n < NUM_KIT_ITEMS; n++) + if((kit[n].padpars != NULL) && (kit[n].Ppadenabled != 0)) + kit[n].padpars->applyparameters(true); + ; +} void Part::getfromXMLinstrument(XMLwrapper *xml) { - if (xml->enterbranch("INFO")) { - xml->getparstr("name",(char *)Pname,PART_MAX_NAME_LEN); - xml->getparstr("author",(char *)info.Pauthor,MAX_INFO_TEXT_SIZE); - xml->getparstr("comments",(char *)info.Pcomments,MAX_INFO_TEXT_SIZE); - info.Ptype=xml->getpar("type",info.Ptype,0,16); + if(xml->enterbranch("INFO")) { + xml->getparstr("name", (char *)Pname, PART_MAX_NAME_LEN); + xml->getparstr("author", (char *)info.Pauthor, MAX_INFO_TEXT_SIZE); + xml->getparstr("comments", (char *)info.Pcomments, MAX_INFO_TEXT_SIZE); + info.Ptype = xml->getpar("type", info.Ptype, 0, 16); xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_KIT")) { - Pkitmode=xml->getpar127("kit_mode",Pkitmode); - Pdrummode=xml->getparbool("drum_mode",Pdrummode); + if(xml->enterbranch("INSTRUMENT_KIT")) { + Pkitmode = xml->getpar127("kit_mode", Pkitmode); + Pdrummode = xml->getparbool("drum_mode", Pdrummode); - setkititemstatus(0,0); - for (int i=0;ienterbranch("INSTRUMENT_KIT_ITEM",i)==0) continue; - setkititemstatus(i,xml->getparbool("enabled",kit[i].Penabled)); - if (kit[i].Penabled==0) { + setkititemstatus(0, 0); + for(int i = 0; i < NUM_KIT_ITEMS; i++) { + if(xml->enterbranch("INSTRUMENT_KIT_ITEM", i) == 0) + continue; + setkititemstatus(i, xml->getparbool("enabled", kit[i].Penabled)); + if(kit[i].Penabled == 0) { xml->exitbranch(); continue; - }; + } - xml->getparstr("name",(char *)kit[i].Pname,PART_MAX_NAME_LEN); + xml->getparstr("name", (char *)kit[i].Pname, PART_MAX_NAME_LEN); - kit[i].Pmuted=xml->getparbool("muted",kit[i].Pmuted); - kit[i].Pminkey=xml->getpar127("min_key",kit[i].Pminkey); - kit[i].Pmaxkey=xml->getpar127("max_key",kit[i].Pmaxkey); + kit[i].Pmuted = xml->getparbool("muted", kit[i].Pmuted); + kit[i].Pminkey = xml->getpar127("min_key", kit[i].Pminkey); + kit[i].Pmaxkey = xml->getpar127("max_key", kit[i].Pmaxkey); - kit[i].Psendtoparteffect=xml->getpar127("send_to_instrument_effect",kit[i].Psendtoparteffect); + kit[i].Psendtoparteffect = xml->getpar127( + "send_to_instrument_effect", + kit[i].Psendtoparteffect); - kit[i].Padenabled=xml->getparbool("add_enabled",kit[i].Padenabled); - if (xml->enterbranch("ADD_SYNTH_PARAMETERS")) { + kit[i].Padenabled = xml->getparbool("add_enabled", + kit[i].Padenabled); + if(xml->enterbranch("ADD_SYNTH_PARAMETERS")) { kit[i].adpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Psubenabled=xml->getparbool("sub_enabled",kit[i].Psubenabled); - if (xml->enterbranch("SUB_SYNTH_PARAMETERS")) { + kit[i].Psubenabled = xml->getparbool("sub_enabled", + kit[i].Psubenabled); + if(xml->enterbranch("SUB_SYNTH_PARAMETERS")) { kit[i].subpars->getfromXML(xml); xml->exitbranch(); - }; + } - kit[i].Ppadenabled=xml->getparbool("pad_enabled",kit[i].Ppadenabled); - if (xml->enterbranch("PAD_SYNTH_PARAMETERS")) { + kit[i].Ppadenabled = xml->getparbool("pad_enabled", + kit[i].Ppadenabled); + if(xml->enterbranch("PAD_SYNTH_PARAMETERS")) { kit[i].padpars->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("INSTRUMENT_EFFECTS")) { - for (int nefx=0;nefxenterbranch("INSTRUMENT_EFFECT",nefx)==0) continue; - if (xml->enterbranch("EFFECT")) { + if(xml->enterbranch("INSTRUMENT_EFFECTS")) { + for(int nefx = 0; nefx < NUM_PART_EFX; nefx++) { + if(xml->enterbranch("INSTRUMENT_EFFECT", nefx) == 0) + continue; + if(xml->enterbranch("EFFECT")) { partefx[nefx]->getfromXML(xml); xml->exitbranch(); - }; + } - Pefxroute[nefx]=xml->getpar("route",Pefxroute[nefx],0,NUM_PART_EFX); - partefx[nefx]->setdryonly(Pefxroute[nefx]==2); - Pefxbypass[nefx]=xml->getparbool("bypass",Pefxbypass[nefx]); + Pefxroute[nefx] = xml->getpar("route", + Pefxroute[nefx], + 0, + NUM_PART_EFX); + partefx[nefx]->setdryonly(Pefxroute[nefx] == 2); + Pefxbypass[nefx] = xml->getparbool("bypass", Pefxbypass[nefx]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} void Part::getfromXML(XMLwrapper *xml) { - Penabled=xml->getparbool("enabled",Penabled); + Penabled = xml->getparbool("enabled", Penabled); - setPvolume(xml->getpar127("volume",Pvolume)); - setPpanning(xml->getpar127("panning",Ppanning)); + setPvolume(xml->getpar127("volume", Pvolume)); + setPpanning(xml->getpar127("panning", Ppanning)); - Pminkey=xml->getpar127("min_key",Pminkey); - Pmaxkey=xml->getpar127("max_key",Pmaxkey); - Pkeyshift=xml->getpar127("key_shift",Pkeyshift); - Prcvchn=xml->getpar127("rcv_chn",Prcvchn); + Pminkey = xml->getpar127("min_key", Pminkey); + Pmaxkey = xml->getpar127("max_key", Pmaxkey); + Pkeyshift = xml->getpar127("key_shift", Pkeyshift); + Prcvchn = xml->getpar127("rcv_chn", Prcvchn); - Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); - Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + Pvelsns = xml->getpar127("velocity_sensing", Pvelsns); + Pveloffs = xml->getpar127("velocity_offset", Pveloffs); - Pnoteon=xml->getparbool("note_on",Pnoteon); - Ppolymode=xml->getparbool("poly_mode",Ppolymode); - Plegatomode=xml->getparbool("legato_mode",Plegatomode);//older versions - if (!Plegatomode) Plegatomode=xml->getpar127("legato_mode",Plegatomode); - Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + Pnoteon = xml->getparbool("note_on", Pnoteon); + Ppolymode = xml->getparbool("poly_mode", Ppolymode); + Plegatomode = xml->getparbool("legato_mode", Plegatomode); //older versions + if(!Plegatomode) + Plegatomode = xml->getpar127("legato_mode", Plegatomode); + Pkeylimit = xml->getpar127("key_limit", Pkeylimit); - if (xml->enterbranch("INSTRUMENT")) { + if(xml->enterbranch("INSTRUMENT")) { getfromXMLinstrument(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("CONTROLLER")) { + if(xml->enterbranch("CONTROLLER")) { ctl.getfromXML(xml); xml->exitbranch(); - }; - -}; - - + } +} diff --git a/plugins/zynaddsubfx/src/Misc/Part.h b/plugins/zynaddsubfx/src/Misc/Part.h index 1ac12a50b..66169e3e3 100644 --- a/plugins/zynaddsubfx/src/Misc/Part.h +++ b/plugins/zynaddsubfx/src/Misc/Part.h @@ -43,159 +43,163 @@ /** Part implementation*/ class Part { + public: + /**Constructor + * @param microtonal_ Pointer to the microtonal object + * @param fft_ Pointer to the FFTwrapper + * @param mutex_ Pointer to the master pthread_mutex_t*/ + Part(Microtonal *microtonal_, FFTwrapper *fft_, pthread_mutex_t *mutex_); + /**Destructor*/ + ~Part(); -public: - /**Constructor - * @param microtonal_ Pointer to the microtonal object - * @param fft_ Pointer to the FFTwrapper - * @param mutex_ Pointer to the master pthread_mutex_t*/ - Part(Microtonal *microtonal_,FFTwrapper *fft_,pthread_mutex_t *mutex_); - /**Destructor*/ - ~Part(); + // Midi commands implemented + void NoteOn(unsigned char note, + unsigned char velocity, + int masterkeyshift); + void NoteOff(unsigned char note); + void AllNotesOff(); //panic + void SetController(unsigned int type, int par); + void RelaseSustainedKeys(); //this is called when the sustain pedal is relased + void RelaseAllKeys(); //this is called on AllNotesOff controller - // Midi commands implemented - void NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift); - void NoteOff(unsigned char note); - void AllNotesOff();//panic - void SetController(unsigned int type,int par); - void RelaseSustainedKeys();//this is called when the sustain pedal is relased - void RelaseAllKeys();//this is called on AllNotesOff controller + /* The synthesizer part output */ + void ComputePartSmps(); //Part output - /* The synthesizer part output */ - void ComputePartSmps();//Part output - - //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) + //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) - //saves the instrument settings to a XML file - //returns 0 for ok or <0 if there is an error - int saveXML(char *filename); - int loadXMLinstrument(const char *filename); + //saves the instrument settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + int loadXMLinstrument(const char *filename); - void add2XML(XMLwrapper *xml); - void add2XMLinstrument(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void add2XMLinstrument(XMLwrapper *xml); - void defaults(); - void defaultsinstrument(); + void defaults(); + void defaultsinstrument(); - void applyparameters(); + void applyparameters(); - void getfromXML(XMLwrapper *xml); - void getfromXMLinstrument(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + void getfromXMLinstrument(XMLwrapper *xml); - void cleanup(); + void cleanup(); // ADnoteParameters *ADPartParameters; // SUBnoteParameters *SUBPartParameters; - //the part's kit - struct { - unsigned char Penabled,Pmuted,Pminkey,Pmaxkey; - unsigned char *Pname; - unsigned char Padenabled,Psubenabled,Ppadenabled; - unsigned char Psendtoparteffect; - ADnoteParameters *adpars; - SUBnoteParameters *subpars; - PADnoteParameters *padpars; - } kit[NUM_KIT_ITEMS]; - - - //Part parameters - void setkeylimit(unsigned char Pkeylimit); - void setkititemstatus(int kititem,int Penabled_); - - unsigned char Penabled;/** monomemnotes; // A list to remember held notes. - struct { - unsigned char velocity; - int mkeyshift;// I'm not sure masterkeyshift should be remembered. - } monomem[256]; /* 256 is to cover all possible note values. - monomem[] is used in conjunction with the list to - store the velocity and masterkeyshift values of a - given note (the list only store note values). - For example 'monomem[note].velocity' would be the - velocity value of the note 'note'. - */ + //Part parameters + void setkeylimit(unsigned char Pkeylimit); + void setkititemstatus(int kititem, int Penabled_); - PartNotes partnote[POLIPHONY]; + unsigned char Penabled; /** monomemnotes; // A list to remember held notes. + struct { + unsigned char velocity; + int mkeyshift; // I'm not sure masterkeyshift should be remembered. + } monomem[256]; /* 256 is to cover all possible note values. + monomem[] is used in conjunction with the list to + store the velocity and masterkeyshift values of a + given note (the list only store note values). + For example 'monomem[note].velocity' would be the + velocity value of the note 'note'. + */ + + PartNotes partnote[POLIPHONY]; + + REALTYPE *tmpoutl; //used to get the note + REALTYPE *tmpoutr; + + REALTYPE oldfreq; //this is used for portamento + Microtonal *microtonal; + FFTwrapper *fft; }; #endif diff --git a/plugins/zynaddsubfx/src/Misc/Stereo.cpp b/plugins/zynaddsubfx/src/Misc/Stereo.cpp index fde296043..928be6e29 100644 --- a/plugins/zynaddsubfx/src/Misc/Stereo.cpp +++ b/plugins/zynaddsubfx/src/Misc/Stereo.cpp @@ -19,19 +19,20 @@ Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -template +template Stereo::Stereo(const T &left, const T &right) - :leftChannel(left),rightChannel(right) + :leftChannel(left), rightChannel(right) {} -template +template Stereo::Stereo(const T &val) - :leftChannel(val),rightChannel(val) + :leftChannel(val), rightChannel(val) {} -template -void Stereo::operator=(const Stereo & nstr) +template +void Stereo::operator=(const Stereo &nstr) { - leftChannel=nstr.leftChannel; - rightChannel=nstr.rightChannel; + leftChannel = nstr.leftChannel; + rightChannel = nstr.rightChannel; } + diff --git a/plugins/zynaddsubfx/src/Misc/Stereo.h b/plugins/zynaddsubfx/src/Misc/Stereo.h index b9c71b359..8bdf43017 100644 --- a/plugins/zynaddsubfx/src/Misc/Stereo.h +++ b/plugins/zynaddsubfx/src/Misc/Stereo.h @@ -21,46 +21,45 @@ #ifndef STEREO_H #define STEREO_H -template +template class Stereo { -public: - Stereo(const T &left,const T &right); + public: + Stereo(const T &left, const T &right); - /**Initializes Stereo with left and right set to val - * @param val the value for both channels*/ - Stereo(const T &val); - ~Stereo() {}; - - void operator=(const Stereo &smp); - T &left() { - return leftChannel; - }; - T &right() { - return rightChannel; - }; - T &l() { - return leftChannel; - }; - T &r() { - return rightChannel; - }; - const T &left()const { - return leftChannel; - }; - const T &right()const { - return rightChannel; - }; - const T &l()const { - return leftChannel; - }; - const T &r()const { - return rightChannel; - }; -private: - T leftChannel; - T rightChannel; + /**Initializes Stereo with left and right set to val + * @param val the value for both channels*/ + Stereo(const T &val); + ~Stereo() {} + void operator=(const Stereo &smp); + T &left() { + return leftChannel; + } + T &right() { + return rightChannel; + } + T &l() { + return leftChannel; + } + T &r() { + return rightChannel; + } + const T &left() const { + return leftChannel; + } + const T &right() const { + return rightChannel; + } + const T &l() const { + return leftChannel; + } + const T &r() const { + return rightChannel; + } + private: + T leftChannel; + T rightChannel; }; #include "Stereo.cpp" #endif diff --git a/plugins/zynaddsubfx/src/Misc/Util.cpp b/plugins/zynaddsubfx/src/Misc/Util.cpp index 5069a9ea6..0f862c602 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.cpp +++ b/plugins/zynaddsubfx/src/Misc/Util.cpp @@ -31,92 +31,85 @@ #include #include -int SAMPLE_RATE=44100; -int SOUND_BUFFER_SIZE=256; -int OSCIL_SIZE=1024; +int SAMPLE_RATE = 44100; +int SOUND_BUFFER_SIZE = 256; +int OSCIL_SIZE = 1024; -Config config; +Config config; REALTYPE *denormalkillbuf; /* * Transform the velocity according the scaling parameter (velocity sensing) */ -REALTYPE VelF(REALTYPE velocity,unsigned char scaling) +REALTYPE VelF(REALTYPE velocity, unsigned char scaling) { REALTYPE x; - x=pow(VELOCITY_MAX_SCALE,(64.0-scaling)/64.0); - if ((scaling==127)||(velocity>0.99)) return(1.0); - else return(pow(velocity,x)); -}; + x = pow(VELOCITY_MAX_SCALE, (64.0 - scaling) / 64.0); + if((scaling == 127) || (velocity > 0.99)) + return 1.0; + else + return pow(velocity, x); +} /* * Get the detune in cents */ -REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune) +REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune) { - REALTYPE det=0.0,octdet=0.0,cdet=0.0,findet=0.0; + REALTYPE det = 0.0, octdet = 0.0, cdet = 0.0, findet = 0.0; //Get Octave - int octave=coarsedetune/1024; - if (octave>=8) octave-=16; - octdet=octave*1200.0; + int octave = coarsedetune / 1024; + if(octave >= 8) + octave -= 16; + octdet = octave * 1200.0; //Coarse and fine detune - int cdetune=coarsedetune%1024; - if (cdetune>512) cdetune-=1024; + int cdetune = coarsedetune % 1024; + if(cdetune > 512) + cdetune -= 1024; - int fdetune=finedetune-8192; + int fdetune = finedetune - 8192; - switch (type) { + switch(type) { // case 1: is used for the default (see below) case 2: - cdet=fabs(cdetune*10.0); - findet=fabs(fdetune/8192.0)*10.0; + cdet = fabs(cdetune * 10.0); + findet = fabs(fdetune / 8192.0) * 10.0; break; case 3: - cdet=fabs(cdetune*100); - findet=pow(10,fabs(fdetune/8192.0)*3.0)/10.0-0.1; + cdet = fabs(cdetune * 100); + findet = pow(10, fabs(fdetune / 8192.0) * 3.0) / 10.0 - 0.1; break; case 4: - cdet=fabs(cdetune*701.95500087);//perfect fifth - findet=(pow(2,fabs(fdetune/8192.0)*12.0)-1.0)/4095*1200; + cdet = fabs(cdetune * 701.95500087); //perfect fifth + findet = (pow(2, fabs(fdetune / 8192.0) * 12.0) - 1.0) / 4095 * 1200; break; - //case ...: need to update N_DETUNE_TYPES, if you'll add more + //case ...: need to update N_DETUNE_TYPES, if you'll add more default: - cdet=fabs(cdetune*50.0); - findet=fabs(fdetune/8192.0)*35.0;//almost like "Paul's Sound Designer 2" + cdet = fabs(cdetune * 50.0); + findet = fabs(fdetune / 8192.0) * 35.0; //almost like "Paul's Sound Designer 2" break; - }; - if (finedetune<8192) findet=-findet; - if (cdetune<0) cdet=-cdet; + } + if(finedetune < 8192) + findet = -findet; + if(cdetune < 0) + cdet = -cdet; - det=octdet+cdet+findet; - return(det); -}; + det = octdet + cdet + findet; + return det; +} bool fileexists(const char *filename) { struct stat tmp; - int result=stat(filename,&tmp); - if (result>=0) return(true); + int result = stat(filename, &tmp); + if(result >= 0) + return true; - return(false); -}; - -void newFFTFREQS(FFTFREQS *f,int size) -{ - f->c=new REALTYPE[size]; - f->s=new REALTYPE[size]; - for (int i=0;ic[i]=0.0; - f->s[i]=0.0; - }; -}; -void deleteFFTFREQS(FFTFREQS *f) -{ - delete[] f->c; - delete[] f->s; - f->c=f->s=NULL; -}; + return false; +} diff --git a/plugins/zynaddsubfx/src/Misc/Util.h b/plugins/zynaddsubfx/src/Misc/Util.h index 66c313b13..ccdac4dea 100644 --- a/plugins/zynaddsubfx/src/Misc/Util.h +++ b/plugins/zynaddsubfx/src/Misc/Util.h @@ -23,23 +23,42 @@ #ifndef UTIL_H #define UTIL_H -#include +#include +#include #include "../globals.h" -#include "Microtonal.h" -#include "../DSP/FFTwrapper.h" #include "Config.h" //Velocity Sensing function -extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling); +extern REALTYPE VelF(REALTYPE velocity, unsigned char scaling); bool fileexists(const char *filename); #define N_DETUNE_TYPES 4 //the number of detune types -extern REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune); +extern REALTYPE getdetune(unsigned char type, + unsigned short int coarsedetune, + unsigned short int finedetune); -extern REALTYPE *denormalkillbuf;/** +std::string stringFrom(T x) +{ + std::stringstream ss; + ss << x; + return ss.str(); +} + +template +T stringTo(const char *x) +{ + std::string str = x != NULL ? x : "0"; //should work for the basic float/int + std::stringstream ss(str); + T ans; + ss >> ans; + return ans; +} + #endif diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp index 078cbb86f..b9ee3d6e6 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.cpp @@ -3,7 +3,9 @@ XMLwrapper.C - XML wrapper Copyright (C) 2003-2005 Nasca Octavian Paul + Copyright (C) 2009-2009 Mark McCurry Author: Nasca Octavian Paul + Mark McCurry This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License @@ -34,241 +36,263 @@ using namespace std; -int xml_k=0; -char tabs[STACKSIZE+2]; +int xml_k = 0; +bool verbose = false; -const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where) +const char *XMLwrapper_whitespace_callback(mxml_node_t *node, int where) { - const char *name=node->value.element.name; + const char *name = node->value.element.name; - if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL); - if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL); + if((where == MXML_WS_BEFORE_OPEN) && (!strcmp(name, "?xml"))) + return NULL; + if((where == MXML_WS_BEFORE_CLOSE) && (!strcmp(name, "string"))) + return NULL; - if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) { + if((where == MXML_WS_BEFORE_OPEN) || (where == MXML_WS_BEFORE_CLOSE)) /* const char *tmp=node->value.element.name; - if (tmp!=NULL) { - if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { - printf("%s ",tmp); - if (where==MXML_WS_BEFORE_OPEN) xml_k++; - if (where==MXML_WS_BEFORE_CLOSE) xml_k--; - if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; - if (xml_k<0) xml_k=0; - printf("%d\n",xml_k); - printf("\n"); - }; + if (tmp!=NULL) { + if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { + printf("%s ",tmp); + if (where==MXML_WS_BEFORE_OPEN) xml_k++; + if (where==MXML_WS_BEFORE_CLOSE) xml_k--; + if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; + if (xml_k<0) xml_k=0; + printf("%d\n",xml_k); + printf("\n"); + }; - }; - int i=0; - for (i=1;i(mxmlFindElement( + const_cast(node), + const_cast(top), + name, attr, value, descend)); +} + +//temporary const overload of mxmlElementGetAttr +const char *mxmlElementGetAttr(const mxml_node_t *node, const char *name) +{ + return mxmlElementGetAttr(const_cast(node), name); +} XMLwrapper::XMLwrapper() { - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + version.Major = 2; + version.Minor = 4; + version.Revision = 1; - minimal=true; - stackpos=0; + minimal = true; - information.PADsynth_used=false; - - tree=mxmlNewElement(MXML_NO_PARENT,"?xml version=\"1.0\" encoding=\"UTF-8\"?"); + node = tree = mxmlNewElement(MXML_NO_PARENT, + "?xml version=\"1.0\" encoding=\"UTF-8\"?"); /* for mxml 2.1 (and older) tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); mxmlElementSetAttr(tree,"version","1.0"); mxmlElementSetAttr(tree,"encoding","UTF-8"); */ - mxml_node_t *doctype=mxmlNewElement(tree,"!DOCTYPE"); - mxmlElementSetAttr(doctype,"ZynAddSubFX-data",NULL); + mxml_node_t *doctype = mxmlNewElement(tree, "!DOCTYPE"); + mxmlElementSetAttr(doctype, "ZynAddSubFX-data", NULL); - node=root=mxmlNewElement(tree,"ZynAddSubFX-data"); - - mxmlElementSetAttr(root,"version-major","1"); - mxmlElementSetAttr(root,"version-minor","1"); - mxmlElementSetAttr(root,"ZynAddSubFX-author","Nasca Octavian Paul"); + node = root = addparams("ZynAddSubFX-data", 4, + "version-major", stringFrom( + version.Major).c_str(), + "version-minor", stringFrom( + version.Minor).c_str(), + "version-revision", + stringFrom(version.Revision).c_str(), + "ZynAddSubFX-author", "Nasca Octavian Paul"); //make the empty branch that will contain the information parameters - info=addparams0("INFORMATION"); + info = addparams("INFORMATION", 0); //save zynaddsubfx specifications beginbranch("BASE_PARAMETERS"); - addpar("max_midi_parts",NUM_MIDI_PARTS); - addpar("max_kit_items_per_instrument",NUM_KIT_ITEMS); + addpar("max_midi_parts", NUM_MIDI_PARTS); + addpar("max_kit_items_per_instrument", NUM_KIT_ITEMS); - addpar("max_system_effects",NUM_SYS_EFX); - addpar("max_insertion_effects",NUM_INS_EFX); - addpar("max_instrument_effects",NUM_PART_EFX); + addpar("max_system_effects", NUM_SYS_EFX); + addpar("max_insertion_effects", NUM_INS_EFX); + addpar("max_instrument_effects", NUM_PART_EFX); - addpar("max_addsynth_voices",NUM_VOICES); + addpar("max_addsynth_voices", NUM_VOICES); endbranch(); - -}; +} XMLwrapper::~XMLwrapper() { - if (tree!=NULL) mxmlDelete(tree); -}; + if(tree != NULL) + mxmlDelete(tree); +} -bool XMLwrapper::checkfileinformation(const char *filename) +void XMLwrapper::setPadSynth(bool enabled) { - stackpos=0; - ZERO(&parentstack,(int)sizeof(parentstack)); - information.PADsynth_used=false; + /**@bug this might create multiple nodes when only one is needed*/ + mxml_node_t *oldnode = node; + node = info; + //Info storing + addparbool("PADsynth_used", enabled); + node = oldnode; +} - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; - char *xmldata=doloadfile(filename); - if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed +bool XMLwrapper::hasPadSynth() const +{ + /**Right now this has a copied implementation of setparbool, so this should + * be reworked as XMLwrapper evolves*/ + mxml_node_t *tmp = mxmlFindElement(tree, + tree, + "INFORMATION", + NULL, + NULL, + MXML_DESCEND); + mxml_node_t *parameter = mxmlFindElement(tmp, + tmp, + "par_bool", + "name", + "PADsynth_used", + MXML_DESCEND_FIRST); + if(parameter == NULL) //no information availiable + return false; - char *start=strstr(xmldata,""); - char *end=strstr(xmldata,""); + const char *strval = mxmlElementGetAttr(parameter, "value"); + if(strval == NULL) //no information available + return false; - if ((start==NULL)||(end==NULL)||(start>end)) { - delete []xmldata; - return(false); - }; - end+=strlen(""); - end[0]='\0'; - - tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); - node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK); - if (root==NULL) { - delete []xmldata; - mxmlDelete(tree); - node=root=tree=NULL; - return(false); - }; - - root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND); - push(root); - - if (root==NULL) { - delete []xmldata; - mxmlDelete(tree); - node=root=tree=NULL; - return(false); - }; - - information.PADsynth_used=getparbool("PADsynth_used",false); - - exitbranch(); - if (tree!=NULL) mxmlDelete(tree); - delete []xmldata; - node=root=tree=NULL; - - return(true); -}; + if((strval[0] == 'Y') || (strval[0] == 'y')) + return true; + else + return false; +} /* SAVE XML members */ -int XMLwrapper::saveXMLfile(const string &filename) +int XMLwrapper::saveXMLfile(const string &filename) const { - char *xmldata=getXMLdata(); - if (xmldata==NULL) return(-2); + char *xmldata = getXMLdata(); + if(xmldata == NULL) + return -2; - int compression=config.cfg.GzipCompression; - int result=dosavefile(filename.c_str(),compression,xmldata); + int compression = config.cfg.GzipCompression; + int result = dosavefile(filename.c_str(), compression, xmldata); free(xmldata); - return(result); -}; + return result; +} -char *XMLwrapper::getXMLdata() +char *XMLwrapper::getXMLdata() const { - xml_k=0; - ZERO(tabs,STACKSIZE+2); + xml_k = 0; - mxml_node_t *oldnode=node; + char *xmldata = mxmlSaveAllocString(tree, XMLwrapper_whitespace_callback); - node=info; - //Info storing - addparbool("PADsynth_used",information.PADsynth_used); - - node=oldnode; - char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); - - return(xmldata); -}; + return xmldata; +} -int XMLwrapper::dosavefile(const char *filename,int compression,const char *xmldata) +int XMLwrapper::dosavefile(const char *filename, + int compression, + const char *xmldata) const { - if (compression==0) { + if(compression == 0) { FILE *file; - file=fopen(filename,"w"); - if (file==NULL) return(-1); - fputs(xmldata,file); + file = fopen(filename, "w"); + if(file == NULL) + return -1; + fputs(xmldata, file); fclose(file); - } else { - if (compression>9) compression=9; - if (compression<1) compression=1; + } + else { + if(compression > 9) + compression = 9; + if(compression < 1) + compression = 1; char options[10]; - snprintf(options,10,"wb%d",compression); + snprintf(options, 10, "wb%d", compression); gzFile gzfile; - gzfile=gzopen(filename,options); - if (gzfile==NULL) return(-1); - gzputs(gzfile,xmldata); + gzfile = gzopen(filename, options); + if(gzfile == NULL) + return -1; + gzputs(gzfile, xmldata); gzclose(gzfile); - }; + } - return(0); -}; + return 0; +} -void XMLwrapper::addpar(const string &name,int val) +void XMLwrapper::addpar(const string &name, int val) { - addparams2("par","name",name.c_str(),"value",int2str(val)); -}; + addparams("par", 2, "name", name.c_str(), "value", stringFrom( + val).c_str()); +} -void XMLwrapper::addparreal(const string &name,REALTYPE val) +void XMLwrapper::addparreal(const string &name, REALTYPE val) { - addparams2("par_real","name",name.c_str(),"value",real2str(val)); -}; + addparams("par_real", 2, "name", name.c_str(), "value", + stringFrom(val).c_str()); +} -void XMLwrapper::addparbool(const string &name,int val) +void XMLwrapper::addparbool(const string &name, int val) { - if (val!=0) addparams2("par_bool","name",name.c_str(),"value","yes"); - else addparams2("par_bool","name",name.c_str(),"value","no"); -}; + if(val != 0) + addparams("par_bool", 2, "name", name.c_str(), "value", "yes"); + else + addparams("par_bool", 2, "name", name.c_str(), "value", "no"); +} -void XMLwrapper::addparstr(const string &name,const string &val) +void XMLwrapper::addparstr(const string &name, const string &val) { - mxml_node_t *element=mxmlNewElement(node,"string"); - mxmlElementSetAttr(element,"name",name.c_str()); - mxmlNewText(element,0,val.c_str()); -}; + mxml_node_t *element = mxmlNewElement(node, "string"); + mxmlElementSetAttr(element, "name", name.c_str()); + mxmlNewText(element, 0, val.c_str()); +} void XMLwrapper::beginbranch(const string &name) { - push(node); - node=addparams0(name.c_str()); -}; + if(verbose) + cout << "beginbranch()" << name << endl; + node = addparams(name.c_str(), 0); +} -void XMLwrapper::beginbranch(const string &name,int id) +void XMLwrapper::beginbranch(const string &name, int id) { - push(node); - node=addparams1(name.c_str(),"id",int2str(id)); -}; + if(verbose) + cout << "beginbranch(" << id << ")" << name << endl; + node = addparams(name.c_str(), 1, "id", stringFrom(id).c_str()); +} void XMLwrapper::endbranch() { - node=pop(); -}; + if(verbose) + cout << "endbranch()" << node << "-" << node->value.element.name + << " To " + << node->parent << "-" << node->parent->value.element.name << endl; + node = node->parent; +} @@ -276,61 +300,71 @@ void XMLwrapper::endbranch() int XMLwrapper::loadXMLfile(const string &filename) { - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; + if(tree != NULL) + mxmlDelete(tree); + tree = NULL; - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + const char *xmldata = doloadfile(filename.c_str()); + if(xmldata == NULL) + return -1; //the file could not be loaded or uncompressed - stackpos=0; + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); - const char *xmldata=doloadfile(filename.c_str()); - if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + delete [] xmldata; - root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); - - delete []xmldata; - - if (tree==NULL) return(-2);//this is not XML + if(tree == NULL) + return -2; //this is not XML - node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data - push(root); + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return -3; //the XML doesnt embbed zynaddsubfx data - values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major")); - values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor")); + //fetch version information + version.Major = stringTo(mxmlElementGetAttr(root, "version-major")); + version.Minor = stringTo(mxmlElementGetAttr(root, "version-minor")); + version.Revision = + stringTo(mxmlElementGetAttr(root, "version-revision")); - return(0); -}; + if(verbose) + cout << "loadXMLfile() version: " << version.Major << '.' + << version.Minor << '.' << version.Revision << endl; -char *XMLwrapper::doloadfile(const string &filename) + return 0; +} + + +char *XMLwrapper::doloadfile(const string &filename) const { - char * xmldata = NULL; - gzFile gzfile = gzopen(filename.c_str(),"rb"); - - if (gzfile != NULL) {//The possibly compressed file opened + char *xmldata = NULL; + gzFile gzfile = gzopen(filename.c_str(), "rb"); + if(gzfile != NULL) { //The possibly compressed file opened stringstream strBuf; //reading stream const int bufSize = 500; //fetch size - char fetchBuf[bufSize+1];//fetch buffer - int read = 0; //chars read in last fetch + char fetchBuf[bufSize + 1]; //fetch buffer + int read = 0; //chars read in last fetch - fetchBuf[bufSize] = 0;//force null termination + fetchBuf[bufSize] = 0; //force null termination while(bufSize == (read = gzread(gzfile, fetchBuf, bufSize))) strBuf << fetchBuf; - fetchBuf[read] = 0;//Truncate last partial read + fetchBuf[read] = 0; //Truncate last partial read strBuf << fetchBuf; gzclose(gzfile); //Place data in output format string tmp = strBuf.str(); - xmldata = new char[tmp.size()+1]; - strncpy(xmldata, tmp.c_str(), tmp.size()+1); + xmldata = new char[tmp.size() + 1]; + strncpy(xmldata, tmp.c_str(), tmp.size() + 1); } return xmldata; @@ -338,218 +372,246 @@ char *XMLwrapper::doloadfile(const string &filename) bool XMLwrapper::putXMLdata(const char *xmldata) { - if (tree!=NULL) mxmlDelete(tree); - tree=NULL; + if(tree != NULL) + mxmlDelete(tree); - ZERO(&parentstack,(int)sizeof(parentstack)); - ZERO(&values,(int)sizeof(values)); + tree = NULL; + if(xmldata == NULL) + return false; - stackpos=0; + root = tree = mxmlLoadString(NULL, xmldata, MXML_OPAQUE_CALLBACK); + if(tree == NULL) + return false; - if (xmldata==NULL) return (false); + node = root = mxmlFindElement(tree, + tree, + "ZynAddSubFX-data", + NULL, + NULL, + MXML_DESCEND); + if(root == NULL) + return false; - root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); - - if (tree==NULL) return(false); - - node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); - if (root==NULL) return (false);; - push(root); - - return(true); -}; + return true; +} int XMLwrapper::enterbranch(const string &name) { - node=mxmlFindElement(peek(),peek(),name.c_str(),NULL,NULL,MXML_DESCEND_FIRST); - if (node==NULL) return(0); + if(verbose) + cout << "enterbranch() " << name << endl; + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), NULL, NULL, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; - push(node); - return(1); -}; + node = tmp; + return 1; +} -int XMLwrapper::enterbranch(const string &name,int id) +int XMLwrapper::enterbranch(const string &name, int id) { - snprintf(tmpstr,TMPSTR_SIZE,"%d",id); - node=mxmlFindElement(peek(),peek(),name.c_str(),"id",tmpstr,MXML_DESCEND_FIRST); - if (node==NULL) return(0); + if(verbose) + cout << "enterbranch(" << id << ") " << name << endl; + mxml_node_t *tmp = mxmlFindElement(node, node, + name.c_str(), "id", stringFrom( + id).c_str(), MXML_DESCEND_FIRST); + if(tmp == NULL) + return 0; - push(node); - return(1); -}; + node = tmp; + return 1; +} void XMLwrapper::exitbranch() { - /**@bug Does not set the current node correctly*/ - pop(); -}; + if(verbose) + cout << "exitbranch()" << node << "-" << node->value.element.name + << " To " + << node->parent << "-" << node->parent->value.element.name << endl; + node = node->parent; +} -int XMLwrapper::getbranchid(int min, int max) +int XMLwrapper::getbranchid(int min, int max) const { - int id=str2int(mxmlElementGetAttr(node,"id")); - if ((min==0)&&(max==0)) return(id); + int id = stringTo(mxmlElementGetAttr(node, "id")); + if((min == 0) && (max == 0)) + return id; - if (idmax) id=max; + if(id < min) + id = min; + else + if(id > max) + id = max; - return(id); -}; + return id; +} -int XMLwrapper::getpar(const string &name,int defaultpar,int min,int max) +int XMLwrapper::getpar(const string &name, int defaultpar, int min, + int max) const { - node=mxmlFindElement(peek(),peek(),"par","name",name.c_str(),MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - int val=str2int(strval); - if (valmax) val=max; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; - return(val); -}; + int val = stringTo(strval); + if(val < min) + val = min; + else + if(val > max) + val = max; -int XMLwrapper::getpar127(const string &name,int defaultpar) + return val; +} + +int XMLwrapper::getpar127(const string &name, int defaultpar) const { - return(getpar(name,defaultpar,0,127)); -}; + return getpar(name, defaultpar, 0, 127); +} -int XMLwrapper::getparbool(const string &name,int defaultpar) +int XMLwrapper::getparbool(const string &name, int defaultpar) const { - node=mxmlFindElement(peek(),peek(),"par_bool","name",name.c_str(),MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_bool", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if(tmp == NULL) + return defaultpar; - if ((strval[0]=='Y')||(strval[0]=='y')) return(1); - else return(0); -}; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; -void XMLwrapper::getparstr(const string &name,char *par,int maxstrlen) + if((strval[0] == 'Y') || (strval[0] == 'y')) + return 1; + else + return 0; +} + +void XMLwrapper::getparstr(const string &name, char *par, int maxstrlen) const { - ZERO(par,maxstrlen); - node=mxmlFindElement(peek(),peek(),"string","name",name.c_str(),MXML_DESCEND_FIRST); + ZERO(par, maxstrlen); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - if (node==NULL) return; - if (node->child==NULL) return; - if (node->child->type!=MXML_OPAQUE) return; + if(tmp == NULL) + return; + if(tmp->child == NULL) + return; + if(tmp->child->type == MXML_OPAQUE) { + snprintf(par, maxstrlen, "%s", tmp->child->value.element.name); + return; + } + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) { + snprintf(par, maxstrlen, "%s", tmp->child->value.text.string); + return; + } +} - snprintf(par,maxstrlen,"%s",node->child->value.element.name); - -}; - -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar) +string XMLwrapper::getparstr(const string &name, + const std::string &defaultpar) const { - node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST); - if (node==NULL) return(defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "string", + "name", + name.c_str(), + MXML_DESCEND_FIRST); - const char *strval=mxmlElementGetAttr(node,"value"); - if (strval==NULL) return(defaultpar); + if((tmp == NULL) || (tmp->child == NULL)) + return defaultpar; - return(str2real(strval)); -}; + if((tmp->child->type == MXML_OPAQUE) + && (tmp->child->value.element.name != NULL)) + return tmp->child->value.element.name; -REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max) + if((tmp->child->type == MXML_TEXT) + && (tmp->child->value.text.string != NULL)) + return tmp->child->value.text.string; + + return defaultpar; +} + +REALTYPE XMLwrapper::getparreal(const char *name, REALTYPE defaultpar) const { - REALTYPE result=getparreal(name,defaultpar); + const mxml_node_t *tmp = mxmlFindElement(node, + node, + "par_real", + "name", + name, + MXML_DESCEND_FIRST); + if(tmp == NULL) + return defaultpar; - if (resultmax) result=max; - return(result); -}; + const char *strval = mxmlElementGetAttr(tmp, "value"); + if(strval == NULL) + return defaultpar; + + return stringTo(strval); +} + +REALTYPE XMLwrapper::getparreal(const char *name, + REALTYPE defaultpar, + REALTYPE min, + REALTYPE max) const +{ + REALTYPE result = getparreal(name, defaultpar); + + if(result < min) + result = min; + else + if(result > max) + result = max; + return result; +} /** Private members **/ -char *XMLwrapper::int2str(int x) +mxml_node_t *XMLwrapper::addparams(const char *name, unsigned int params, + ...) const { - snprintf(tmpstr,TMPSTR_SIZE,"%d",x); - return(tmpstr); -}; - -char *XMLwrapper::real2str(REALTYPE x) -{ - snprintf(tmpstr,TMPSTR_SIZE,"%g",x); - return(tmpstr); -}; - -int XMLwrapper::str2int(const char *str) -{ - if (str==NULL) return(0); - int result=strtol(str,NULL,10); - return(result); -}; - -REALTYPE XMLwrapper::str2real(const char *str) -{ - if (str==NULL) return(0.0); - REALTYPE result=strtod(str,NULL); - return(result); -}; - - -mxml_node_t *XMLwrapper::addparams0(const char *name) -{ - mxml_node_t *element=mxmlNewElement(node,name); - return(element); -}; - -mxml_node_t *XMLwrapper::addparams1(const char *name,const char *par1,const char *val1) -{ - mxml_node_t *element=mxmlNewElement(node,name); - mxmlElementSetAttr(element,par1,val1); - return(element); -}; - -mxml_node_t *XMLwrapper::addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2) -{ - mxml_node_t *element=mxmlNewElement(node,name); - mxmlElementSetAttr(element,par1,val1); - mxmlElementSetAttr(element,par2,val2); - return(element); -}; - -void XMLwrapper::push(mxml_node_t *node) -{ - if (stackpos>=STACKSIZE-1) { - cerr << "BUG!: XMLwrapper::push() - full parentstack" << endl; - return; - }; - stackpos++; - parentstack[stackpos]=node; - -// printf("push %d - %s\n",stackpos,node->value.element.name); - -}; -mxml_node_t *XMLwrapper::pop() -{ - if (stackpos<=0) { - cerr << "BUG!: XMLwrapper::pop() - empty parentstack" << endl; - return (root); - }; - mxml_node_t *node=parentstack[stackpos]; - parentstack[stackpos]=NULL; - -// printf("pop %d - %s\n",stackpos,node->value.element.name); - - stackpos--; - return(node); -}; - -mxml_node_t *XMLwrapper::peek() -{ - if (stackpos<=0) { - cerr << "BUG!: XMLwrapper::peek() - empty parentstack" << endl; - return (root); - }; - return(parentstack[stackpos]); -}; + /**@todo make this function send out a good error message if something goes + * wrong**/ + mxml_node_t *element = mxmlNewElement(node, name); + if(params) { + va_list variableList; + va_start(variableList, params); + const char *ParamName; + const char *ParamValue; + while(params--) { + ParamName = va_arg(variableList, const char *); + ParamValue = va_arg(variableList, const char *); + if(verbose) + cout << "addparams()[" << params << "]=" << name << " " + << ParamName << "=\"" << ParamValue << "\"" << endl; + mxmlElementSetAttr(element, ParamName, ParamValue); + } + } + return element; +} diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h index ccf875de6..5860f0764 100644 --- a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h @@ -31,287 +31,242 @@ #ifndef XML_WRAPPER_H #define XML_WRAPPER_H -#define TMPSTR_SIZE 50 - -//the maxim tree depth -#define STACKSIZE 100 - /**Mxml wrapper*/ class XMLwrapper { -public: - /** - * Constructor. - * Will Construct the object and fill in top level branch - * */ - XMLwrapper(); + public: + /** + * Constructor. + * Will Construct the object and fill in top level branch + * */ + XMLwrapper(); - /**Destructor*/ - ~XMLwrapper(); + /**Destructor*/ + ~XMLwrapper(); - /** - * Saves the XML to a file. - * @param filename the name of the destination file. - * @returns 0 if ok or -1 if the file cannot be saved. - */ - int saveXMLfile(const std::string &filename); + /** + * Saves the XML to a file. + * @param filename the name of the destination file. + * @returns 0 if ok or -1 if the file cannot be saved. + */ + int saveXMLfile(const std::string &filename) const; - /** - * Return XML tree as a string. - * Note: The string must be freed with free() to deallocate - * @returns a newly allocated NULL terminated string of the XML data. - */ - char *getXMLdata(); + /** + * Return XML tree as a string. + * Note: The string must be freed with free() to deallocate + * @returns a newly allocated NULL terminated string of the XML data. + */ + char *getXMLdata() const; - /** - * Add simple parameter. - * @param name The name of the mXML node. - * @param val The string value of the mXml node - */ - void addpar(const std::string &name,int val); + /** + * Add simple parameter. + * @param name The name of the mXML node. + * @param val The string value of the mXml node + */ + void addpar(const std::string &name, int val); - /** - * Adds a realtype parameter. - * @param name The name of the mXML node. - * @param val The REALTYPE value of the node. - */ - void addparreal(const std::string &name,REALTYPE val); + /** + * Adds a realtype parameter. + * @param name The name of the mXML node. + * @param val The REALTYPE value of the node. + */ + void addparreal(const std::string &name, REALTYPE val); - /** - * Add boolean parameter. - * \todo Fix this reverse boolean logic. - * @param name The name of the mXML node. - * @param val The boolean value of the node (0->"yes";else->"no"). - */ - void addparbool(const std::string &name,int val); + /** + * Add boolean parameter. + * \todo Fix this reverse boolean logic. + * @param name The name of the mXML node. + * @param val The boolean value of the node (0->"yes";else->"no"). + */ + void addparbool(const std::string &name, int val); - /** - * Add string parameter. - * @param name The name of the mXML node. - * @param val The string value of the node. - */ - void addparstr(const std::string &name,const std::string &val); + /** + * Add string parameter. + * @param name The name of the mXML node. + * @param val The string value of the node. + */ + void addparstr(const std::string &name, const std::string &val); - /** - * Create a new branch. - * @param name Name of new branch - * @see void endbranch() - */ - void beginbranch(const std::string &name); - /** - * Create a new branch. - * @param name Name of new branch - * @param id "id" value of branch - * @see void endbranch() - */ - void beginbranch(const std::string &name, int id); + /** + * Create a new branch. + * @param name Name of new branch + * @see void endbranch() + */ + void beginbranch(const std::string &name); + /** + * Create a new branch. + * @param name Name of new branch + * @param id "id" value of branch + * @see void endbranch() + */ + void beginbranch(const std::string &name, int id); - /**Closes new branches. - * This must be called to exit each branch created by beginbranch( ). - * @see void beginbranch(const std::string &name) - * @see void beginbranch(const std::string &name, int id) - */ - void endbranch(); + /**Closes new branches. + * This must be called to exit each branch created by beginbranch( ). + * @see void beginbranch(const std::string &name) + * @see void beginbranch(const std::string &name, int id) + */ + void endbranch(); - /** - * Loads file into XMLwrapper. - * @param filename file to be loaded - * @returns 0 if ok or -1 if the file cannot be loaded - */ - int loadXMLfile(const std::string &filename); + /** + * Loads file into XMLwrapper. + * @param filename file to be loaded + * @returns 0 if ok or -1 if the file cannot be loaded + */ + int loadXMLfile(const std::string &filename); - /** - * Loads string into XMLwrapper. - * @param xmldata NULL terminated string of XML data. - * @returns true if successful. - */ - bool putXMLdata(const char *xmldata); + /** + * Loads string into XMLwrapper. + * @param xmldata NULL terminated string of XML data. + * @returns true if successful. + */ + bool putXMLdata(const char *xmldata); - /** - * Enters the branch. - * @param name Name of branch. - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name); + /** + * Enters the branch. + * @param name Name of branch. + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name); - /** - * Enter into the branch \c name with id \c id. - * @param name Name of branch. - * @param id Value of branch's "id". - * @returns 1 if is ok, or 0 otherwise. - */ - int enterbranch(const std::string &name, int id); + /** + * Enter into the branch \c name with id \c id. + * @param name Name of branch. + * @param id Value of branch's "id". + * @returns 1 if is ok, or 0 otherwise. + */ + int enterbranch(const std::string &name, int id); - /**Exits from a branch*/ - void exitbranch(); + /**Exits from a branch*/ + void exitbranch(); - /**Get the the branch_id and limits it between the min and max. - * if min==max==0, it will not limit it - * if there isn't any id, will return min - * this must be called only imediately after enterbranch() - */ - int getbranchid(int min, int max); + /**Get the the branch_id and limits it between the min and max. + * if min==max==0, it will not limit it + * if there isn't any id, will return min + * this must be called only imediately after enterbranch() + */ + int getbranchid(int min, int max) const; - /** - * Returns the integer value stored in node name. - * It returns the integer value between the limits min and max. - * If min==max==0, then the value will not be limited. - * If there is no location named name, then defaultpar will be returned. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum return value. - * @param max The maximum return value. - */ - int getpar(const std::string &name,int defaultpar,int min,int max); + /** + * Returns the integer value stored in node name. + * It returns the integer value between the limits min and max. + * If min==max==0, then the value will not be limited. + * If there is no location named name, then defaultpar will be returned. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + * @param min The minimum return value. + * @param max The maximum return value. + */ + int getpar(const std::string &name, int defaultpar, int min, + int max) const; - /** - * Returns the integer value stored in the node with range [0,127]. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getpar127(const std::string &name,int defaultpar); + /** + * Returns the integer value stored in the node with range [0,127]. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getpar127(const std::string &name, int defaultpar) const; - /** - * Returns the boolean value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - int getparbool(const std::string &name,int defaultpar); + /** + * Returns the boolean value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + int getparbool(const std::string &name, int defaultpar) const; - /** - * Get the string value stored in the node. - * @param name The parameter name. - * @param par Pointer to destination string - * @param maxstrlen Max string length for destination - */ - void getparstr(const std::string &name,char *par,int maxstrlen); + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param par Pointer to destination string + * @param maxstrlen Max string length for destination + */ + void getparstr(const std::string &name, char *par, int maxstrlen) const; - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar); + /** + * Get the string value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + std::string getparstr(const std::string &name, + const std::string &defaultpar) const; - /** - * Returns the real value stored in the node. - * @param name The parameter name. - * @param defaultpar The default value if the real value is not found. - * @param min The minimum value - * @param max The maximum value - */ - REALTYPE getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max); + /** + * Returns the real value stored in the node. + * @param name The parameter name. + * @param defaultpar The default value if the real value is not found. + */ + REALTYPE getparreal(const char *name, REALTYPE defaultpar) const; - bool minimal;/** + * + * @param name The name of the xml node + * @param params The number of the attributes + * @param ... const char * pairs that are in the format attribute_name, + * attribute_value + */ + mxml_node_t *addparams(const char *name, unsigned int params, + ...) const; - /** - * Adds params like this: - * . - * @returns The node - */ - mxml_node_t *addparams0(const char *name); - - /** - * Adds params like this: - * . - * @returns The node - */ - mxml_node_t *addparams1(const char *name,const char *par1,const char *val1); - - /** - * Adds params like this: - * . - * @returns the node - */ - mxml_node_t *addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2); - - /** - * Convert integer to string - * @param x integer input - * @returns string output - */ - char *int2str(int x); - - /** - * Convert integer to string - * @param x integer input - * @returns string output - */ - char *real2str(REALTYPE x); - - /** - * Convert string to int - * @param str string input - * @returns integer output - */ - int str2int(const char *str); - - /** - * Convert string to realtype - * @param x integer input - * @returns string output - */ - REALTYPE str2real(const char *str); - - /**Temporary string for various uses*/ - char tmpstr[TMPSTR_SIZE]; - - - /**this is used to store the parents. - * @todo Use the stack class provided by C++*/ - mxml_node_t *parentstack[STACKSIZE]; - int stackpos;/**outl = data; break; @@ -58,7 +58,7 @@ static void connectPortTS(LADSPA_Handle instance, unsigned long port, const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) { - switch (index) { + switch(index) { case 0: return tsLDescriptor; default: @@ -71,7 +71,7 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) // FILE *a=fopen("/tmp/zzzzz11z","w"); // fprintf(a,"aaaaaaaaaaa TEST\n"); // fclose(a); - switch (index) { + switch(index) { case 0: return tsDDescriptor; default: @@ -79,14 +79,13 @@ const DSSI_Descriptor *dssi_descriptor(unsigned long index) } } -static LADSPA_Handle instantiateTS(const LADSPA_Descriptor * descriptor, +static LADSPA_Handle instantiateTS(const LADSPA_Descriptor *descriptor, unsigned long s_rate) { - TS *plugin_data = (TS *) malloc(sizeof(TS)); /* for (i=0; iomega[i] = M_PI * 2.0 / (double)s_rate * - pow(2.0, (i-69.0) / 12.0); + plugin_data->omega[i] = M_PI * 2.0 / (double)s_rate * + pow(2.0, (i-69.0) / 12.0); } */ return (LADSPA_Handle) plugin_data; @@ -115,47 +114,47 @@ static void runTS(LADSPA_Handle instance, unsigned long sample_count, unsigned long note; /* if (freq < 1.0) { - freq = 440.0f; + freq = 440.0f; } if (vol < 0.000001) { - vol = 1.0f; + vol = 1.0f; } if (event_count > 0) { - printf("trivial_synth: have %ld events\n", event_count); + printf("trivial_synth: have %ld events\n", event_count); } for (pos = 0, event_pos = 0; pos < sample_count; pos++) { - while (event_pos < event_count - && pos == events[event_pos].time.tick) { + while (event_pos < event_count + && pos == events[event_pos].time.tick) { - printf("trivial_synth: event type %d\n", events[event_pos].type); + printf("trivial_synth: event type %d\n", events[event_pos].type); - if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { - data[events[event_pos].data.note.note].amp = - events[event_pos].data.note.velocity / 512.0f; - data[events[event_pos].data.note.note]. - active = events[event_pos].data.note.velocity > 0; - data[events[event_pos].data.note.note]. - phase = 0.0; - } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { - data[events[event_pos].data.note.note]. - active = 0; - } - event_pos++; - } + if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { + data[events[event_pos].data.note.note].amp = + events[event_pos].data.note.velocity / 512.0f; + data[events[event_pos].data.note.note]. + active = events[event_pos].data.note.velocity > 0; + data[events[event_pos].data.note.note]. + phase = 0.0; + } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { + data[events[event_pos].data.note.note]. + active = 0; + } + event_pos++; + } - output[pos] = 0.0f; - for (note = 0; note < MIDI_NOTES; note++) { - if (data[note].active) { - output[pos] += sin(data[note].phase) * data[note].amp * vol; - data[note].phase += plugin_data->omega[note] * freq; - if (data[note].phase > M_PI * 2.0) { - data[note].phase -= M_PI * 2.0; - } - } - } + output[pos] = 0.0f; + for (note = 0; note < MIDI_NOTES; note++) { + if (data[note].active) { + output[pos] += sin(data[note].phase) * data[note].amp * vol; + data[note].phase += plugin_data->omega[note] * freq; + if (data[note].phase > M_PI * 2.0) { + data[note].phase -= M_PI * 2.0; + } + } + } } */ } @@ -176,22 +175,23 @@ void _init() { char **port_names; LADSPA_PortDescriptor *port_descriptors; - LADSPA_PortRangeHint *port_range_hints; + LADSPA_PortRangeHint *port_range_hints; - FILE *a=fopen("/tmp/zzzzzz","w"); - fprintf(a,"aaaaaaaaaaa TEST\n"); + FILE *a = fopen("/tmp/zzzzzz", "w"); + fprintf(a, "aaaaaaaaaaa TEST\n"); fclose(a); tsLDescriptor = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor)); - if (tsLDescriptor) { - tsLDescriptor->UniqueID = 100; - tsLDescriptor->Label = "ZASF"; + if(tsLDescriptor) { + tsLDescriptor->UniqueID = 100; + tsLDescriptor->Label = "ZASF"; tsLDescriptor->Properties = 0; tsLDescriptor->Name = "ZynAddSubFX"; - tsLDescriptor->Maker = "Nasca Octavian Paul "; - tsLDescriptor->Copyright = "GNU General Public License v.2"; - tsLDescriptor->PortCount = 2; + tsLDescriptor->Maker = + "Nasca Octavian Paul "; + tsLDescriptor->Copyright = "GNU General Public License v.2"; + tsLDescriptor->PortCount = 2; port_descriptors = (LADSPA_PortDescriptor *) calloc(tsLDescriptor->PortCount, sizeof @@ -208,42 +208,40 @@ void _init() port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *)); tsLDescriptor->PortNames = (const char **) port_names; - port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[0] = "Output L"; port_range_hints[0].HintDescriptor = 0; port_descriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; port_names[1] = "Output R"; port_range_hints[1].HintDescriptor = 0; - tsLDescriptor->activate = activateTS; - tsLDescriptor->cleanup = cleanupTS; + tsLDescriptor->activate = activateTS; + tsLDescriptor->cleanup = cleanupTS; tsLDescriptor->connect_port = connectPortTS; - tsLDescriptor->deactivate = NULL; - tsLDescriptor->instantiate = instantiateTS; + tsLDescriptor->deactivate = NULL; + tsLDescriptor->instantiate = instantiateTS; tsLDescriptor->run = runTSWrapper; - tsLDescriptor->run_adding = NULL; + tsLDescriptor->run_adding = NULL; tsLDescriptor->set_run_adding_gain = NULL; } tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor)); - if (tsDDescriptor) { - tsDDescriptor->DSSI_API_Version = 1; - tsDDescriptor->LADSPA_Plugin = tsLDescriptor; + if(tsDDescriptor) { + tsDDescriptor->DSSI_API_Version = 1; + tsDDescriptor->LADSPA_Plugin = tsLDescriptor; tsDDescriptor->configure = NULL; - tsDDescriptor->get_program = NULL; + tsDDescriptor->get_program = NULL; tsDDescriptor->get_midi_controller_for_port = getControllerTS; - tsDDescriptor->select_program = NULL; + tsDDescriptor->select_program = NULL; tsDDescriptor->run_synth = runTS; - tsDDescriptor->run_synth_adding = NULL; + tsDDescriptor->run_synth_adding = NULL; tsDDescriptor->run_multiple_synths = NULL; tsDDescriptor->run_multiple_synths_adding = NULL; } - -}; +} void _fini() -{ -}; +{} @@ -272,17 +270,18 @@ long int VSTSynth::canDo(char *txt){ }; bool VSTSynth::getVendorString(char *txt){ - strcpy(txt,"Nasca O. Paul"); - return(true); + strcpy(txt,"Nasca O. Paul"); + return(true); }; bool VSTSynth::getProductString(char *txt){ - strcpy(txt,"ZynAddSubFX"); - return(true); + strcpy(txt,"ZynAddSubFX"); + return(true); }; void VSTSynth::resume(){ - wantEvents(); + wantEvents(); }; */ + diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h index 6ca808fbf..a2ecf3c55 100644 --- a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h @@ -34,25 +34,25 @@ /* class VSTSynth:public AudioEffectX{ public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); + VSTSynth (audioMasterCallback audioMaster); + ~VSTSynth(); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + virtual void process (float **inputs, float **outputs, long sampleframes); + virtual void processReplacing (float **inputs, float **outputs, long sampleframes); + virtual long processEvents(VstEvents *events);//this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); - virtual long getChunk(void** data,bool isPreset=false); - virtual void setChunk(void *data,long size,bool isPreset=false); + virtual long getChunk(void** data,bool isPreset=false); + virtual void setChunk(void *data,long size,bool isPreset=false); - MasterUI *ui; - int Pexitprogram; + MasterUI *ui; + int Pexitprogram; Master *vmaster; - pthread_t thr; + pthread_t thr; }; */ #endif diff --git a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp index ca568e08b..2ee019d1c 100644 --- a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.cpp @@ -33,174 +33,197 @@ extern "C" #include "JACKaudiooutput.h" Master *jackmaster; -jack_client_t *jackclient; -jack_port_t *outport_left,*outport_right; -jack_ringbuffer_t *rb=NULL; +jack_client_t *jackclient; +jack_port_t *outport_left, *outport_right; +jack_ringbuffer_t *rb = NULL; -REALTYPE *jackoutl,*jackoutr; -int jackfinish=0; +REALTYPE *jackoutl, *jackoutr; +int jackfinish = 0; void *thread_blocked(void *arg); -int jackprocess(jack_nframes_t nframes,void *arg); -int jacksrate(jack_nframes_t nframes,void *arg); +int jackprocess(jack_nframes_t nframes, void *arg); +int jacksrate(jack_nframes_t nframes, void *arg); void jackshutdown(void *arg); -pthread_cond_t more_data=PTHREAD_COND_INITIALIZER; -pthread_mutex_t zyn_thread_lock=PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t more_data = PTHREAD_COND_INITIALIZER; +pthread_mutex_t zyn_thread_lock = PTHREAD_MUTEX_INITIALIZER; pthread_t bthr; bool JACKaudiooutputinit(Master *master_) { - jackmaster=master_; - jackclient=0; + jackmaster = master_; + jackclient = 0; char tmpstr[100]; - jackoutl=new REALTYPE [SOUND_BUFFER_SIZE]; - jackoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutl = new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutr = new REALTYPE [SOUND_BUFFER_SIZE]; - int rbbufsize=SOUND_BUFFER_SIZE*sizeof (REALTYPE)*2*2; - printf("%d\n",rbbufsize); - rb=jack_ringbuffer_create(rbbufsize); - for (int i=0;ibuf[i]=0.0; + int rbbufsize = SOUND_BUFFER_SIZE * sizeof(REALTYPE) * 2 * 2; + printf("%d\n", rbbufsize); + rb = jack_ringbuffer_create(rbbufsize); + for(int i = 0; i < rbbufsize; i++) + rb->buf[i] = 0.0; - for (int i=0;i<15;i++) { - if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i); - else snprintf(tmpstr,100,"ZynAddSubFX"); - jackclient=jack_client_new(tmpstr); - if (jackclient!=0) break; - }; + for(int i = 0; i < 15; i++) { + if(i != 0) + snprintf(tmpstr, 100, "ZynAddSubFX_%d", i); + else + snprintf(tmpstr, 100, "ZynAddSubFX"); + jackclient = jack_client_new(tmpstr); + if(jackclient != 0) + break; + } - if (jackclient==0) { - fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); - return(false); - }; + if(jackclient == 0) { + fprintf( + stderr, + "\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); + return false; + } - fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); - if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) - fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); + fprintf(stderr, + "Internal SampleRate = %d\nJack Output SampleRate= %d\n", + SAMPLE_RATE, + jack_get_sample_rate(jackclient)); + if((unsigned int)jack_get_sample_rate(jackclient) != + (unsigned int) SAMPLE_RATE) + fprintf(stderr, + "It is recomanded that the both samplerates to be equal.\n"); - jack_set_process_callback(jackclient,jackprocess,0); - jack_set_sample_rate_callback(jackclient,jacksrate,0); - jack_on_shutdown(jackclient,jackshutdown,0); + jack_set_process_callback(jackclient, jackprocess, 0); + jack_set_sample_rate_callback(jackclient, jacksrate, 0); + jack_on_shutdown(jackclient, jackshutdown, 0); - outport_left=jack_port_register(jackclient,"out_1", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); - outport_right=jack_port_register(jackclient,"out_2", - JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + outport_left = jack_port_register(jackclient, + "out_1", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); + outport_right = jack_port_register(jackclient, + "out_2", + JACK_DEFAULT_AUDIO_TYPE, + JackPortIsOutput | JackPortIsTerminal, + 0); - if (jack_activate(jackclient)) { - fprintf(stderr,"Cannot activate jack client\n"); - return(false); - }; + if(jack_activate(jackclient)) { + fprintf(stderr, "Cannot activate jack client\n"); + return false; + } - pthread_create(&bthr,NULL,thread_blocked,NULL); + pthread_create(&bthr, NULL, thread_blocked, NULL); /* jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); */ - return(true); -}; + return true; +} void *thread_blocked(void *arg) { - int datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); + int datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); //try to get realtime sched_param sc; - sc.sched_priority=50; - int err=sched_setscheduler(0,SCHED_FIFO,&sc); + sc.sched_priority = 50; + int err = sched_setscheduler(0, SCHED_FIFO, &sc); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); pthread_mutex_lock(&zyn_thread_lock); - while (jackfinish==0) { - while (jack_ringbuffer_write_space(rb)>=datasize) { + while(jackfinish == 0) { + while(jack_ringbuffer_write_space(rb) >= datasize) { pthread_mutex_lock(&jackmaster->mutex); - jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,jack_get_sample_rate(jackclient),jackoutl,jackoutr); + jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, + jack_get_sample_rate(jackclient), + jackoutl, + jackoutr); pthread_mutex_unlock(&jackmaster->mutex); - jack_ringbuffer_write(rb, (char *) jackoutl,datasize); - jack_ringbuffer_write(rb, (char *) jackoutr,datasize); - }; - pthread_cond_wait(&more_data,&zyn_thread_lock); - }; + jack_ringbuffer_write(rb, (char *) jackoutl, datasize); + jack_ringbuffer_write(rb, (char *) jackoutr, datasize); + } + pthread_cond_wait(&more_data, &zyn_thread_lock); + } pthread_mutex_unlock(&zyn_thread_lock); - return(0); -}; + return 0; +} -int jackprocess(jack_nframes_t nframes,void *arg) +int jackprocess(jack_nframes_t nframes, void *arg) { - jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); - jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); + jack_default_audio_sample_t *outl = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_left, + nframes); + jack_default_audio_sample_t *outr = + (jack_default_audio_sample_t *) jack_port_get_buffer(outport_right, + nframes); - int datasize=nframes*sizeof (REALTYPE); - int incoming_datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); - int data_read=0; + int datasize = nframes * sizeof(REALTYPE); + int incoming_datasize = SOUND_BUFFER_SIZE * sizeof(REALTYPE); + int data_read = 0; - if (jack_ringbuffer_read_space(rb)>=(2*incoming_datasize)) { - if (datasize>incoming_datasize) { - data_read=0; - while (data_read < datasize) { - jack_ringbuffer_read(rb, (char *) outl+data_read,datasize); - jack_ringbuffer_read(rb, (char *) outr+data_read,datasize); - data_read+=incoming_datasize; - }; - } else if (datasize==incoming_datasize) { - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); - } else { - }; - } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;i= (2 * incoming_datasize)) { + if(datasize > incoming_datasize) { + data_read = 0; + while(data_read < datasize) { + jack_ringbuffer_read(rb, (char *) outl + data_read, datasize); + jack_ringbuffer_read(rb, (char *) outr + data_read, datasize); + data_read += incoming_datasize; + } + } + else + if(datasize == incoming_datasize) { + jack_ringbuffer_read(rb, (char *) outl, datasize); + jack_ringbuffer_read(rb, (char *) outr, datasize); + } + else {} + } + else { //the ringbuffer is empty or there are too small amount of samples in it + for(int i = 0; i < nframes; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + } /* if (jack_ringbuffer_read_space(rb)>=datasize){ - jack_ringbuffer_read(rb, (char *) outl,datasize); - jack_ringbuffer_read(rb, (char *) outr,datasize); + jack_ringbuffer_read(rb, (char *) outl,datasize); + jack_ringbuffer_read(rb, (char *) outr,datasize); } else {//the ringbuffer is empty or there are too small amount of samples in it - for (int i=0;imutex)) { + if(!pthread_mutex_trylock(&jackmaster->mutex)) { JACKhandlemidi(nframes); - jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr); + jackmaster->GetAudioOutSamples(nframes, jack_get_sample_rate( + jackclient), outl, outr); pthread_mutex_unlock(&jackmaster->mutex); - } else { + } + else { memset(outl, 0, sizeof(jack_default_audio_sample_t) * nframes); memset(outr, 0, sizeof(jack_default_audio_sample_t) * nframes); } - return(0); -}; + return 0; +} void JACKfinish() { jack_client_close(jackclient); -}; +} -int jacksrate(jack_nframes_t nframes,void *arg) +int jacksrate(jack_nframes_t nframes, void *arg) { - - return(0); -}; + return 0; +} void jackshutdown(void *arg) -{ -}; +{} void JACKhandlemidi(unsigned long frames) { - // We must have the master mutex before we run this function // XXX This is really nasty, not only do we lose the sample accuracy of // JACK MIDI, but any accuracy at all below the buffer size - void* midi_buf = jack_port_get_buffer(midi_inport, frames); + void *midi_buf = jack_port_get_buffer(midi_inport, frames); jack_midi_event_t jack_midi_event; - jack_nframes_t event_index = 0; - unsigned char* midi_data; - unsigned char type, chan; + jack_nframes_t event_index = 0; + unsigned char *midi_data; + unsigned char type, chan; - while (jack_midi_event_get(&jack_midi_event,midi_buf, event_index++) == 0) { + while(jack_midi_event_get(&jack_midi_event, midi_buf, + event_index++) == 0) { midi_data = jack_midi_event.buffer; - type = midi_data[0] & 0xF0; - chan = midi_data[0] & 0x0F; - - switch (type) { + type = midi_data[0] & 0xF0; + chan = midi_data[0] & 0x0F; + switch(type) { case 0x80: /* note-off */ jackmaster->NoteOff(chan, midi_data[1]); break; @@ -151,13 +173,13 @@ void JACKhandlemidi(unsigned long frames) /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */ } } - } -const char* JACKgetname() +const char *JACKgetname() { - if (jackclient != NULL) + if(jackclient != NULL) return jackname; return NULL; } + diff --git a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h index 7061f8c16..afc5e5b7f 100644 --- a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h @@ -28,11 +28,12 @@ #include "../Misc/Master.h" -#if (REALTYPE!=jack_default_audio_sample_t) -#error "The internal sample datatype of ZynAddSubFX and the datatype of jack differs.\ - In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal.\ - Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ - in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." +#if (REALTYPE != jack_default_audio_sample_t) +#error \ + "The internal sample datatype of ZynAddSubFX and the datatype of jack differs. \ + In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal. \ + Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ + in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." #endif @@ -41,7 +42,7 @@ bool JACKaudiooutputinit(Master *master_); void JACKfinish(); void JACKhandlemidi(unsigned long frames); -const char* JACKgetname(); +const char *JACKgetname(); #endif diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp index d10d32c96..ad77573af 100644 --- a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.cpp @@ -37,60 +37,92 @@ using namespace std; OSSaudiooutput::OSSaudiooutput() { int i; - int snd_bitsize=16; - snd_fragment=0x00080009;//fragment size (?) - snd_stereo=1;//stereo - snd_format=AFMT_S16_LE; - snd_samplerate=SAMPLE_RATE; + int snd_bitsize = 16; + snd_fragment = 0x00080009; //fragment size (?) + snd_stereo = 1; //stereo + snd_format = AFMT_S16_LE; + snd_samplerate = SAMPLE_RATE; + playing_until.tv_sec = 0; + playing_until.tv_usec = 0; - smps=new short int[SOUND_BUFFER_SIZE*2]; - for (i=0;i 10000) //Don't sleep() less than 10ms. + //This will add latency... + usleep(remaining - 10000); + if(remaining < 0) + cerr << "WARNING - too late" << endl; + } + playing_until.tv_usec += SOUND_BUFFER_SIZE * 1000000 / SAMPLE_RATE; + if(remaining < 0) + playing_until.tv_usec -= remaining; + playing_until.tv_sec += playing_until.tv_usec / 1000000; + playing_until.tv_usec %= 1000000; + return; + } - if (l<-1.0) l=-1.0; - else if (l>1.0) l=1.0; - if (r<-1.0) r=-1.0; - else if (r>1.0) r=1.0; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + l = smp_left[i]; + r = smp_right[i]; - smps[i*2]=(short int) (l*32767.0); - smps[i*2+1]=(short int) (r*32767.0); - }; - write(snd_handle,smps,SOUND_BUFFER_SIZE*4);// *2 because is 16 bit, again * 2 because is stereo -}; + if(l < -1.0) + l = -1.0; + else + if(l > 1.0) + l = 1.0; + if(r < -1.0) + r = -1.0; + else + if(r > 1.0) + r = 1.0; + + smps[i * 2] = (short int) (l * 32767.0); + smps[i * 2 + 1] = (short int) (r * 32767.0); + } + write(snd_handle, smps, SOUND_BUFFER_SIZE * 4); // *2 because is 16 bit, again * 2 because is stereo +} OSSaudiooutput::~OSSaudiooutput() { close(snd_handle); delete [] smps; -}; +} diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h index 3f130e084..28da1cfaf 100644 --- a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h @@ -23,25 +23,27 @@ #ifndef OSS_AUDIO_OUTPUT_H #define OSS_AUDIO_OUTPUT_H +#include #include "../globals.h" class OSSaudiooutput { -public: - OSSaudiooutput(); - ~OSSaudiooutput(); + public: + OSSaudiooutput(); + ~OSSaudiooutput(); - //the out is [-1.0 .. 1.0] - /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ - void OSSout(REALTYPE *smp_left,REALTYPE *smp_right); -private: - int snd_handle; - int snd_fragment; - int snd_stereo; - int snd_format; - int snd_samplerate; + //the out is [-1.0 .. 1.0] + /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ + void OSSout(REALTYPE *smp_left, REALTYPE *smp_right); + private: + int snd_handle; + int snd_fragment; + int snd_stereo; + int snd_format; + int snd_samplerate; + struct timeval playing_until; - short int *smps;//Samples to be sent to soundcard + short int *smps; //Samples to be sent to soundcard }; #endif diff --git a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp index 161153ffd..73b346827 100644 --- a/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/PAaudiooutput.cpp @@ -22,52 +22,59 @@ #include "PAaudiooutput.h" -Master *PAmaster; +Master *PAmaster; PaStream *stream; -REALTYPE *outl,*outr; +REALTYPE *outl, *outr; -int PAprocess(void *inputBuffer,void *outputBuffer, +int PAprocess(void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, - PaTimestamp outTime,void *userData) + PaTimestamp outTime, void *userData) { - - if (framesPerBuffer!=SOUND_BUFFER_SIZE) { - fprintf(stderr,"Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); - fprintf(stderr,"%d %d\n",framesPerBuffer,SOUND_BUFFER_SIZE); - }; + if(framesPerBuffer != SOUND_BUFFER_SIZE) { + fprintf( + stderr, + "Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); + fprintf(stderr, "%d %d\n", framesPerBuffer, SOUND_BUFFER_SIZE); + } pthread_mutex_lock(&PAmaster->mutex); - PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,SAMPLE_RATE,outl,outr); + PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE, SAMPLE_RATE, outl, outr); pthread_mutex_unlock(&PAmaster->mutex); - float *out=(float *)outputBuffer; + float *out = (float *)outputBuffer; - for (int i=0;i=SOUND_BUFFER_SIZE) break;//this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE - out[i*2]=outl[i]; - out[i*2+1]=outr[i]; - }; + for(int i = 0; i < framesPerBuffer; i++) { + if(i >= SOUND_BUFFER_SIZE) + break; //this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE + out[i * 2] = outl[i]; + out[i * 2 + 1] = outr[i]; + } - return(0); -}; + return 0; +} void PAaudiooutputinit(Master *master_) { - PAmaster=master_; - outl=new REALTYPE [SOUND_BUFFER_SIZE]; - outr=new REALTYPE [SOUND_BUFFER_SIZE]; + PAmaster = master_; + outl = new REALTYPE [SOUND_BUFFER_SIZE]; + outr = new REALTYPE [SOUND_BUFFER_SIZE]; Pa_Initialize(); - Pa_OpenDefaultStream(&stream,0,2,paFloat32,SAMPLE_RATE,SOUND_BUFFER_SIZE,0,PAprocess,NULL); + Pa_OpenDefaultStream(&stream, + 0, + 2, + paFloat32, + SAMPLE_RATE, + SOUND_BUFFER_SIZE, + 0, + PAprocess, + NULL); Pa_StartStream(stream); -}; +} void PAfinish() { Pa_StopStream(stream); delete (outl); delete (outr); -}; - - - +} diff --git a/plugins/zynaddsubfx/src/Output/Recorder.cpp b/plugins/zynaddsubfx/src/Output/Recorder.cpp index 388ab7f74..43a44630e 100644 --- a/plugins/zynaddsubfx/src/Output/Recorder.cpp +++ b/plugins/zynaddsubfx/src/Output/Recorder.cpp @@ -25,80 +25,89 @@ Recorder::Recorder() { - recordbuf_16bit=new short int [SOUND_BUFFER_SIZE*2]; - status=0; - notetrigger=0; - for (int i=0;i32767) tmp=32767; - recordbuf_16bit[i*2]=tmp; + if(status != 2) + return; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + tmp = (int)(outl[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2] = tmp; - tmp=(int)(outr[i]*32767.0); - if (tmp<-32768) tmp=-32768; - if (tmp>32767) tmp=32767; - recordbuf_16bit[i*2+1]=tmp; - }; - wav.write_stereo_samples(SOUND_BUFFER_SIZE,recordbuf_16bit); -}; + tmp = (int)(outr[i] * 32767.0); + if(tmp < -32768) + tmp = -32768; + if(tmp > 32767) + tmp = 32767; + recordbuf_16bit[i * 2 + 1] = tmp; + } + wav.write_stereo_samples(SOUND_BUFFER_SIZE, recordbuf_16bit); +} void Recorder::triggernow() { - if (status==2) notetrigger=1; -}; + if(status == 2) + notetrigger = 1; +} + diff --git a/plugins/zynaddsubfx/src/Output/Recorder.h b/plugins/zynaddsubfx/src/Output/Recorder.h index 059f7108f..997ed3783 100644 --- a/plugins/zynaddsubfx/src/Output/Recorder.h +++ b/plugins/zynaddsubfx/src/Output/Recorder.h @@ -29,28 +29,29 @@ /**Records sound to a file*/ class Recorder { -public: + public: - Recorder(); - ~Recorder(); - int preparefile(std::string filename_,int overwrite);//returns 1 if the file exists - void start(); - void stop(); - void pause(); - int recording(); - void triggernow(); - void recordbuffer(REALTYPE *outl,REALTYPE *outr); + Recorder(); + ~Recorder(); + int preparefile(std::string filename_, int overwrite); //returns 1 if the file exists + void start(); + void stop(); + void pause(); + int recording(); + void triggernow(); + void recordbuffer(REALTYPE *outl, REALTYPE *outr); - /** Status: - * 0 - not ready(no file selected), - * 1 - ready - * 2 - recording */ - int status; + /** Status: + * 0 - not ready(no file selected), + * 1 - ready + * 2 - recording */ + int status; -private: - WAVaudiooutput wav; - short int *recordbuf_16bit; - int notetrigger; + private: + WAVaudiooutput wav; + short int *recordbuf_16bit; + int notetrigger; }; #endif + diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp index 6441ab092..183a3bb55 100644 --- a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.cpp @@ -24,42 +24,45 @@ //the constructor and the destructor are defined in main.C -void VSTSynth::process (float **inputs, float **outputs, long sampleframes) +void VSTSynth::process(float **inputs, float **outputs, long sampleframes) { - float *outl=outputs[0]; - float *outr=outputs[1]; + float *outl = outputs[0]; + float *outr = outputs[1]; pthread_mutex_lock(&vmaster->mutex); - vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); + vmaster->GetAudioOutSamples(sampleframes, (int) getSampleRate(), outl, outr); pthread_mutex_unlock(&vmaster->mutex); -}; +} -void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes) +void VSTSynth::processReplacing(float **inputs, + float **outputs, + long sampleframes) { - process(inputs,outputs,sampleframes); -}; + process(inputs, outputs, sampleframes); +} long int VSTSynth::canDo(char *txt) { - if (strcmp(txt,"receiveVstEvents")==0) return (1); - if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); - return(-1); -}; + if(strcmp(txt, "receiveVstEvents") == 0) + return 1; + if(strcmp(txt, "receiveVstMidiEvent") == 0) + return 1; + return -1; +} bool VSTSynth::getVendorString(char *txt) { - strcpy(txt,"Nasca O. Paul"); - return(true); -}; + strcpy(txt, "Nasca O. Paul"); + return true; +} bool VSTSynth::getProductString(char *txt) { - strcpy(txt,"ZynAddSubFX"); - return(true); -}; + strcpy(txt, "ZynAddSubFX"); + return true; +} void VSTSynth::resume() { wantEvents(); -}; - +} diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h index 116f33004..1fe0afd13 100644 --- a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h @@ -32,26 +32,28 @@ class VSTSynth:public AudioEffectX { -public: - VSTSynth (audioMasterCallback audioMaster); - ~VSTSynth(); + public: + VSTSynth(audioMasterCallback audioMaster); + ~VSTSynth(); - virtual void process (float **inputs, float **outputs, long sampleframes); - virtual void processReplacing (float **inputs, float **outputs, long sampleframes); - virtual long processEvents(VstEvents *events);//this is used for Midi input - virtual long int canDo(char *txt); - virtual bool getVendorString(char *txt); - virtual bool getProductString(char *txt); - virtual void resume(); + virtual void process(float **inputs, float **outputs, long sampleframes); + virtual void processReplacing(float **inputs, + float **outputs, + long sampleframes); + virtual long processEvents(VstEvents *events); //this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); - virtual long getChunk(void** data,bool isPreset=false); - virtual long setChunk(void *data,long size,bool isPreset=false); + virtual long getChunk(void **data, bool isPreset = false); + virtual long setChunk(void *data, long size, bool isPreset = false); - MasterUI *ui; - int Pexitprogram; + MasterUI *ui; + int Pexitprogram; - Master *vmaster; - pthread_t thr; + Master *vmaster; + pthread_t thr; }; #endif diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp index fc03243c4..cc1f87c0e 100644 --- a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.cpp @@ -23,77 +23,79 @@ using namespace std; WAVaudiooutput::WAVaudiooutput() { - file=NULL; - sampleswritten=0; - samplerate=44100; -}; + file = NULL; + sampleswritten = 0; + samplerate = 44100; +} WAVaudiooutput::~WAVaudiooutput() { close(); -}; +} -bool WAVaudiooutput::newfile(string filename,int samplerate,int channels) +bool WAVaudiooutput::newfile(string filename, int samplerate, int channels) { /**\todo Move this into the Constructor*/ - close();//inchide un posibil fisier existent - file=fopen(filename.c_str(),"w"); - if (!file) return false; - this->samplerate=samplerate; - this->channels=channels; - sampleswritten=0; + close(); //inchide un posibil fisier existent + file = fopen(filename.c_str(), "w"); + if(!file) + return false; + this->samplerate = samplerate; + this->channels = channels; + sampleswritten = 0; char tmp[44]; - fwrite(tmp,1,44,file); - return(true); -}; + fwrite(tmp, 1, 44, file); + return true; +} void WAVaudiooutput::close() { - if (file) { + if(file) { unsigned int chunksize; rewind(file); - fwrite("RIFF",4,1,file); - chunksize=sampleswritten*4+36; - fwrite(&chunksize,4,1,file); + fwrite("RIFF", 4, 1, file); + chunksize = sampleswritten * 4 + 36; + fwrite(&chunksize, 4, 1, file); - fwrite("WAVEfmt ",8,1,file); - chunksize=16; - fwrite(&chunksize,4,1,file); - unsigned short int formattag=1;//uncompresed wave - fwrite(&formattag,2,1,file); - unsigned short int nchannels=channels;//stereo - fwrite(&nchannels,2,1,file); - unsigned int samplerate_=samplerate;//samplerate - fwrite(&samplerate_,4,1,file); - unsigned int bytespersec=samplerate*2*channels;//bytes/sec - fwrite(&bytespersec,4,1,file); - unsigned short int blockalign=2*channels;//2 channels * 16 bits/8 - fwrite(&blockalign,2,1,file); - unsigned short int bitspersample=16; - fwrite(&bitspersample,2,1,file); + fwrite("WAVEfmt ", 8, 1, file); + chunksize = 16; + fwrite(&chunksize, 4, 1, file); + unsigned short int formattag = 1; //uncompresed wave + fwrite(&formattag, 2, 1, file); + unsigned short int nchannels = channels; //stereo + fwrite(&nchannels, 2, 1, file); + unsigned int samplerate_ = samplerate; //samplerate + fwrite(&samplerate_, 4, 1, file); + unsigned int bytespersec = samplerate * 2 * channels; //bytes/sec + fwrite(&bytespersec, 4, 1, file); + unsigned short int blockalign = 2 * channels; //2 channels * 16 bits/8 + fwrite(&blockalign, 2, 1, file); + unsigned short int bitspersample = 16; + fwrite(&bitspersample, 2, 1, file); - fwrite("data",4,1,file); - chunksize=sampleswritten*blockalign; - fwrite(&chunksize,4,1,file); + fwrite("data", 4, 1, file); + chunksize = sampleswritten * blockalign; + fwrite(&chunksize, 4, 1, file); fclose(file); - file=NULL; + file = NULL; } -}; +} -void WAVaudiooutput::write_stereo_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_stereo_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,4,file); - sampleswritten+=nsmps; -}; + if(!file) + return; + fwrite(smps, nsmps, 4, file); + sampleswritten += nsmps; +} -void WAVaudiooutput::write_mono_samples(int nsmps,short int *smps) +void WAVaudiooutput::write_mono_samples(int nsmps, short int *smps) { - if (!file) return; - fwrite(smps,nsmps,2,file); - sampleswritten+=nsmps; -}; - + if(!file) + return; + fwrite(smps, nsmps, 2, file); + sampleswritten += nsmps; +} diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h index 54abae8fd..193fb19f3 100644 --- a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h @@ -23,20 +23,21 @@ class WAVaudiooutput { -public: - WAVaudiooutput(); - ~WAVaudiooutput(); + public: + WAVaudiooutput(); + ~WAVaudiooutput(); - bool newfile(std::string filename,int samplerate,int channels); - void close(); + bool newfile(std::string filename, int samplerate, int channels); + void close(); - void write_mono_samples(int nsmps, short int *smps); - void write_stereo_samples(int nsmps, short int *smps); + void write_mono_samples(int nsmps, short int *smps); + void write_stereo_samples(int nsmps, short int *smps); -private: - int sampleswritten; - int samplerate; - int channels; - FILE *file; + private: + int sampleswritten; + int samplerate; + int channels; + FILE *file; }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp index 5fb6ce797..80c23391d 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.cpp @@ -25,114 +25,125 @@ #include #include "ADnoteParameters.h" +int ADnote_unison_sizes[] = +{1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 25, 30, 40, 50, 0}; ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets() { setpresettype("Padsyth"); - fft=fft_; + fft = fft_; - GlobalPar.FreqEnvelope=new EnvelopeParams(0,0); - GlobalPar.FreqEnvelope->ASRinit(64,50,64,60); - GlobalPar.FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + GlobalPar.FreqEnvelope = new EnvelopeParams(0, 0); + GlobalPar.FreqEnvelope->ASRinit(64, 50, 64, 60); + GlobalPar.FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - GlobalPar.AmpEnvelope=new EnvelopeParams(64,1); - GlobalPar.AmpEnvelope->ADSRinit_dB(0,40,127,25); - GlobalPar.AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + GlobalPar.AmpEnvelope = new EnvelopeParams(64, 1); + GlobalPar.AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + GlobalPar.AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalPar.GlobalFilter=new FilterParams(2,94,40); - GlobalPar.FilterEnvelope=new EnvelopeParams(0,1); - GlobalPar.FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - GlobalPar.FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); - GlobalPar.Reson=new Resonance(); + GlobalPar.GlobalFilter = new FilterParams(2, 94, 40); + GlobalPar.FilterEnvelope = new EnvelopeParams(0, 1); + GlobalPar.FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + GlobalPar.FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); + GlobalPar.Reson = new Resonance(); - for (int nvoice=0;nvoicedefaults(); GlobalPar.FreqLfo->defaults(); - GlobalPar.PBandwidth=64; + GlobalPar.PBandwidth = 64; /* Amplitude Global Parameters */ - GlobalPar.PVolume=90; - GlobalPar.PPanning=64;//center - GlobalPar.PAmpVelocityScaleFunction=64; + GlobalPar.PVolume = 90; + GlobalPar.PPanning = 64; //center + GlobalPar.PAmpVelocityScaleFunction = 64; GlobalPar.AmpEnvelope->defaults(); GlobalPar.AmpLfo->defaults(); - GlobalPar.PPunchStrength=0; - GlobalPar.PPunchTime=60; - GlobalPar.PPunchStretch=64; - GlobalPar.PPunchVelocitySensing=72; - GlobalPar.Hrandgrouping=0; + GlobalPar.PPunchStrength = 0; + GlobalPar.PPunchTime = 60; + GlobalPar.PPunchStretch = 64; + GlobalPar.PPunchVelocitySensing = 72; + GlobalPar.Hrandgrouping = 0; /* Filter Global Parameters*/ - GlobalPar.PFilterVelocityScale=64; - GlobalPar.PFilterVelocityScaleFunction=64; + GlobalPar.PFilterVelocityScale = 64; + GlobalPar.PFilterVelocityScaleFunction = 64; GlobalPar.GlobalFilter->defaults(); GlobalPar.FilterEnvelope->defaults(); GlobalPar.FilterLfo->defaults(); GlobalPar.Reson->defaults(); - for (int nvoice=0;nvoicedefaults(); VoicePar[nvoice].FMSmp->defaults(); @@ -149,7 +160,7 @@ void ADnoteParameters::defaults(int n) VoicePar[nvoice].FMFreqEnvelope->defaults(); VoicePar[nvoice].FMAmpEnvelope->defaults(); -}; +} @@ -158,39 +169,48 @@ void ADnoteParameters::defaults(int n) */ void ADnoteParameters::EnableVoice(int nvoice) { - VoicePar[nvoice].OscilSmp=new OscilGen(fft,GlobalPar.Reson); - VoicePar[nvoice].FMSmp=new OscilGen(fft,NULL); + VoicePar[nvoice].OscilSmp = new OscilGen(fft, GlobalPar.Reson); + VoicePar[nvoice].FMSmp = new OscilGen(fft, NULL); - VoicePar[nvoice].AmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0,100,127,100); - VoicePar[nvoice].AmpLfo=new LFOParams(90,32,64,0,0,30,0,1); + VoicePar[nvoice].AmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0, 100, 127, 100); + VoicePar[nvoice].AmpLfo = new LFOParams(90, 32, 64, 0, 0, 30, 0, 1); - VoicePar[nvoice].FreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FreqEnvelope->ASRinit(30,40,64,60); - VoicePar[nvoice].FreqLfo=new LFOParams(50,40,0,0,0,0,0,0); + VoicePar[nvoice].FreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FreqEnvelope->ASRinit(30, 40, 64, 60); + VoicePar[nvoice].FreqLfo = new LFOParams(50, 40, 0, 0, 0, 0, 0, 0); - VoicePar[nvoice].VoiceFilter=new FilterParams(2,50,60); - VoicePar[nvoice].FilterEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90,70,40,70,10,40); - VoicePar[nvoice].FilterLfo=new LFOParams(50,20,64,0,0,0,0,2); + VoicePar[nvoice].VoiceFilter = new FilterParams(2, 50, 60); + VoicePar[nvoice].FilterEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90, 70, 40, 70, 10, 40); + VoicePar[nvoice].FilterLfo = new LFOParams(50, 20, 64, 0, 0, 0, 0, 2); - VoicePar[nvoice].FMFreqEnvelope=new EnvelopeParams(0,0); - VoicePar[nvoice].FMFreqEnvelope->ASRinit(20,90,40,80); - VoicePar[nvoice].FMAmpEnvelope=new EnvelopeParams(64,1); - VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80,90,127,100); -}; + VoicePar[nvoice].FMFreqEnvelope = new EnvelopeParams(0, 0); + VoicePar[nvoice].FMFreqEnvelope->ASRinit(20, 90, 40, 80); + VoicePar[nvoice].FMAmpEnvelope = new EnvelopeParams(64, 1); + VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80, 90, 127, 100); +} /* * Get the Multiplier of the fine detunes of the voices */ REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier() { - REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0; - bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0); + REALTYPE bw = (GlobalPar.PBandwidth - 64.0) / 64.0; + bw = pow(2.0, bw * pow(fabs(bw), 0.2) * 5.0); - return(bw); -}; + return bw; +} +/* + * Get the unison spread in cents for a voice + */ + +REALTYPE ADnoteParameters::getUnisonFrequencySpreadCents(int nvoice) { + REALTYPE unison_spread = VoicePar[nvoice].Unison_frequency_spread / 127.0; + unison_spread = pow(unison_spread * 2.0, 2.0) * 50.0; //cents + return unison_spread; +} /* * Kill the voice @@ -212,56 +232,101 @@ void ADnoteParameters::KillVoice(int nvoice) delete (VoicePar[nvoice].FMFreqEnvelope); delete (VoicePar[nvoice].FMAmpEnvelope); -}; +} ADnoteParameters::~ADnoteParameters() { - delete(GlobalPar.FreqEnvelope); - delete(GlobalPar.FreqLfo); - delete(GlobalPar.AmpEnvelope); - delete(GlobalPar.AmpLfo); - delete(GlobalPar.GlobalFilter); - delete(GlobalPar.FilterEnvelope); - delete(GlobalPar.FilterLfo); - delete(GlobalPar.Reson); + delete (GlobalPar.FreqEnvelope); + delete (GlobalPar.FreqLfo); + delete (GlobalPar.AmpEnvelope); + delete (GlobalPar.AmpLfo); + delete (GlobalPar.GlobalFilter); + delete (GlobalPar.FilterEnvelope); + delete (GlobalPar.FilterLfo); + delete (GlobalPar.Reson); - for (int nvoice=0;nvoice= NUM_VOICES) + return 0; + int unison = VoicePar[nvoice].Unison_size; + + while(1) { + if(ADnote_unison_sizes[index] >= unison) + return index; + ; + if(ADnote_unison_sizes[index] == 0) + return index - 1; + ; + index++; + } + return 0; +} + +void ADnoteParameters::set_unison_size_index(int nvoice, int index) { + int unison = 1; + for(int i = 0; i <= index; i++) { + unison = ADnote_unison_sizes[i]; + if(unison == 0) { + unison = ADnote_unison_sizes[i - 1]; + break; + } + } + + VoicePar[nvoice].Unison_size = unison; +} - -void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) +void ADnoteParameters::add2XMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; - int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice + int oscilused = 0, fmoscilused = 0; //if the oscil or fmoscil are used by another voice - for (int i=0;iaddparbool("enabled",VoicePar[nvoice].Enabled); - if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return; + xml->addparbool("enabled", VoicePar[nvoice].Enabled); + if(((VoicePar[nvoice].Enabled == 0) && (oscilused == 0) + && (fmoscilused == 0)) && (xml->minimal)) + return; - xml->addpar("type",VoicePar[nvoice].Type); - xml->addpar("delay",VoicePar[nvoice].PDelay); - xml->addparbool("resonance",VoicePar[nvoice].Presonance); - xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil); - xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil); + xml->addpar("type", VoicePar[nvoice].Type); - xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase); - xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + xml->addpar("unison_size", VoicePar[nvoice].Unison_size); + xml->addpar("unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + xml->addpar("unison_stereo_spread", VoicePar[nvoice].Unison_stereo_spread); + xml->addpar("unison_vibratto", VoicePar[nvoice].Unison_vibratto); + xml->addpar("unison_vibratto_speed", VoicePar[nvoice].Unison_vibratto_speed); + xml->addpar("unison_invert_phase", VoicePar[nvoice].Unison_invert_phase); - xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + xml->addpar("delay", VoicePar[nvoice].PDelay); + xml->addparbool("resonance", VoicePar[nvoice].Presonance); - xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled); + xml->addpar("ext_oscil", VoicePar[nvoice].Pextoscil); + xml->addpar("ext_fm_oscil", VoicePar[nvoice].PextFMoscil); + + xml->addpar("oscil_phase", VoicePar[nvoice].Poscilphase); + xml->addpar("oscil_fm_phase", VoicePar[nvoice].PFMoscilphase); + + xml->addparbool("filter_enabled", VoicePar[nvoice].PFilterEnabled); + xml->addparbool("filter_bypass", VoicePar[nvoice].Pfilterbypass); + + xml->addpar("fm_enabled", VoicePar[nvoice].PFMEnabled); xml->beginbranch("OSCIL"); VoicePar[nvoice].OscilSmp->add2XML(xml); @@ -269,94 +334,102 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("panning",VoicePar[nvoice].PPanning); - xml->addpar("volume",VoicePar[nvoice].PVolume); - xml->addparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - xml->addpar("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + xml->addpar("panning", VoicePar[nvoice].PPanning); + xml->addpar("volume", VoicePar[nvoice].PVolume); + xml->addparbool("volume_minus", VoicePar[nvoice].PVolumeminus); + xml->addpar("velocity_sensing", VoicePar[nvoice].PAmpVelocityScaleFunction); - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if((VoicePar[nvoice].PAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].AmpEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if ((VoicePar[nvoice].PAmpLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("amp_lfo_enabled", VoicePar[nvoice].PAmpLfoEnabled); + if((VoicePar[nvoice].PAmpLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_LFO"); VoicePar[nvoice].AmpLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - xml->addpar("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); - xml->addpar("detune",VoicePar[nvoice].PDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PDetuneType); + xml->addparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + xml->addpar("fixed_freq_et", VoicePar[nvoice].PfixedfreqET); + xml->addpar("detune", VoicePar[nvoice].PDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PDetuneType); - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FreqEnvelope->add2XML(xml); xml->endbranch(); - }; - xml->addparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if ((VoicePar[nvoice].PFreqLfoEnabled!=0)||(!xml->minimal)) { + } + xml->addparbool("freq_lfo_enabled", VoicePar[nvoice].PFreqLfoEnabled); + if((VoicePar[nvoice].PFreqLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_LFO"); VoicePar[nvoice].FreqLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_PARAMETERS"); xml->beginbranch("FILTER"); VoicePar[nvoice].VoiceFilter->add2XML(xml); xml->endbranch(); - xml->addparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if ((VoicePar[nvoice].PFilterEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if((VoicePar[nvoice].PFilterEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_ENVELOPE"); VoicePar[nvoice].FilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if ((VoicePar[nvoice].PFilterLfoEnabled!=0)||(!xml->minimal)) { + xml->addparbool("filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if((VoicePar[nvoice].PFilterLfoEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER_LFO"); VoicePar[nvoice].FilterLfo->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); - }; + } - if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)) { + if((VoicePar[nvoice].PFMEnabled != 0) || (fmoscilused != 0) + || (!xml->minimal)) { xml->beginbranch("FM_PARAMETERS"); - xml->addpar("input_voice",VoicePar[nvoice].PFMVoice); + xml->addpar("input_voice", VoicePar[nvoice].PFMVoice); - xml->addpar("volume",VoicePar[nvoice].PFMVolume); - xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + xml->addpar("volume", VoicePar[nvoice].PFMVolume); + xml->addpar("volume_damp", VoicePar[nvoice].PFMVolumeDamp); + xml->addpar("velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); - xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if((VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("AMPLITUDE_ENVELOPE"); VoicePar[nvoice].FMAmpEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("MODULATOR"); - xml->addpar("detune",VoicePar[nvoice].PFMDetune); - xml->addpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune); - xml->addpar("detune_type",VoicePar[nvoice].PFMDetuneType); + xml->addpar("detune", VoicePar[nvoice].PFMDetune); + xml->addpar("coarse_detune", VoicePar[nvoice].PFMCoarseDetune); + xml->addpar("detune_type", VoicePar[nvoice].PFMDetuneType); - xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if((VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); VoicePar[nvoice].FMFreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->beginbranch("OSCIL"); VoicePar[nvoice].FMSmp->add2XML(xml); @@ -364,23 +437,23 @@ void ADnoteParameters::add2XMLsection(XMLwrapper *xml,int n) xml->endbranch(); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::add2XML(XMLwrapper *xml) { - xml->addparbool("stereo",GlobalPar.PStereo); + xml->addparbool("stereo", GlobalPar.PStereo); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",GlobalPar.PVolume); - xml->addpar("panning",GlobalPar.PPanning); - xml->addpar("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); - xml->addpar("punch_strength",GlobalPar.PPunchStrength); - xml->addpar("punch_time",GlobalPar.PPunchTime); - xml->addpar("punch_stretch",GlobalPar.PPunchStretch); - xml->addpar("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - xml->addpar("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + xml->addpar("volume", GlobalPar.PVolume); + xml->addpar("panning", GlobalPar.PPanning); + xml->addpar("velocity_sensing", GlobalPar.PAmpVelocityScaleFunction); + xml->addpar("punch_strength", GlobalPar.PPunchStrength); + xml->addpar("punch_time", GlobalPar.PPunchTime); + xml->addpar("punch_stretch", GlobalPar.PPunchStretch); + xml->addpar("punch_velocity_sensing", GlobalPar.PPunchVelocitySensing); + xml->addpar("harmonic_randomness_grouping", GlobalPar.Hrandgrouping); xml->beginbranch("AMPLITUDE_ENVELOPE"); GlobalPar.AmpEnvelope->add2XML(xml); @@ -392,12 +465,12 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("detune",GlobalPar.PDetune); + xml->addpar("detune", GlobalPar.PDetune); - xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); - xml->addpar("detune_type",GlobalPar.PDetuneType); + xml->addpar("coarse_detune", GlobalPar.PCoarseDetune); + xml->addpar("detune_type", GlobalPar.PDetuneType); - xml->addpar("bandwidth",GlobalPar.PBandwidth); + xml->addpar("bandwidth", GlobalPar.PBandwidth); xml->beginbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->add2XML(xml); @@ -410,8 +483,8 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", GlobalPar.PFilterVelocityScale); + xml->addpar("velocity_sensing", GlobalPar.PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalPar.GlobalFilter->add2XML(xml); @@ -430,48 +503,66 @@ void ADnoteParameters::add2XML(XMLwrapper *xml) GlobalPar.Reson->add2XML(xml); xml->endbranch(); - for (int nvoice=0;nvoicebeginbranch("VOICE",nvoice); - add2XMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + xml->beginbranch("VOICE", nvoice); + add2XMLsection(xml, nvoice); xml->endbranch(); - }; -}; + } +} void ADnoteParameters::getfromXML(XMLwrapper *xml) { - GlobalPar.PStereo=xml->getparbool("stereo",GlobalPar.PStereo); + GlobalPar.PStereo = xml->getparbool("stereo", GlobalPar.PStereo); - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - GlobalPar.PVolume=xml->getpar127("volume",GlobalPar.PVolume); - GlobalPar.PPanning=xml->getpar127("panning",GlobalPar.PPanning); - GlobalPar.PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + GlobalPar.PVolume = xml->getpar127("volume", GlobalPar.PVolume); + GlobalPar.PPanning = xml->getpar127("panning", GlobalPar.PPanning); + GlobalPar.PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar. + PAmpVelocityScaleFunction); - GlobalPar.PPunchStrength=xml->getpar127("punch_strength",GlobalPar.PPunchStrength); - GlobalPar.PPunchTime=xml->getpar127("punch_time",GlobalPar.PPunchTime); - GlobalPar.PPunchStretch=xml->getpar127("punch_stretch",GlobalPar.PPunchStretch); - GlobalPar.PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); - GlobalPar.Hrandgrouping=xml->getpar127("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + GlobalPar.PPunchStrength = xml->getpar127("punch_strength", + GlobalPar.PPunchStrength); + GlobalPar.PPunchTime = xml->getpar127("punch_time", + GlobalPar.PPunchTime); + GlobalPar.PPunchStretch = xml->getpar127("punch_stretch", + GlobalPar.PPunchStretch); + GlobalPar.PPunchVelocitySensing = xml->getpar127( + "punch_velocity_sensing", + GlobalPar.PPunchVelocitySensing); + GlobalPar.Hrandgrouping = xml->getpar127( + "harmonic_randomness_grouping", + GlobalPar.Hrandgrouping); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { GlobalPar.AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_LFO")) { + if(xml->enterbranch("AMPLITUDE_LFO")) { GlobalPar.AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - GlobalPar.PDetune=xml->getpar("detune",GlobalPar.PDetune,0,16383); - GlobalPar.PCoarseDetune=xml->getpar("coarse_detune",GlobalPar.PCoarseDetune,0,16383); - GlobalPar.PDetuneType=xml->getpar127("detune_type",GlobalPar.PDetuneType); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + GlobalPar.PDetune = xml->getpar("detune", + GlobalPar.PDetune, + 0, + 16383); + GlobalPar.PCoarseDetune = xml->getpar("coarse_detune", + GlobalPar.PCoarseDetune, + 0, + 16383); + GlobalPar.PDetuneType = xml->getpar127("detune_type", + GlobalPar.PDetuneType); - GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); + GlobalPar.PBandwidth = xml->getpar127("bandwidth", + GlobalPar.PBandwidth); xml->enterbranch("FREQUENCY_ENVELOPE"); GlobalPar.FreqEnvelope->getfromXML(xml); @@ -482,12 +573,16 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - GlobalPar.PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); - GlobalPar.PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + GlobalPar.PFilterVelocityScale = xml->getpar127( + "velocity_sensing_amplitude", + GlobalPar.PFilterVelocityScale); + GlobalPar.PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + GlobalPar.PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalPar.GlobalFilter->getfromXML(xml); @@ -501,148 +596,244 @@ void ADnoteParameters::getfromXML(XMLwrapper *xml) GlobalPar.FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { GlobalPar.Reson->getfromXML(xml); xml->exitbranch(); - }; + } - for (int nvoice=0;nvoiceenterbranch("VOICE",nvoice)==0) continue; - getfromXMLsection(xml,nvoice); + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + VoicePar[nvoice].Enabled = 0; + if(xml->enterbranch("VOICE", nvoice) == 0) + continue; + getfromXMLsection(xml, nvoice); xml->exitbranch(); - }; + } +} - -}; - -void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n) +void ADnoteParameters::getfromXMLsection(XMLwrapper *xml, int n) { - int nvoice=n; - if (nvoice>=NUM_VOICES) return; + int nvoice = n; + if(nvoice >= NUM_VOICES) + return; - VoicePar[nvoice].Enabled=xml->getparbool("enabled",0); + VoicePar[nvoice].Enabled = xml->getparbool("enabled", 0); - VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type); - VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay); - VoicePar[nvoice].Presonance=xml->getparbool("resonance",VoicePar[nvoice].Presonance); + VoicePar[nvoice].Unison_size = + xml->getpar127("unison_size", VoicePar[nvoice].Unison_size); + VoicePar[nvoice].Unison_frequency_spread = xml->getpar127( + "unison_frequency_spread", + VoicePar[nvoice].Unison_frequency_spread); + VoicePar[nvoice].Unison_stereo_spread = xml->getpar127( + "unison_stereo_spread", + VoicePar[nvoice].Unison_stereo_spread); + VoicePar[nvoice].Unison_vibratto = xml->getpar127( + "unison_vibratto", + VoicePar[nvoice]. + Unison_vibratto); + VoicePar[nvoice].Unison_vibratto_speed = xml->getpar127( + "unison_vibratto_speed", + VoicePar[nvoice].Unison_vibratto_speed); + VoicePar[nvoice].Unison_invert_phase = xml->getpar127( + "unison_invert_phase", + VoicePar[nvoice].Unison_invert_phase); - VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); - VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); + VoicePar[nvoice].Type = xml->getpar127("type", + VoicePar[nvoice].Type); + VoicePar[nvoice].PDelay = xml->getpar127("delay", + VoicePar[nvoice].PDelay); + VoicePar[nvoice].Presonance = + xml->getparbool("resonance", VoicePar[nvoice].Presonance); - VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); - VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + VoicePar[nvoice].Pextoscil = xml->getpar("ext_oscil", + -1, + -1, + nvoice - 1); + VoicePar[nvoice].PextFMoscil = xml->getpar("ext_fm_oscil", + -1, + -1, + nvoice - 1); - VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); - VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + VoicePar[nvoice].Poscilphase = + xml->getpar127("oscil_phase", VoicePar[nvoice].Poscilphase); + VoicePar[nvoice].PFMoscilphase = xml->getpar127( + "oscil_fm_phase", + VoicePar[nvoice]. + PFMoscilphase); - VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled); + VoicePar[nvoice].PFilterEnabled = xml->getparbool( + "filter_enabled", + VoicePar[nvoice]. + PFilterEnabled); + VoicePar[nvoice].Pfilterbypass = xml->getparbool( + "filter_bypass", + VoicePar[nvoice]. + Pfilterbypass); - if (xml->enterbranch("OSCIL")) { + VoicePar[nvoice].PFMEnabled = + xml->getpar127("fm_enabled", VoicePar[nvoice].PFMEnabled); + + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].OscilSmp->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - VoicePar[nvoice].PPanning=xml->getpar127("panning",VoicePar[nvoice].PPanning); - VoicePar[nvoice].PVolume=xml->getpar127("volume",VoicePar[nvoice].PVolume); - VoicePar[nvoice].PVolumeminus=xml->getparbool("volume_minus",VoicePar[nvoice].PVolumeminus); - VoicePar[nvoice].PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + VoicePar[nvoice].PPanning = + xml->getpar127("panning", VoicePar[nvoice].PPanning); + VoicePar[nvoice].PVolume = + xml->getpar127("volume", VoicePar[nvoice].PVolume); + VoicePar[nvoice].PVolumeminus = xml->getparbool( + "volume_minus", + VoicePar[nvoice]. + PVolumeminus); + VoicePar[nvoice].PAmpVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PAmpVelocityScaleFunction); - VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + VoicePar[nvoice].PAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); - if (xml->enterbranch("AMPLITUDE_LFO")) { + VoicePar[nvoice].PAmpLfoEnabled = xml->getparbool( + "amp_lfo_enabled", + VoicePar[nvoice]. + PAmpLfoEnabled); + if(xml->enterbranch("AMPLITUDE_LFO")) { VoicePar[nvoice].AmpLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - VoicePar[nvoice].Pfixedfreq=xml->getparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); - VoicePar[nvoice].PfixedfreqET=xml->getpar127("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + VoicePar[nvoice].Pfixedfreq = + xml->getparbool("fixed_freq", VoicePar[nvoice].Pfixedfreq); + VoicePar[nvoice].PfixedfreqET = xml->getpar127( + "fixed_freq_et", + VoicePar[nvoice]. + PfixedfreqET); - VoicePar[nvoice].PDetune=xml->getpar("detune",VoicePar[nvoice].PDetune,0,16383); + VoicePar[nvoice].PDetune = xml->getpar("detune", + VoicePar[nvoice].PDetune, + 0, + 16383); - VoicePar[nvoice].PCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PCoarseDetune,0,16383); - VoicePar[nvoice].PDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PDetuneType); + VoicePar[nvoice].PCoarseDetune = + xml->getpar("coarse_detune", + VoicePar[nvoice].PCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PDetuneType); - VoicePar[nvoice].PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + VoicePar[nvoice].PFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); - if (xml->enterbranch("FREQUENCY_LFO")) { + VoicePar[nvoice].PFreqLfoEnabled = xml->getparbool( + "freq_lfo_enabled", + VoicePar[nvoice]. + PFreqLfoEnabled); + if(xml->enterbranch("FREQUENCY_LFO")) { VoicePar[nvoice].FreqLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + if(xml->enterbranch("FILTER")) { VoicePar[nvoice].VoiceFilter->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); - if (xml->enterbranch("FILTER_ENVELOPE")) { + VoicePar[nvoice].PFilterEnvelopeEnabled = xml->getparbool( + "filter_envelope_enabled", + VoicePar[nvoice].PFilterEnvelopeEnabled); + if(xml->enterbranch("FILTER_ENVELOPE")) { VoicePar[nvoice].FilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); - if (xml->enterbranch("FILTER_LFO")) { + VoicePar[nvoice].PFilterLfoEnabled = xml->getparbool( + "filter_lfo_enabled", + VoicePar[nvoice].PFilterLfoEnabled); + if(xml->enterbranch("FILTER_LFO")) { VoicePar[nvoice].FilterLfo->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FM_PARAMETERS")) { - VoicePar[nvoice].PFMVoice=xml->getpar("input_voice",VoicePar[nvoice].PFMVoice,-1,nvoice-1); + if(xml->enterbranch("FM_PARAMETERS")) { + VoicePar[nvoice].PFMVoice = + xml->getpar("input_voice", + VoicePar[nvoice].PFMVoice, + -1, + nvoice - 1); - VoicePar[nvoice].PFMVolume=xml->getpar127("volume",VoicePar[nvoice].PFMVolume); - VoicePar[nvoice].PFMVolumeDamp=xml->getpar127("volume_damp",VoicePar[nvoice].PFMVolumeDamp); - VoicePar[nvoice].PFMVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + VoicePar[nvoice].PFMVolume = + xml->getpar127("volume", VoicePar[nvoice].PFMVolume); + VoicePar[nvoice].PFMVolumeDamp = xml->getpar127( + "volume_damp", + VoicePar[nvoice]. + PFMVolumeDamp); + VoicePar[nvoice].PFMVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + VoicePar[nvoice].PFMVelocityScaleFunction); - VoicePar[nvoice].PFMAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + VoicePar[nvoice].PFMAmpEnvelopeEnabled = xml->getparbool( + "amp_envelope_enabled", + VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("MODULATOR")) { - VoicePar[nvoice].PFMDetune=xml->getpar("detune",VoicePar[nvoice].PFMDetune,0,16383); - VoicePar[nvoice].PFMCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune,0,16383); - VoicePar[nvoice].PFMDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PFMDetuneType); + if(xml->enterbranch("MODULATOR")) { + VoicePar[nvoice].PFMDetune = + xml->getpar("detune", VoicePar[nvoice].PFMDetune, 0, 16383); + VoicePar[nvoice].PFMCoarseDetune = xml->getpar( + "coarse_detune", + VoicePar[nvoice]. + PFMCoarseDetune, + 0, + 16383); + VoicePar[nvoice].PFMDetuneType = xml->getpar127( + "detune_type", + VoicePar[nvoice]. + PFMDetuneType); - VoicePar[nvoice].PFMFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + VoicePar[nvoice].PFMFreqEnvelopeEnabled = xml->getparbool( + "freq_envelope_enabled", + VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { VoicePar[nvoice].FMSmp->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h index 8b35f92c4..ee5a632bd 100644 --- a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h @@ -35,14 +35,16 @@ #include "../DSP/FFTwrapper.h" #include "Presets.h" -enum FMTYPE {NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD}; +enum FMTYPE { + NONE, MORPH, RING_MOD, PHASE_MOD, FREQ_MOD, PITCH_MOD +}; +extern int ADnote_unison_sizes[]; /*****************************************************************/ /* GLOBAL PARAMETERS */ /*****************************************************************/ struct ADnoteGlobalParam { - /* The instrument type - MONO/STEREO If the mode is MONO, the panning of voices are not used Stereo=1, Mono=0. */ @@ -53,35 +55,36 @@ struct ADnoteGlobalParam { /****************************************** * FREQUENCY GLOBAL PARAMETERS * ******************************************/ - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - unsigned char PBandwidth;//how much the relative fine detunes of the voices are changed + unsigned char PBandwidth; //how much the relative fine detunes of the voices are changed - EnvelopeParams *FreqEnvelope; //Frequency Envelope + EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + LFOParams *FreqLfo; //Frequency LFO /******************************************** * AMPLITUDE GLOBAL PARAMETERS * ********************************************/ /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - unsigned char PVolume; + unsigned char PVolume; - unsigned char PAmpVelocityScaleFunction; + unsigned char PAmpVelocityScaleFunction; EnvelopeParams *AmpEnvelope; - LFOParams *AmpLfo; + LFOParams *AmpLfo; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; /****************************************** * FILTER GLOBAL PARAMETERS * @@ -92,11 +95,11 @@ struct ADnoteGlobalParam { unsigned char PFilterVelocityScale; // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; + unsigned char PFilterVelocityScaleFunction; EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + LFOParams *FilterLfo; // RESONANCE Resonance *Reson; @@ -111,10 +114,27 @@ struct ADnoteGlobalParam { /* VOICE PARAMETERS */ /***********************************************************/ struct ADnoteVoiceParam { - /** If the voice is enabled */ unsigned char Enabled; + /** How many subvoices are used in this voice */ + unsigned char Unison_size; + + /** How subvoices are spread */ + unsigned char Unison_frequency_spread; + + /** Stereo spread of the subvoices*/ + unsigned char Unison_stereo_spread; + + /** Vibratto of the subvoices (which makes the unison more "natural")*/ + unsigned char Unison_vibratto; + + /** Medium speed of the vibratto of the subvoices*/ + unsigned char Unison_vibratto_speed; + + /** Unison invert phase */ + unsigned char Unison_invert_phase; //0=none,1=random,2=50%,3=33%,4=25% + /** Type of the voice (0=Sound,1=Noise)*/ unsigned char Type; @@ -125,11 +145,11 @@ struct ADnoteVoiceParam { unsigned char Presonance; // What external oscil should I use, -1 for internal OscilSmp&FMSmp - short int Pextoscil,PextFMoscil; + short int Pextoscil, PextFMoscil; // it is not allowed that the externoscil,externFMoscil => current voice // oscillator phases - unsigned char Poscilphase,PFMoscilphase; + unsigned char Poscilphase, PFMoscilphase; // filter bypass unsigned char Pfilterbypass; @@ -159,12 +179,12 @@ struct ADnoteVoiceParam { unsigned char PDetuneType; /* Frequency Envelope */ - unsigned char PFreqEnvelopeEnabled; + unsigned char PFreqEnvelopeEnabled; EnvelopeParams *FreqEnvelope; /* Frequency LFO */ unsigned char PFreqLfoEnabled; - LFOParams *FreqLfo; + LFOParams *FreqLfo; /*************************** @@ -172,9 +192,9 @@ struct ADnoteVoiceParam { ***************************/ /* Panning 0 - random - 1 - left - 64 - center - 127 - right + 1 - left + 64 - center + 127 - right The Panning is ignored if the instrument is mono */ unsigned char PPanning; @@ -188,12 +208,12 @@ struct ADnoteVoiceParam { unsigned char PAmpVelocityScaleFunction; /* Amplitude Envelope */ - unsigned char PAmpEnvelopeEnabled; + unsigned char PAmpEnvelopeEnabled; EnvelopeParams *AmpEnvelope; /* Amplitude LFO */ unsigned char PAmpLfoEnabled; - LFOParams *AmpLfo; + LFOParams *AmpLfo; @@ -206,12 +226,12 @@ struct ADnoteVoiceParam { FilterParams *VoiceFilter; /* Filter Envelope */ - unsigned char PFilterEnvelopeEnabled; + unsigned char PFilterEnvelopeEnabled; EnvelopeParams *FilterEnvelope; /* LFO Envelope */ unsigned char PFilterLfoEnabled; - LFOParams *FilterLfo; + LFOParams *FilterLfo; /**************************** * MODULLATOR PARAMETERS * @@ -247,37 +267,41 @@ struct ADnoteVoiceParam { unsigned char PFMDetuneType; /* Frequency Envelope of the Modullator */ - unsigned char PFMFreqEnvelopeEnabled; + unsigned char PFMFreqEnvelopeEnabled; EnvelopeParams *FMFreqEnvelope; /* Frequency Envelope of the Modullator */ - unsigned char PFMAmpEnvelopeEnabled; + unsigned char PFMAmpEnvelopeEnabled; EnvelopeParams *FMAmpEnvelope; }; class ADnoteParameters:public Presets { -public: - ADnoteParameters(FFTwrapper *fft_); - ~ADnoteParameters(); + public: + ADnoteParameters(FFTwrapper *fft_); + ~ADnoteParameters(); - ADnoteGlobalParam GlobalPar; - ADnoteVoiceParam VoicePar[NUM_VOICES]; + ADnoteGlobalParam GlobalPar; + ADnoteVoiceParam VoicePar[NUM_VOICES]; - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - REALTYPE getBandwidthDetuneMultiplier(); -private: - void defaults(int n);//n is the nvoice + REALTYPE getBandwidthDetuneMultiplier(); + REALTYPE getUnisonFrequencySpreadCents(int nvoice); + int get_unison_size_index(int nvoice); + void set_unison_size_index(int nvoice, int index); + private: + void defaults(int n); //n is the nvoice - void EnableVoice(int nvoice); - void KillVoice(int nvoice); - FFTwrapper *fft; + void EnableVoice(int nvoice); + void KillVoice(int nvoice); + FFTwrapper *fft; - void add2XMLsection(XMLwrapper *xml,int n); - void getfromXMLsection(XMLwrapper *xml,int n); + void add2XMLsection(XMLwrapper *xml, int n); + void getfromXMLsection(XMLwrapper *xml, int n); }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/Controller.cpp b/plugins/zynaddsubfx/src/Params/Controller.cpp index 2388dd4b6..61a0793e0 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.cpp +++ b/plugins/zynaddsubfx/src/Params/Controller.cpp @@ -28,50 +28,48 @@ Controller::Controller() { defaults(); resetall(); -}; +} Controller::~Controller() -{ -}; +{} void Controller::defaults() { - setpitchwheelbendrange(200);//2 halftones - expression.receive=1; - panning.depth=64; - filtercutoff.depth=64; - filterq.depth=64; - bandwidth.depth=64; - bandwidth.exponential=0; - modwheel.depth=80; - modwheel.exponential=0; - fmamp.receive=1; - volume.receive=1; - sustain.receive=1; - NRPN.receive=1; + setpitchwheelbendrange(200); //2 halftones + expression.receive = 1; + panning.depth = 64; + filtercutoff.depth = 64; + filterq.depth = 64; + bandwidth.depth = 64; + bandwidth.exponential = 0; + modwheel.depth = 80; + modwheel.exponential = 0; + fmamp.receive = 1; + volume.receive = 1; + sustain.receive = 1; + NRPN.receive = 1; - portamento.portamento=0; - portamento.used=0; - portamento.proportional=0; - portamento.propRate=80; - portamento.propDepth=90; - portamento.receive=1; - portamento.time=64; - portamento.updowntimestretch=64; - portamento.pitchthresh=3; - portamento.pitchthreshtype=1; - portamento.noteusing=-1; - resonancecenter.depth=64; - resonancebandwidth.depth=64; + portamento.portamento = 0; + portamento.used = 0; + portamento.proportional = 0; + portamento.propRate = 80; + portamento.propDepth = 90; + portamento.receive = 1; + portamento.time = 64; + portamento.updowntimestretch = 64; + portamento.pitchthresh = 3; + portamento.pitchthreshtype = 1; + portamento.noteusing = -1; + resonancecenter.depth = 64; + resonancebandwidth.depth = 64; - initportamento(440.0,440.0,false); // Now has a third argument + initportamento(440.0, 440.0, false); // Now has a third argument setportamento(0); - -}; +} void Controller::resetall() { - setpitchwheel(0);//center + setpitchwheel(0); //center setexpression(127); setpanning(64); setfiltercutoff(64); @@ -85,276 +83,333 @@ void Controller::resetall() setresonancebw(64); //reset the NRPN - NRPN.parhi=-1; - NRPN.parlo=-1; - NRPN.valhi=-1; - NRPN.vallo=-1; -}; + NRPN.parhi = -1; + NRPN.parlo = -1; + NRPN.valhi = -1; + NRPN.vallo = -1; +} void Controller::setpitchwheel(int value) { - pitchwheel.data=value; - REALTYPE cents=value/8192.0; - cents*=pitchwheel.bendrange; - pitchwheel.relfreq=pow(2,cents/1200.0); + pitchwheel.data = value; + REALTYPE cents = value / 8192.0; + cents *= pitchwheel.bendrange; + pitchwheel.relfreq = pow(2, cents / 1200.0); //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); -}; +} void Controller::setpitchwheelbendrange(unsigned short int value) { - pitchwheel.bendrange=value; -}; + pitchwheel.bendrange = value; +} void Controller::setexpression(int value) { - expression.data=value; - if (expression.receive!=0) expression.relvolume=value/127.0; - else expression.relvolume=1.0; -}; + expression.data = value; + if(expression.receive != 0) + expression.relvolume = value / 127.0; + else + expression.relvolume = 1.0; +} void Controller::setpanning(int value) { - panning.data=value; - panning.pan=(value/128.0-0.5)*(panning.depth/64.0); -}; + panning.data = value; + panning.pan = (value / 128.0 - 0.5) * (panning.depth / 64.0); +} void Controller::setfiltercutoff(int value) { - filtercutoff.data=value; - filtercutoff.relfreq=(value-64.0)*filtercutoff.depth/4096.0*3.321928;//3.3219..=ln2(10) -}; + filtercutoff.data = value; + filtercutoff.relfreq = + (value - 64.0) * filtercutoff.depth / 4096.0 * 3.321928; //3.3219..=ln2(10) +} void Controller::setfilterq(int value) { - filterq.data=value; - filterq.relq=pow(30.0,(value-64.0)/64.0*(filterq.depth/64.0)); -}; + filterq.data = value; + filterq.relq = pow(30.0, (value - 64.0) / 64.0 * (filterq.depth / 64.0)); +} void Controller::setbandwidth(int value) { - bandwidth.data=value; - if (bandwidth.exponential==0) { - REALTYPE tmp=pow(25.0,pow(bandwidth.depth/127.0,1.5))-1.0; - if ((value<64)&&(bandwidth.depth>=64)) tmp=1.0; - bandwidth.relbw=(value/64.0-1.0)*tmp+1.0; - if (bandwidth.relbw<0.01) bandwidth.relbw=0.01; - } else { - bandwidth.relbw=pow(25.0,(value-64.0)/64.0*(bandwidth.depth/64.0)); - }; -}; + bandwidth.data = value; + if(bandwidth.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(bandwidth.depth / 127.0, 1.5)) - 1.0; + if((value < 64) && (bandwidth.depth >= 64)) + tmp = 1.0; + bandwidth.relbw = (value / 64.0 - 1.0) * tmp + 1.0; + if(bandwidth.relbw < 0.01) + bandwidth.relbw = 0.01; + } + else + bandwidth.relbw = + pow(25.0, (value - 64.0) / 64.0 * (bandwidth.depth / 64.0)); + ; +} void Controller::setmodwheel(int value) { - modwheel.data=value; - if (modwheel.exponential==0) { - REALTYPE tmp=pow(25.0,pow(modwheel.depth/127.0,1.5)*2.0)/25.0; - if ((value<64)&&(modwheel.depth>=64)) tmp=1.0; - modwheel.relmod=(value/64.0-1.0)*tmp+1.0; - if (modwheel.relmod<0.0) modwheel.relmod=0.0; - } else modwheel.relmod=pow(25.0,(value-64.0)/64.0*(modwheel.depth/80.0)); -}; + modwheel.data = value; + if(modwheel.exponential == 0) { + REALTYPE tmp = pow(25.0, pow(modwheel.depth / 127.0, 1.5) * 2.0) / 25.0; + if((value < 64) && (modwheel.depth >= 64)) + tmp = 1.0; + modwheel.relmod = (value / 64.0 - 1.0) * tmp + 1.0; + if(modwheel.relmod < 0.0) + modwheel.relmod = 0.0; + } + else + modwheel.relmod = + pow(25.0, (value - 64.0) / 64.0 * (modwheel.depth / 80.0)); +} void Controller::setfmamp(int value) { - fmamp.data=value; - fmamp.relamp=value/127.0; - if (fmamp.receive!=0) fmamp.relamp=value/127.0; - else fmamp.relamp=1.0; -}; + fmamp.data = value; + fmamp.relamp = value / 127.0; + if(fmamp.receive != 0) + fmamp.relamp = value / 127.0; + else + fmamp.relamp = 1.0; +} void Controller::setvolume(int value) { - volume.data=value; - if (volume.receive!=0) volume.volume=pow(0.1,(127-value)/127.0*2.0); - else volume.volume=1.0; -}; + volume.data = value; + if(volume.receive != 0) + volume.volume = pow(0.1, (127 - value) / 127.0 * 2.0); + else + volume.volume = 1.0; +} void Controller::setsustain(int value) { - sustain.data=value; - if (sustain.receive!=0) sustain.sustain=((value<64) ? 0 : 1 ); - else sustain.sustain=0; -}; + sustain.data = value; + if(sustain.receive != 0) + sustain.sustain = ((value < 64) ? 0 : 1); + else + sustain.sustain = 0; +} void Controller::setportamento(int value) { - portamento.data=value; - if (portamento.receive!=0) portamento.portamento=((value<64) ? 0 : 1 ); -}; + portamento.data = value; + if(portamento.receive != 0) + portamento.portamento = ((value < 64) ? 0 : 1); +} -int Controller::initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag) +int Controller::initportamento(REALTYPE oldfreq, + REALTYPE newfreq, + bool legatoflag) { - portamento.x=0.0; + portamento.x = 0.0; - if (legatoflag) { // Legato in progress - if (portamento.portamento==0) return(0); - } else { // No legato, do the original if...return - if ((portamento.used!=0) || (portamento.portamento==0)) return(0); - }; + if(legatoflag) { // Legato in progress + if(portamento.portamento == 0) + return 0; + } + else // No legato, do the original if...return + if((portamento.used != 0) || (portamento.portamento == 0)) + return 0; + ; - REALTYPE portamentotime=pow(100.0,portamento.time/127.0)/50.0;//portamento time in seconds - - if (portamento.proportional) { + REALTYPE portamentotime = pow(100.0, portamento.time / 127.0) / 50.0; //portamento time in seconds + + if(portamento.proportional) { //If there is a min(float,float) and a max(float,float) then they //could be used here //Linear functors could also make this nicer if(oldfreq > newfreq) //2 is the center of propRate - portamentotime *= pow(oldfreq/newfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(oldfreq / newfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); else //1 is the center of propDepth - portamentotime *= pow(newfreq/oldfreq/(portamento.propRate/127.0*3+.05), - (portamento.propDepth/127.0*1.6+.2)); + portamentotime *= + pow(newfreq / oldfreq / (portamento.propRate / 127.0 * 3 + .05), + (portamento.propDepth / 127.0 * 1.6 + .2)); } - if ((portamento.updowntimestretch>=64)&&(newfreq= 64) && (newfreq < oldfreq)) { + if(portamento.updowntimestretch == 127) + return 0; + portamentotime *= pow(0.1, (portamento.updowntimestretch - 64) / 63.0); + } + if((portamento.updowntimestretch < 64) && (newfreq > oldfreq)) { + if(portamento.updowntimestretch == 0) + return 0; + portamentotime *= pow(0.1, (64.0 - portamento.updowntimestretch) / 64.0); } - if ((portamento.updowntimestretch<64)&&(newfreq>oldfreq)) { - if (portamento.updowntimestretch==0) return(0); - portamentotime*=pow(0.1,(64.0-portamento.updowntimestretch)/64.0); - }; //printf("%f->%f : Time %f\n",oldfreq,newfreq,portamentotime); - portamento.dx=SOUND_BUFFER_SIZE/(portamentotime*SAMPLE_RATE); - portamento.origfreqrap=oldfreq/newfreq; + portamento.dx = SOUND_BUFFER_SIZE / (portamentotime * SAMPLE_RATE); + portamento.origfreqrap = oldfreq / newfreq; - REALTYPE tmprap=( (portamento.origfreqrap>1.0) ? - (portamento.origfreqrap) : - (1.0/portamento.origfreqrap) ); + REALTYPE tmprap = ((portamento.origfreqrap > 1.0) ? + (portamento.origfreqrap) : + (1.0 / portamento.origfreqrap)); - REALTYPE thresholdrap=pow(2.0,portamento.pitchthresh/12.0); - if ((portamento.pitchthreshtype==0) && (tmprap-0.00001>thresholdrap) ) return(0); - if ((portamento.pitchthreshtype==1) && (tmprap+0.00001 thresholdrap)) + return 0; + if((portamento.pitchthreshtype == 1) && (tmprap + 0.00001 < thresholdrap)) + return 0; - portamento.used=1; - portamento.freqrap=portamento.origfreqrap; - return (1); -}; + portamento.used = 1; + portamento.freqrap = portamento.origfreqrap; + return 1; +} void Controller::updateportamento() { - if (portamento.used==0) return; + if(portamento.used == 0) + return; - portamento.x+=portamento.dx; - if (portamento.x>1.0) { - portamento.x=1.0; - portamento.used=0; - }; - portamento.freqrap=(1.0-portamento.x)*portamento.origfreqrap+portamento.x; -}; + portamento.x += portamento.dx; + if(portamento.x > 1.0) { + portamento.x = 1.0; + portamento.used = 0; + } + portamento.freqrap = + (1.0 - portamento.x) * portamento.origfreqrap + portamento.x; +} void Controller::setresonancecenter(int value) { - resonancecenter.data=value; - resonancecenter.relcenter=pow(3.0,(value-64.0)/64.0*(resonancecenter.depth/64.0)); -}; + resonancecenter.data = value; + resonancecenter.relcenter = + pow(3.0, (value - 64.0) / 64.0 * (resonancecenter.depth / 64.0)); +} void Controller::setresonancebw(int value) { - resonancebandwidth.data=value; - resonancebandwidth.relbw=pow(1.5,(value-64.0)/64.0*(resonancebandwidth.depth/127.0)); -}; + resonancebandwidth.data = value; + resonancebandwidth.relbw = + pow(1.5, (value - 64.0) / 64.0 * (resonancebandwidth.depth / 127.0)); +} //Returns 0 if there is NRPN or 1 if there is not int Controller::getnrpn(int *parhi, int *parlo, int *valhi, int *vallo) { - if (NRPN.receive==0) return(1); - if ((NRPN.parhi<0)||(NRPN.parlo<0)||(NRPN.valhi<0)||(NRPN.vallo<0)) - return(1); + if(NRPN.receive == 0) + return 1; + if((NRPN.parhi < 0) || (NRPN.parlo < 0) || (NRPN.valhi < 0) + || (NRPN.vallo < 0)) + return 1; - *parhi=NRPN.parhi; - *parlo=NRPN.parlo; - *valhi=NRPN.valhi; - *vallo=NRPN.vallo; - return(0); -}; + *parhi = NRPN.parhi; + *parlo = NRPN.parlo; + *valhi = NRPN.valhi; + *vallo = NRPN.vallo; + return 0; +} -void Controller::setparameternumber(unsigned int type,int value) +void Controller::setparameternumber(unsigned int type, int value) { - switch (type) { + switch(type) { case C_nrpnhi: - NRPN.parhi=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parhi = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_nrpnlo: - NRPN.parlo=value; - NRPN.valhi=-1; - NRPN.vallo=-1;//clear the values + NRPN.parlo = value; + NRPN.valhi = -1; + NRPN.vallo = -1; //clear the values break; case C_dataentryhi: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.valhi = value; break; case C_dataentrylo: - if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value; + if((NRPN.parhi >= 0) && (NRPN.parlo >= 0)) + NRPN.vallo = value; break; - }; -}; + } +} void Controller::add2XML(XMLwrapper *xml) { - xml->addpar("pitchwheel_bendrange",pitchwheel.bendrange); + xml->addpar("pitchwheel_bendrange", pitchwheel.bendrange); - xml->addparbool("expression_receive",expression.receive); - xml->addpar("panning_depth",panning.depth); - xml->addpar("filter_cutoff_depth",filtercutoff.depth); - xml->addpar("filter_q_depth",filterq.depth); - xml->addpar("bandwidth_depth",bandwidth.depth); - xml->addpar("mod_wheel_depth",modwheel.depth); - xml->addparbool("mod_wheel_exponential",modwheel.exponential); - xml->addparbool("fm_amp_receive",fmamp.receive); - xml->addparbool("volume_receive",volume.receive); - xml->addparbool("sustain_receive",sustain.receive); + xml->addparbool("expression_receive", expression.receive); + xml->addpar("panning_depth", panning.depth); + xml->addpar("filter_cutoff_depth", filtercutoff.depth); + xml->addpar("filter_q_depth", filterq.depth); + xml->addpar("bandwidth_depth", bandwidth.depth); + xml->addpar("mod_wheel_depth", modwheel.depth); + xml->addparbool("mod_wheel_exponential", modwheel.exponential); + xml->addparbool("fm_amp_receive", fmamp.receive); + xml->addparbool("volume_receive", volume.receive); + xml->addparbool("sustain_receive", sustain.receive); - xml->addparbool("portamento_receive",portamento.receive); - xml->addpar("portamento_time",portamento.time); - xml->addpar("portamento_pitchthresh",portamento.pitchthresh); - xml->addpar("portamento_pitchthreshtype",portamento.pitchthreshtype); - xml->addpar("portamento_portamento",portamento.portamento); - xml->addpar("portamento_updowntimestretch",portamento.updowntimestretch); - xml->addpar("portamento_proportional",portamento.proportional); - xml->addpar("portamento_proprate",portamento.propRate); - xml->addpar("portamento_propdepth",portamento.propDepth); + xml->addparbool("portamento_receive", portamento.receive); + xml->addpar("portamento_time", portamento.time); + xml->addpar("portamento_pitchthresh", portamento.pitchthresh); + xml->addpar("portamento_pitchthreshtype", portamento.pitchthreshtype); + xml->addpar("portamento_portamento", portamento.portamento); + xml->addpar("portamento_updowntimestretch", portamento.updowntimestretch); + xml->addpar("portamento_proportional", portamento.proportional); + xml->addpar("portamento_proprate", portamento.propRate); + xml->addpar("portamento_propdepth", portamento.propDepth); - xml->addpar("resonance_center_depth",resonancecenter.depth); - xml->addpar("resonance_bandwidth_depth",resonancebandwidth.depth); -}; + xml->addpar("resonance_center_depth", resonancecenter.depth); + xml->addpar("resonance_bandwidth_depth", resonancebandwidth.depth); +} void Controller::getfromXML(XMLwrapper *xml) { - pitchwheel.bendrange=xml->getpar("pitchwheel_bendrange",pitchwheel.bendrange,-6400,6400); + pitchwheel.bendrange = xml->getpar("pitchwheel_bendrange", + pitchwheel.bendrange, + -6400, + 6400); - expression.receive=xml->getparbool("expression_receive",expression.receive); - panning.depth=xml->getpar127("panning_depth",panning.depth); - filtercutoff.depth=xml->getpar127("filter_cutoff_depth",filtercutoff.depth); - filterq.depth=xml->getpar127("filter_q_depth",filterq.depth); - bandwidth.depth=xml->getpar127("bandwidth_depth",bandwidth.depth); - modwheel.depth=xml->getpar127("mod_wheel_depth",modwheel.depth); - modwheel.exponential=xml->getparbool("mod_wheel_exponential",modwheel.exponential); - fmamp.receive=xml->getparbool("fm_amp_receive",fmamp.receive); - volume.receive=xml->getparbool("volume_receive",volume.receive); - sustain.receive=xml->getparbool("sustain_receive",sustain.receive); + expression.receive = xml->getparbool("expression_receive", + expression.receive); + panning.depth = xml->getpar127("panning_depth", panning.depth); + filtercutoff.depth = xml->getpar127("filter_cutoff_depth", + filtercutoff.depth); + filterq.depth = xml->getpar127("filter_q_depth", filterq.depth); + bandwidth.depth = xml->getpar127("bandwidth_depth", bandwidth.depth); + modwheel.depth = xml->getpar127("mod_wheel_depth", modwheel.depth); + modwheel.exponential = xml->getparbool("mod_wheel_exponential", + modwheel.exponential); + fmamp.receive = xml->getparbool("fm_amp_receive", + fmamp.receive); + volume.receive = xml->getparbool("volume_receive", + volume.receive); + sustain.receive = xml->getparbool("sustain_receive", + sustain.receive); - portamento.receive=xml->getparbool("portamento_receive",portamento.receive); - portamento.time=xml->getpar127("portamento_time",portamento.time); - portamento.pitchthresh=xml->getpar127("portamento_pitchthresh",portamento.pitchthresh); - portamento.pitchthreshtype=xml->getpar127("portamento_pitchthreshtype",portamento.pitchthreshtype); - portamento.portamento=xml->getpar127("portamento_portamento",portamento.portamento); - portamento.updowntimestretch=xml->getpar127("portamento_updowntimestretch",portamento.updowntimestretch); - portamento.proportional=xml->getpar127("portamento_proportional",portamento.proportional); - portamento.propRate=xml->getpar127("portamento_proprate",portamento.propRate); - portamento.propDepth=xml->getpar127("portamento_propdepth",portamento.propDepth); - - - resonancecenter.depth=xml->getpar127("resonance_center_depth",resonancecenter.depth); - resonancebandwidth.depth=xml->getpar127("resonance_bandwidth_depth",resonancebandwidth.depth); -}; + portamento.receive = xml->getparbool("portamento_receive", + portamento.receive); + portamento.time = xml->getpar127("portamento_time", + portamento.time); + portamento.pitchthresh = xml->getpar127("portamento_pitchthresh", + portamento.pitchthresh); + portamento.pitchthreshtype = xml->getpar127("portamento_pitchthreshtype", + portamento.pitchthreshtype); + portamento.portamento = xml->getpar127("portamento_portamento", + portamento.portamento); + portamento.updowntimestretch = xml->getpar127( + "portamento_updowntimestretch", + portamento.updowntimestretch); + portamento.proportional = xml->getpar127("portamento_proportional", + portamento.proportional); + portamento.propRate = xml->getpar127("portamento_proprate", + portamento.propRate); + portamento.propDepth = xml->getpar127("portamento_propdepth", + portamento.propDepth); + resonancecenter.depth = xml->getpar127("resonance_center_depth", + resonancecenter.depth); + resonancebandwidth.depth = xml->getpar127("resonance_bandwidth_depth", + resonancebandwidth.depth); +} diff --git a/plugins/zynaddsubfx/src/Params/Controller.h b/plugins/zynaddsubfx/src/Params/Controller.h index 3e5ededac..86a4badbb 100644 --- a/plugins/zynaddsubfx/src/Params/Controller.h +++ b/plugins/zynaddsubfx/src/Params/Controller.h @@ -30,191 +30,191 @@ /**(Midi) Controllers implementation*/ class Controller { -public: - Controller(); - ~Controller(); - void resetall(); + public: + Controller(); + ~Controller(); + void resetall(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - //Controllers functions - void setpitchwheel(int value); - void setpitchwheelbendrange(unsigned short int value); - void setexpression(int value); - void setpanning(int value); - void setfiltercutoff(int value); - void setfilterq(int value); - void setbandwidth(int value); - void setmodwheel(int value); - void setfmamp(int value); - void setvolume(int value); - void setsustain(int value); - /**Enable or disable portamento - * @param value 0-127 MIDI value (greater than 64 enables)*/ - void setportamento(int value); - void setresonancecenter(int value); - void setresonancebw(int value); + //Controllers functions + void setpitchwheel(int value); + void setpitchwheelbendrange(unsigned short int value); + void setexpression(int value); + void setpanning(int value); + void setfiltercutoff(int value); + void setfilterq(int value); + void setbandwidth(int value); + void setmodwheel(int value); + void setfmamp(int value); + void setvolume(int value); + void setsustain(int value); + /**Enable or disable portamento + * @param value 0-127 MIDI value (greater than 64 enables)*/ + void setportamento(int value); + void setresonancecenter(int value); + void setresonancebw(int value); - void setparameternumber(unsigned int type,int value);//used for RPN and NRPN's - int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); + void setparameternumber(unsigned int type, int value); //used for RPN and NRPN's + int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); - /** - * Initialize a portamento - * - * @param oldfreq Starting frequency of the portamento (Hz) - * @param newfreq Ending frequency of the portamento (Hz) - * @param legatoflag true when legato is in progress, false otherwise - * @returns 1 if properly initialized, 0 otherwise*/ - int initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag); - /**Update portamento's freqrap to next value based upon dx*/ - void updateportamento(); - - // Controllers values - struct {//Pitch Wheel - int data; - short int bendrange;//bendrange is in cents - REALTYPE relfreq;//the relative frequency (default is 1.0) - } pitchwheel; - - struct {//Expression - int data; - REALTYPE relvolume; - unsigned char receive; - } expression; - - struct {//Panning - int data; - REALTYPE pan; - unsigned char depth; - } panning; - - - struct {//Filter cutoff - int data; - REALTYPE relfreq; - unsigned char depth; - } filtercutoff; - - struct {//Filter Q - int data; - REALTYPE relq; - unsigned char depth; - } filterq; - - struct {//Bandwidth - int data; - REALTYPE relbw; - unsigned char depth; - unsigned char exponential; - } bandwidth; - - struct {//Modulation Wheel - int data; - REALTYPE relmod; - unsigned char depth; - unsigned char exponential; - } modwheel; - - struct {//FM amplitude - int data; - REALTYPE relamp; - unsigned char receive; - } fmamp; - - struct {//Volume - int data; - REALTYPE volume; - unsigned char receive; - } volume; - - struct {//Sustain - int data,sustain; - unsigned char receive; - } sustain; - - struct {/** #include "EnvelopeParams.h" -EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_):Presets() +EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_):Presets() { int i; - PA_dt=10; - PD_dt=10; - PR_dt=10; - PA_val=64; - PD_val=64; - PS_val=64; - PR_val=64; + PA_dt = 10; + PD_dt = 10; + PR_dt = 10; + PA_val = 64; + PD_val = 64; + PS_val = 64; + PR_val = 64; - for (i=0;iaddparbool("free_mode",Pfreemode); - xml->addpar("env_points",Penvpoints); - xml->addpar("env_sustain",Penvsustain); - xml->addpar("env_stretch",Penvstretch); - xml->addparbool("forced_release",Pforcedrelease); - xml->addparbool("linear_envelope",Plinearenvelope); - xml->addpar("A_dt",PA_dt); - xml->addpar("D_dt",PD_dt); - xml->addpar("R_dt",PR_dt); - xml->addpar("A_val",PA_val); - xml->addpar("D_val",PD_val); - xml->addpar("S_val",PS_val); - xml->addpar("R_val",PR_val); + xml->addparbool("free_mode", Pfreemode); + xml->addpar("env_points", Penvpoints); + xml->addpar("env_sustain", Penvsustain); + xml->addpar("env_stretch", Penvstretch); + xml->addparbool("forced_release", Pforcedrelease); + xml->addparbool("linear_envelope", Plinearenvelope); + xml->addpar("A_dt", PA_dt); + xml->addpar("D_dt", PD_dt); + xml->addpar("R_dt", PR_dt); + xml->addpar("A_val", PA_val); + xml->addpar("D_val", PD_val); + xml->addpar("S_val", PS_val); + xml->addpar("R_val", PR_val); - if ((Pfreemode!=0)||(!xml->minimal)) { - for (int i=0;ibeginbranch("POINT",i); - if (i!=0) xml->addpar("dt",Penvdt[i]); - xml->addpar("val",Penvval[i]); + if((Pfreemode != 0) || (!xml->minimal)) { + for(int i = 0; i < Penvpoints; i++) { + xml->beginbranch("POINT", i); + if(i != 0) + xml->addpar("dt", Penvdt[i]); + xml->addpar("val", Penvval[i]); xml->endbranch(); - }; - }; -}; + } + } +} void EnvelopeParams::getfromXML(XMLwrapper *xml) { - Pfreemode=xml->getparbool("free_mode",Pfreemode); - Penvpoints=xml->getpar127("env_points",Penvpoints); - Penvsustain=xml->getpar127("env_sustain",Penvsustain); - Penvstretch=xml->getpar127("env_stretch",Penvstretch); - Pforcedrelease=xml->getparbool("forced_release",Pforcedrelease); - Plinearenvelope=xml->getparbool("linear_envelope",Plinearenvelope); + Pfreemode = xml->getparbool("free_mode", Pfreemode); + Penvpoints = xml->getpar127("env_points", Penvpoints); + Penvsustain = xml->getpar127("env_sustain", Penvsustain); + Penvstretch = xml->getpar127("env_stretch", Penvstretch); + Pforcedrelease = xml->getparbool("forced_release", Pforcedrelease); + Plinearenvelope = xml->getparbool("linear_envelope", Plinearenvelope); - PA_dt=xml->getpar127("A_dt",PA_dt); - PD_dt=xml->getpar127("D_dt",PD_dt); - PR_dt=xml->getpar127("R_dt",PR_dt); - PA_val=xml->getpar127("A_val",PA_val); - PD_val=xml->getpar127("D_val",PD_val); - PS_val=xml->getpar127("S_val",PS_val); - PR_val=xml->getpar127("R_val",PR_val); + PA_dt = xml->getpar127("A_dt", PA_dt); + PD_dt = xml->getpar127("D_dt", PD_dt); + PR_dt = xml->getpar127("R_dt", PR_dt); + PA_val = xml->getpar127("A_val", PA_val); + PD_val = xml->getpar127("D_val", PD_val); + PS_val = xml->getpar127("S_val", PS_val); + PR_val = xml->getpar127("R_val", PR_val); - for (int i=0;ienterbranch("POINT",i)==0) continue; - if (i!=0) Penvdt[i]=xml->getpar127("dt",Penvdt[i]); - Penvval[i]=xml->getpar127("val",Penvval[i]); + for(int i = 0; i < Penvpoints; i++) { + if(xml->enterbranch("POINT", i) == 0) + continue; + if(i != 0) + Penvdt[i] = xml->getpar127("dt", Penvdt[i]); + Penvval[i] = xml->getpar127("val", Penvval[i]); xml->exitbranch(); - }; + } - if (!Pfreemode) converttofree(); -}; + if(!Pfreemode) + converttofree(); +} void EnvelopeParams::defaults() { - Penvstretch=Denvstretch; - Pforcedrelease=Dforcedrelease; - Plinearenvelope=Dlinearenvelope; - PA_dt=DA_dt; - PD_dt=DD_dt; - PR_dt=DR_dt; - PA_val=DA_val; - PD_val=DD_val; - PS_val=DS_val; - PR_val=DR_val; - Pfreemode=0; + Penvstretch = Denvstretch; + Pforcedrelease = Dforcedrelease; + Plinearenvelope = Dlinearenvelope; + PA_dt = DA_dt; + PD_dt = DD_dt; + PR_dt = DR_dt; + PA_val = DA_val; + PD_val = DD_val; + PS_val = DS_val; + PR_val = DR_val; + Pfreemode = 0; converttofree(); -}; +} void EnvelopeParams::store2defaults() { - Denvstretch=Penvstretch; - Dforcedrelease=Pforcedrelease; - Dlinearenvelope=Plinearenvelope; - DA_dt=PA_dt; - DD_dt=PD_dt; - DR_dt=PR_dt; - DA_val=PA_val; - DD_val=PD_val; - DS_val=PS_val; - DR_val=PR_val; -}; + Denvstretch = Penvstretch; + Dforcedrelease = Pforcedrelease; + Dlinearenvelope = Plinearenvelope; + DA_dt = PA_dt; + DD_dt = PD_dt; + DR_dt = PR_dt; + DA_val = PA_val; + DD_val = PD_val; + DS_val = PS_val; + DR_val = PR_val; +} diff --git a/plugins/zynaddsubfx/src/Params/EnvelopeParams.h b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h index d7d44c859..e2fcf3ec8 100644 --- a/plugins/zynaddsubfx/src/Params/EnvelopeParams.h +++ b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h @@ -32,54 +32,58 @@ class EnvelopeParams:public Presets { -public: - EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_); - ~EnvelopeParams(); - void ADSRinit(char A_dt,char D_dt,char S_val,char R_dt); - void ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt); - void ASRinit(char A_val,char A_dt,char R_val,char R_dt); - void ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val); - void ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt); - void converttofree(); + public: + EnvelopeParams(unsigned char Penvstretch_, + unsigned char Pforcedrelease_); + ~EnvelopeParams(); + void ADSRinit(char A_dt, char D_dt, char S_val, char R_dt); + void ADSRinit_dB(char A_dt, char D_dt, char S_val, char R_dt); + void ASRinit(char A_val, char A_dt, char R_val, char R_dt); + void ADSRinit_filter(char A_val, + char A_dt, + char D_val, + char D_dt, + char R_dt, + char R_val); + void ASRinit_bw(char A_val, char A_dt, char R_val, char R_dt); + void converttofree(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - REALTYPE getdt(char i); + REALTYPE getdt(char i); - /* MIDI Parameters */ - unsigned char Pfreemode;//1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... - unsigned char Penvpoints; - unsigned char Penvsustain;//127 pentru dezactivat - unsigned char Penvdt[MAX_ENVELOPE_POINTS]; - unsigned char Penvval[MAX_ENVELOPE_POINTS]; - unsigned char Penvstretch;//64=normal stretch (piano-like), 0=no stretch - unsigned char Pforcedrelease;//0 - OFF, 1 - ON - unsigned char Plinearenvelope;//if the amplitude envelope is linear + /* MIDI Parameters */ + unsigned char Pfreemode; //1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... + unsigned char Penvpoints; + unsigned char Penvsustain; //127 pentru dezactivat + unsigned char Penvdt[MAX_ENVELOPE_POINTS]; + unsigned char Penvval[MAX_ENVELOPE_POINTS]; + unsigned char Penvstretch; //64=normal stretch (piano-like), 0=no stretch + unsigned char Pforcedrelease; //0 - OFF, 1 - ON + unsigned char Plinearenvelope; //if the amplitude envelope is linear - unsigned char PA_dt,PD_dt,PR_dt, - PA_val,PD_val,PS_val,PR_val; + unsigned char PA_dt, PD_dt, PR_dt, + PA_val, PD_val, PS_val, PR_val; - int Envmode;// 1 for ADSR parameters (linear amplitude) - // 2 for ADSR_dB parameters (dB amplitude) - // 3 for ASR parameters (frequency LFO) - // 4 for ADSR_filter parameters (filter parameters) - // 5 for ASR_bw parameters (bandwidth parameters) - -private: - void store2defaults(); - - /* Default parameters */ - unsigned char Denvstretch; - unsigned char Dforcedrelease; - unsigned char Dlinearenvelope; - unsigned char DA_dt,DD_dt,DR_dt, - DA_val,DD_val,DS_val,DR_val; + int Envmode; // 1 for ADSR parameters (linear amplitude) + // 2 for ADSR_dB parameters (dB amplitude) + // 3 for ASR parameters (frequency LFO) + // 4 for ADSR_filter parameters (filter parameters) + // 5 for ASR_bw parameters (bandwidth parameters) + private: + void store2defaults(); + /* Default parameters */ + unsigned char Denvstretch; + unsigned char Dforcedrelease; + unsigned char Dlinearenvelope; + unsigned char DA_dt, DD_dt, DR_dt, + DA_val, DD_val, DS_val, DR_val; }; #endif diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.cpp b/plugins/zynaddsubfx/src/Params/FilterParams.cpp index 861b6d313..a74bf5a99 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.cpp +++ b/plugins/zynaddsubfx/src/Params/FilterParams.cpp @@ -25,58 +25,60 @@ #include #include "FilterParams.h" -FilterParams::FilterParams(unsigned char Ptype_,unsigned char Pfreq_,unsigned char Pq_):Presets() +FilterParams::FilterParams(unsigned char Ptype_, + unsigned char Pfreq_, + unsigned char Pq_):Presets() { setpresettype("Pfilter"); - Dtype=Ptype_; - Dfreq=Pfreq_; - Dq=Pq_; + Dtype = Ptype_; + Dfreq = Pfreq_; + Dq = Pq_; - changed=false; + changed = false; defaults(); -}; +} FilterParams::~FilterParams() -{ -}; +{} void FilterParams::defaults() { - Ptype=Dtype; - Pfreq=Dfreq; - Pq=Dq; + Ptype = Dtype; + Pfreq = Dfreq; + Pq = Dq; - Pstages=0; - Pfreqtrack=64; - Pgain=64; - Pcategory=0; + Pstages = 0; + Pfreqtrack = 64; + Pgain = 64; + Pcategory = 0; - Pnumformants=3; - Pformantslowness=64; - for (int j=0;jPtype; - Pfreq=pars->Pfreq; - Pq=pars->Pq; + Ptype = pars->Ptype; + Pfreq = pars->Pfreq; + Pq = pars->Pq; - Pstages=pars->Pstages; - Pfreqtrack=pars->Pfreqtrack; - Pgain=pars->Pgain; - Pcategory=pars->Pcategory; + Pstages = pars->Pstages; + Pfreqtrack = pars->Pfreqtrack; + Pgain = pars->Pgain; + Pcategory = pars->Pcategory; - Pnumformants=pars->Pnumformants; - Pformantslowness=pars->Pformantslowness; - for (int j=0;jPvowels[j].formants[i].freq; - Pvowels[j].formants[i].q=pars->Pvowels[j].formants[i].q; - Pvowels[j].formants[i].amp=pars->Pvowels[j].formants[i].amp; - }; - }; + Pnumformants = pars->Pnumformants; + Pformantslowness = pars->Pformantslowness; + for(int j = 0; j < FF_MAX_VOWELS; j++) { + for(int i = 0; i < FF_MAX_FORMANTS; i++) { + Pvowels[j].formants[i].freq = pars->Pvowels[j].formants[i].freq; + Pvowels[j].formants[i].q = pars->Pvowels[j].formants[i].q; + Pvowels[j].formants[i].amp = pars->Pvowels[j].formants[i].amp; + } + } - Psequencesize=pars->Psequencesize; - for (int i=0;iPsequence[i].nvowel; + Psequencesize = pars->Psequencesize; + for(int i = 0; i < FF_MAX_SEQUENCE; i++) + Psequence[i].nvowel = pars->Psequence[i].nvowel; - Psequencestretch=pars->Psequencestretch; - Psequencereversed=pars->Psequencereversed; - Pcenterfreq=pars->Pcenterfreq; - Poctavesfreq=pars->Poctavesfreq; - Pvowelclearness=pars->Pvowelclearness; -}; + Psequencestretch = pars->Psequencestretch; + Psequencereversed = pars->Psequencereversed; + Pcenterfreq = pars->Pcenterfreq; + Poctavesfreq = pars->Poctavesfreq; + Pvowelclearness = pars->Pvowelclearness; +} /* @@ -124,243 +128,264 @@ void FilterParams::getfromFilterParams(FilterParams *pars) */ REALTYPE FilterParams::getfreq() { - return((Pfreq/64.0-1.0)*5.0); -}; + return (Pfreq / 64.0 - 1.0) * 5.0; +} REALTYPE FilterParams::getq() { - return(exp(pow((REALTYPE) Pq/127.0,2)*log(1000.0))-0.9); -}; + return exp(pow((REALTYPE) Pq / 127.0, 2) * log(1000.0)) - 0.9; +} REALTYPE FilterParams::getfreqtracking(REALTYPE notefreq) { - return(log(notefreq/440.0)*(Pfreqtrack-64.0)/(64.0*LOG_2)); -}; + return log(notefreq / 440.0) * (Pfreqtrack - 64.0) / (64.0 * LOG_2); +} REALTYPE FilterParams::getgain() { - return((Pgain/64.0-1.0)*30.0);//-30..30dB -}; + return (Pgain / 64.0 - 1.0) * 30.0; //-30..30dB +} /* * Get the center frequency of the formant's graph */ REALTYPE FilterParams::getcenterfreq() { - return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); -}; + return 10000.0 * pow(10, -(1.0 - Pcenterfreq / 127.0) * 2.0); +} /* * Get the number of octave that the formant functions applies to */ REALTYPE FilterParams::getoctavesfreq() { - return(0.25+10.0*Poctavesfreq/127.0); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} /* * Get the frequency from x, where x is [0..1] */ REALTYPE FilterParams::getfreqx(REALTYPE x) { - if (x>1.0) x=1.0; - REALTYPE octf=pow(2.0,getoctavesfreq()); - return(getcenterfreq()/sqrt(octf)*pow(octf,x)); -}; + if(x > 1.0) + x = 1.0; + REALTYPE octf = pow(2.0, getoctavesfreq()); + return getcenterfreq() / sqrt(octf) * pow(octf, x); +} /* * Get the x coordinate from frequency (used by the UI) */ REALTYPE FilterParams::getfreqpos(REALTYPE freq) { - return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); -}; + return (log(freq) - log(getfreqx(0.0))) / log(2.0) / getoctavesfreq(); +} /* * Get the freq. response of the formant filter */ -void FilterParams::formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs) +void FilterParams::formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs) { - REALTYPE c[3],d[3]; - REALTYPE filter_freq,filter_q,filter_amp; - REALTYPE omega,sn,cs,alpha; + REALTYPE c[3], d[3]; + REALTYPE filter_freq, filter_q, filter_amp; + REALTYPE omega, sn, cs, alpha; - for (int i=0;i0) filter_q=(filter_q>1.0 ? pow(filter_q,1.0/(Pstages+1)) : filter_q); + filter_freq = getformantfreq(Pvowels[nvowel].formants[nformant].freq); + filter_q = getformantq(Pvowels[nvowel].formants[nformant].q) * getq(); + if(Pstages > 0) + filter_q = + (filter_q > 1.0 ? pow(filter_q, 1.0 / (Pstages + 1)) : filter_q); - filter_amp=getformantamp(Pvowels[nvowel].formants[nformant].amp); + filter_amp = getformantamp(Pvowels[nvowel].formants[nformant].amp); - if (filter_freq<=(SAMPLE_RATE/2-100.0)) { - omega=2*PI*filter_freq/SAMPLE_RATE; - sn=sin(omega); - cs=cos(omega); - alpha=sn/(2*filter_q); - REALTYPE tmp=1+alpha; - c[0]=alpha/tmp*sqrt(filter_q+1); - c[1]=0; - c[2]=-alpha/tmp*sqrt(filter_q+1); - d[1]=-2*cs/tmp*(-1); - d[2]=(1-alpha)/tmp*(-1); - } else continue; + if(filter_freq <= (SAMPLE_RATE / 2 - 100.0)) { + omega = 2 * PI * filter_freq / SAMPLE_RATE; + sn = sin(omega); + cs = cos(omega); + alpha = sn / (2 * filter_q); + REALTYPE tmp = 1 + alpha; + c[0] = alpha / tmp *sqrt(filter_q + 1); + c[1] = 0; + c[2] = -alpha / tmp *sqrt(filter_q + 1); + d[1] = -2 * cs / tmp * (-1); + d[2] = (1 - alpha) / tmp * (-1); + } + else + continue; - for (int i=0;iSAMPLE_RATE/2) { - for (int tmp=i;tmp SAMPLE_RATE / 2) { + for(int tmp = i; tmp < nfreqs; tmp++) + freqs[tmp] = 0.0; break; - }; - REALTYPE fr=freq/SAMPLE_RATE*PI*2.0; - REALTYPE x=c[0],y=0.0; - for (int n=1;n<3;n++) { - x+=cos(n*fr)*c[n]; - y-=sin(n*fr)*c[n]; - }; - REALTYPE h=x*x+y*y; - x=1.0; - y=0.0; - for (int n=1;n<3;n++) { - x-=cos(n*fr)*d[n]; - y+=sin(n*fr)*d[n]; - }; - h=h/(x*x+y*y); + } + REALTYPE fr = freq / SAMPLE_RATE * PI * 2.0; + REALTYPE x = c[0], y = 0.0; + for(int n = 1; n < 3; n++) { + x += cos(n * fr) * c[n]; + y -= sin(n * fr) * c[n]; + } + REALTYPE h = x * x + y * y; + x = 1.0; + y = 0.0; + for(int n = 1; n < 3; n++) { + x -= cos(n * fr) * d[n]; + y += sin(n * fr) * d[n]; + } + h = h / (x * x + y * y); - freqs[i]+=pow(h,(Pstages+1.0)/2.0)*filter_amp; - }; - }; - for (int i=0;i0.000000001) freqs[i]=rap2dB(freqs[i])+getgain(); - else freqs[i]=-90.0; - }; - -}; + freqs[i] += pow(h, (Pstages + 1.0) / 2.0) * filter_amp; + } + } + for(int i = 0; i < nfreqs; i++) { + if(freqs[i] > 0.000000001) + freqs[i] = rap2dB(freqs[i]) + getgain(); + else + freqs[i] = -90.0; + } +} /* * Transforms a parameter to the real value */ REALTYPE FilterParams::getformantfreq(unsigned char freq) { - REALTYPE result=getfreqx(freq/127.0); - return(result); -}; + REALTYPE result = getfreqx(freq / 127.0); + return result; +} REALTYPE FilterParams::getformantamp(unsigned char amp) { - REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0); - return(result); -}; + REALTYPE result = pow(0.1, (1.0 - amp / 127.0) * 4.0); + return result; +} REALTYPE FilterParams::getformantq(unsigned char q) { //temp - REALTYPE result=pow(25.0,(q-32.0)/64.0); - return(result); -}; + REALTYPE result = pow(25.0, (q - 32.0) / 64.0); + return result; +} -void FilterParams::add2XMLsection(XMLwrapper *xml,int n) +void FilterParams::add2XMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformantbeginbranch("FORMANT",nformant); - xml->addpar("freq",Pvowels[nvowel].formants[nformant].freq); - xml->addpar("amp",Pvowels[nvowel].formants[nformant].amp); - xml->addpar("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + xml->beginbranch("FORMANT", nformant); + xml->addpar("freq", Pvowels[nvowel].formants[nformant].freq); + xml->addpar("amp", Pvowels[nvowel].formants[nformant].amp); + xml->addpar("q", Pvowels[nvowel].formants[nformant].q); xml->endbranch(); - }; -}; + } +} void FilterParams::add2XML(XMLwrapper *xml) { //filter parameters - xml->addpar("category",Pcategory); - xml->addpar("type",Ptype); - xml->addpar("freq",Pfreq); - xml->addpar("q",Pq); - xml->addpar("stages",Pstages); - xml->addpar("freq_track",Pfreqtrack); - xml->addpar("gain",Pgain); + xml->addpar("category", Pcategory); + xml->addpar("type", Ptype); + xml->addpar("freq", Pfreq); + xml->addpar("q", Pq); + xml->addpar("stages", Pstages); + xml->addpar("freq_track", Pfreqtrack); + xml->addpar("gain", Pgain); //formant filter parameters - if ((Pcategory==1)||(!xml->minimal)) { + if((Pcategory == 1) || (!xml->minimal)) { xml->beginbranch("FORMANT_FILTER"); - xml->addpar("num_formants",Pnumformants); - xml->addpar("formant_slowness",Pformantslowness); - xml->addpar("vowel_clearness",Pvowelclearness); - xml->addpar("center_freq",Pcenterfreq); - xml->addpar("octaves_freq",Poctavesfreq); - for (int nvowel=0;nvowelbeginbranch("VOWEL",nvowel); - add2XMLsection(xml,nvowel); + xml->addpar("num_formants", Pnumformants); + xml->addpar("formant_slowness", Pformantslowness); + xml->addpar("vowel_clearness", Pvowelclearness); + xml->addpar("center_freq", Pcenterfreq); + xml->addpar("octaves_freq", Poctavesfreq); + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + xml->beginbranch("VOWEL", nvowel); + add2XMLsection(xml, nvowel); xml->endbranch(); - }; - xml->addpar("sequence_size",Psequencesize); - xml->addpar("sequence_stretch",Psequencestretch); - xml->addparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseqbeginbranch("SEQUENCE_POS",nseq); - xml->addpar("vowel_id",Psequence[nseq].nvowel); + } + xml->addpar("sequence_size", Psequencesize); + xml->addpar("sequence_stretch", Psequencestretch); + xml->addparbool("sequence_reversed", Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + xml->beginbranch("SEQUENCE_POS", nseq); + xml->addpar("vowel_id", Psequence[nseq].nvowel); xml->endbranch(); - }; + } xml->endbranch(); - }; -}; + } +} -void FilterParams::getfromXMLsection(XMLwrapper *xml,int n) +void FilterParams::getfromXMLsection(XMLwrapper *xml, int n) { - int nvowel=n; - for (int nformant=0;nformantenterbranch("FORMANT",nformant)==0) continue; - Pvowels[nvowel].formants[nformant].freq=xml->getpar127("freq",Pvowels[nvowel].formants[nformant].freq); - Pvowels[nvowel].formants[nformant].amp=xml->getpar127("amp",Pvowels[nvowel].formants[nformant].amp); - Pvowels[nvowel].formants[nformant].q=xml->getpar127("q",Pvowels[nvowel].formants[nformant].q); + int nvowel = n; + for(int nformant = 0; nformant < FF_MAX_FORMANTS; nformant++) { + if(xml->enterbranch("FORMANT", nformant) == 0) + continue; + Pvowels[nvowel].formants[nformant].freq = xml->getpar127( + "freq", + Pvowels[nvowel + ].formants[nformant].freq); + Pvowels[nvowel].formants[nformant].amp = xml->getpar127( + "amp", + Pvowels[nvowel + ].formants[nformant].amp); + Pvowels[nvowel].formants[nformant].q = + xml->getpar127("q", Pvowels[nvowel].formants[nformant].q); xml->exitbranch(); - }; -}; + } +} void FilterParams::getfromXML(XMLwrapper *xml) { //filter parameters - Pcategory=xml->getpar127("category",Pcategory); - Ptype=xml->getpar127("type",Ptype); - Pfreq=xml->getpar127("freq",Pfreq); - Pq=xml->getpar127("q",Pq); - Pstages=xml->getpar127("stages",Pstages); - Pfreqtrack=xml->getpar127("freq_track",Pfreqtrack); - Pgain=xml->getpar127("gain",Pgain); + Pcategory = xml->getpar127("category", Pcategory); + Ptype = xml->getpar127("type", Ptype); + Pfreq = xml->getpar127("freq", Pfreq); + Pq = xml->getpar127("q", Pq); + Pstages = xml->getpar127("stages", Pstages); + Pfreqtrack = xml->getpar127("freq_track", Pfreqtrack); + Pgain = xml->getpar127("gain", Pgain); //formant filter parameters - if (xml->enterbranch("FORMANT_FILTER")) { - Pnumformants=xml->getpar127("num_formants",Pnumformants); - Pformantslowness=xml->getpar127("formant_slowness",Pformantslowness); - Pvowelclearness=xml->getpar127("vowel_clearness",Pvowelclearness); - Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); - Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); + if(xml->enterbranch("FORMANT_FILTER")) { + Pnumformants = xml->getpar127("num_formants", Pnumformants); + Pformantslowness = xml->getpar127("formant_slowness", Pformantslowness); + Pvowelclearness = xml->getpar127("vowel_clearness", Pvowelclearness); + Pcenterfreq = xml->getpar127("center_freq", Pcenterfreq); + Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq); - for (int nvowel=0;nvowelenterbranch("VOWEL",nvowel)==0) continue; - getfromXMLsection(xml,nvowel); + for(int nvowel = 0; nvowel < FF_MAX_VOWELS; nvowel++) { + if(xml->enterbranch("VOWEL", nvowel) == 0) + continue; + getfromXMLsection(xml, nvowel); xml->exitbranch(); - }; - Psequencesize=xml->getpar127("sequence_size",Psequencesize); - Psequencestretch=xml->getpar127("sequence_stretch",Psequencestretch); - Psequencereversed=xml->getparbool("sequence_reversed",Psequencereversed); - for (int nseq=0;nseqenterbranch("SEQUENCE_POS",nseq)==0) continue; - Psequence[nseq].nvowel=xml->getpar("vowel_id",Psequence[nseq].nvowel,0,FF_MAX_VOWELS-1); + } + Psequencesize = xml->getpar127("sequence_size", Psequencesize); + Psequencestretch = xml->getpar127("sequence_stretch", Psequencestretch); + Psequencereversed = xml->getparbool("sequence_reversed", + Psequencereversed); + for(int nseq = 0; nseq < FF_MAX_SEQUENCE; nseq++) { + if(xml->enterbranch("SEQUENCE_POS", nseq) == 0) + continue; + Psequence[nseq].nvowel = xml->getpar("vowel_id", + Psequence[nseq].nvowel, + 0, + FF_MAX_VOWELS - 1); xml->exitbranch(); - }; + } xml->exitbranch(); - }; - -}; + } +} diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.h b/plugins/zynaddsubfx/src/Params/FilterParams.h index 89c8b46ad..2a1df6b28 100644 --- a/plugins/zynaddsubfx/src/Params/FilterParams.h +++ b/plugins/zynaddsubfx/src/Params/FilterParams.h @@ -29,72 +29,74 @@ class FilterParams:public Presets { -public: - FilterParams(unsigned char Ptype_,unsigned char Pfreq,unsigned char Pq_); - ~FilterParams(); + public: + FilterParams(unsigned char Ptype_, + unsigned char Pfreq, + unsigned char Pq_); + ~FilterParams(); - void add2XML(XMLwrapper *xml); - void add2XMLsection(XMLwrapper *xml,int n); - void defaults(); - void getfromXML(XMLwrapper *xml); - void getfromXMLsection(XMLwrapper *xml,int n); + void add2XML(XMLwrapper *xml); + void add2XMLsection(XMLwrapper *xml, int n); + void defaults(); + void getfromXML(XMLwrapper *xml); + void getfromXMLsection(XMLwrapper *xml, int n); - void getfromFilterParams(FilterParams *pars); + void getfromFilterParams(FilterParams *pars); - REALTYPE getfreq(); - REALTYPE getq(); - REALTYPE getfreqtracking(REALTYPE notefreq); - REALTYPE getgain(); + REALTYPE getfreq(); + REALTYPE getq(); + REALTYPE getfreqtracking(REALTYPE notefreq); + REALTYPE getgain(); - unsigned char Pcategory;//Filter category (Analog/Formant/StVar) - unsigned char Ptype;// Filter type (for analog lpf,hpf,bpf..) - unsigned char Pfreq;// Frequency (64-central frequency) - unsigned char Pq; // Q parameters (resonance or bandwidth) - unsigned char Pstages; //filter stages+1 - unsigned char Pfreqtrack;//how the filter frequency is changing according the note frequency - unsigned char Pgain;//filter's output gain + unsigned char Pcategory; //Filter category (Analog/Formant/StVar) + unsigned char Ptype; // Filter type (for analog lpf,hpf,bpf..) + unsigned char Pfreq; // Frequency (64-central frequency) + unsigned char Pq; // Q parameters (resonance or bandwidth) + unsigned char Pstages; //filter stages+1 + unsigned char Pfreqtrack; //how the filter frequency is changing according the note frequency + unsigned char Pgain; //filter's output gain - //Formant filter parameters - unsigned char Pnumformants;//how many formants are used - unsigned char Pformantslowness;//how slow varies the formants - unsigned char Pvowelclearness;//how vowels are kept clean (how much try to avoid "mixed" vowels) - unsigned char Pcenterfreq,Poctavesfreq;//the center frequency of the res. func., and the number of octaves + //Formant filter parameters + unsigned char Pnumformants; //how many formants are used + unsigned char Pformantslowness; //how slow varies the formants + unsigned char Pvowelclearness; //how vowels are kept clean (how much try to avoid "mixed" vowels) + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves - struct { struct { - unsigned char freq,amp,q;//frequency,amplitude,Q - }formants[FF_MAX_FORMANTS]; - }Pvowels[FF_MAX_VOWELS]; + struct { + unsigned char freq, amp, q; //frequency,amplitude,Q + } formants[FF_MAX_FORMANTS]; + } Pvowels[FF_MAX_VOWELS]; - unsigned char Psequencesize;//how many vowels are in the sequence - unsigned char Psequencestretch;//how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") - unsigned char Psequencereversed;//if the input from filter envelopes/LFOs/etc. is reversed(negated) - struct { - unsigned char nvowel;//the vowel from the position - } Psequence[FF_MAX_SEQUENCE]; + unsigned char Psequencesize; //how many vowels are in the sequence + unsigned char Psequencestretch; //how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") + unsigned char Psequencereversed; //if the input from filter envelopes/LFOs/etc. is reversed(negated) + struct { + unsigned char nvowel; //the vowel from the position + } Psequence[FF_MAX_SEQUENCE]; - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); - void formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs);//used by UI + void formantfilterH(int nvowel, int nfreqs, REALTYPE *freqs); //used by UI - REALTYPE getformantfreq(unsigned char freq); - REALTYPE getformantamp(unsigned char amp); - REALTYPE getformantq(unsigned char q); + REALTYPE getformantfreq(unsigned char freq); + REALTYPE getformantamp(unsigned char amp); + REALTYPE getformantq(unsigned char q); - bool changed; + bool changed; -private: - void defaults(int n); + private: + void defaults(int n); - //stored default parameters - unsigned char Dtype; - unsigned char Dfreq; - unsigned char Dq; + //stored default parameters + unsigned char Dtype; + unsigned char Dfreq; + unsigned char Dq; }; #endif diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.cpp b/plugins/zynaddsubfx/src/Params/LFOParams.cpp index a124c5937..3cfc37fc8 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.cpp +++ b/plugins/zynaddsubfx/src/Params/LFOParams.cpp @@ -27,9 +27,16 @@ int LFOParams::time; -LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous_,char fel_):Presets() +LFOParams::LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous_, + char fel_):Presets() { - switch (fel_) { + switch(fel_) { case 0: setpresettype("Plfofrequency"); break; @@ -39,61 +46,60 @@ LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOty case 2: setpresettype("Plfofilter"); break; - }; - Dfreq=Pfreq_; - Dintensity=Pintensity_; - Dstartphase=Pstartphase_; - DLFOtype=PLFOtype_; - Drandomness=Prandomness_; - Ddelay=Pdelay_; - Dcontinous=Pcontinous_; - fel=fel_; - time=0; + } + Dfreq = Pfreq_; + Dintensity = Pintensity_; + Dstartphase = Pstartphase_; + DLFOtype = PLFOtype_; + Drandomness = Prandomness_; + Ddelay = Pdelay_; + Dcontinous = Pcontinous_; + fel = fel_; + time = 0; defaults(); -}; +} LFOParams::~LFOParams() -{ -}; +{} void LFOParams::defaults() { - Pfreq=Dfreq/127.0; - Pintensity=Dintensity; - Pstartphase=Dstartphase; - PLFOtype=DLFOtype; - Prandomness=Drandomness; - Pdelay=Ddelay; - Pcontinous=Dcontinous; - Pfreqrand=0; - Pstretch=64; -}; + Pfreq = Dfreq / 127.0; + Pintensity = Dintensity; + Pstartphase = Dstartphase; + PLFOtype = DLFOtype; + Prandomness = Drandomness; + Pdelay = Ddelay; + Pcontinous = Dcontinous; + Pfreqrand = 0; + Pstretch = 64; +} void LFOParams::add2XML(XMLwrapper *xml) { - xml->addparreal("freq",Pfreq); - xml->addpar("intensity",Pintensity); - xml->addpar("start_phase",Pstartphase); - xml->addpar("lfo_type",PLFOtype); - xml->addpar("randomness_amplitude",Prandomness); - xml->addpar("randomness_frequency",Pfreqrand); - xml->addpar("delay",Pdelay); - xml->addpar("stretch",Pstretch); - xml->addparbool("continous",Pcontinous); -}; + xml->addparreal("freq", Pfreq); + xml->addpar("intensity", Pintensity); + xml->addpar("start_phase", Pstartphase); + xml->addpar("lfo_type", PLFOtype); + xml->addpar("randomness_amplitude", Prandomness); + xml->addpar("randomness_frequency", Pfreqrand); + xml->addpar("delay", Pdelay); + xml->addpar("stretch", Pstretch); + xml->addparbool("continous", Pcontinous); +} void LFOParams::getfromXML(XMLwrapper *xml) { - Pfreq=xml->getparreal("freq",Pfreq,0.0,1.0); - Pintensity=xml->getpar127("intensity",Pintensity); - Pstartphase=xml->getpar127("start_phase",Pstartphase); - PLFOtype=xml->getpar127("lfo_type",PLFOtype); - Prandomness=xml->getpar127("randomness_amplitude",Prandomness); - Pfreqrand=xml->getpar127("randomness_frequency",Pfreqrand); - Pdelay=xml->getpar127("delay",Pdelay); - Pstretch=xml->getpar127("stretch",Pstretch); - Pcontinous=xml->getparbool("continous",Pcontinous); -}; + Pfreq = xml->getparreal("freq", Pfreq, 0.0, 1.0); + Pintensity = xml->getpar127("intensity", Pintensity); + Pstartphase = xml->getpar127("start_phase", Pstartphase); + PLFOtype = xml->getpar127("lfo_type", PLFOtype); + Prandomness = xml->getpar127("randomness_amplitude", Prandomness); + Pfreqrand = xml->getpar127("randomness_frequency", Pfreqrand); + Pdelay = xml->getpar127("delay", Pdelay); + Pstretch = xml->getpar127("stretch", Pstretch); + Pcontinous = xml->getparbool("continous", Pcontinous); +} diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.h b/plugins/zynaddsubfx/src/Params/LFOParams.h index a650d27f3..6a7dcd915 100644 --- a/plugins/zynaddsubfx/src/Params/LFOParams.h +++ b/plugins/zynaddsubfx/src/Params/LFOParams.h @@ -28,38 +28,45 @@ class LFOParams:public Presets { -public: - LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous,char fel_); - ~LFOParams(); + public: + LFOParams(char Pfreq_, + char Pintensity_, + char Pstartphase_, + char PLFOtype_, + char Prandomness_, + char Pdelay_, + char Pcontinous, + char fel_); + ~LFOParams(); - void add2XML(XMLwrapper *xml); - void defaults(); - /**Loads the LFO from the xml*/ - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + /**Loads the LFO from the xml*/ + void getfromXML(XMLwrapper *xml); - /* MIDI Parameters*/ - REALTYPE Pfreq; /**ADvsPAD=true; + resonance = new Resonance(); + oscilgen = new OscilGen(fft_, resonance); + oscilgen->ADvsPAD = true; - FreqEnvelope=new EnvelopeParams(0,0); - FreqEnvelope->ASRinit(64,50,64,60); - FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + FreqEnvelope = new EnvelopeParams(0, 0); + FreqEnvelope->ASRinit(64, 50, 64, 60); + FreqLfo = new LFOParams(70, 0, 64, 0, 0, 0, 0, 0); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + AmpLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 1); - GlobalFilter=new FilterParams(2,94,40); - FilterEnvelope=new EnvelopeParams(0,1); - FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); - FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); + GlobalFilter = new FilterParams(2, 94, 40); + FilterEnvelope = new EnvelopeParams(0, 1); + FilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); + FilterLfo = new LFOParams(80, 0, 64, 0, 0, 0, 0, 2); - for (int i=0;idefaults(); oscilgen->defaults(); - Phrpos.type=0; - Phrpos.par1=64; - Phrpos.par2=64; - Phrpos.par3=0; + Phrpos.type = 0; + Phrpos.par1 = 64; + Phrpos.par2 = 64; + Phrpos.par3 = 0; - Pquality.samplesize=3; - Pquality.basenote=4; - Pquality.oct=3; - Pquality.smpoct=2; + Pquality.samplesize = 3; + Pquality.basenote = 4; + Pquality.oct = 3; + Pquality.smpoct = 2; - PStereo=1;//stereo + PStereo = 1; //stereo /* Frequency Global Parameters */ - Pfixedfreq=0; - PfixedfreqET=0; - PDetune=8192;//zero - PCoarseDetune=0; - PDetuneType=1; + Pfixedfreq = 0; + PfixedfreqET = 0; + PDetune = 8192; //zero + PCoarseDetune = 0; + PDetuneType = 1; FreqEnvelope->defaults(); FreqLfo->defaults(); /* Amplitude Global Parameters */ - PVolume=90; - PPanning=64;//center - PAmpVelocityScaleFunction=64; + PVolume = 90; + PPanning = 64; //center + PAmpVelocityScaleFunction = 64; AmpEnvelope->defaults(); AmpLfo->defaults(); - PPunchStrength=0; - PPunchTime=60; - PPunchStretch=64; - PPunchVelocitySensing=72; + PPunchStrength = 0; + PPunchTime = 60; + PPunchStretch = 64; + PPunchVelocitySensing = 72; /* Filter Global Parameters*/ - PFilterVelocityScale=64; - PFilterVelocityScaleFunction=64; + PFilterVelocityScale = 64; + PFilterVelocityScaleFunction = 64; GlobalFilter->defaults(); FilterEnvelope->defaults(); FilterLfo->defaults(); deletesamples(); -}; +} void PADnoteParameters::deletesample(int n) { - if ((n<0)||(n>=PAD_MAX_SAMPLES)) return; - if (sample[n].smp!=NULL) { - delete[]sample[n].smp; - sample[n].smp=NULL; - }; - sample[n].size=0; - sample[n].basefreq=440.0; -}; + if((n < 0) || (n >= PAD_MAX_SAMPLES)) + return; + if(sample[n].smp != NULL) { + delete[] sample[n].smp; + sample[n].smp = NULL; + } + sample[n].size = 0; + sample[n].basefreq = 440.0; +} void PADnoteParameters::deletesamples() { - for (int i=0;i1.0) { - x=1.0; - makezero=true; - }; - }; + x = (x - 0.5) * width + 0.5; + if(x < 0.0) { + x = 0.0; + makezero = true; + } + else { + if(x > 1.0) { + x = 1.0; + makezero = true; + } + } //compute the full profile or one half - switch (Php.onehalf) { + switch(Php.onehalf) { case 1: - x=x*0.5+0.5; + x = x * 0.5 + 0.5; break; case 2: - x=x*0.5; + x = x * 0.5; break; - }; + } - REALTYPE x_before_freq_mult=x; + REALTYPE x_before_freq_mult = x; //do the frequency multiplier - x*=freqmult; + x *= freqmult; //do the modulation of the profile - x+=sin(x_before_freq_mult*3.1415926*modfreq)*modpar1; - x=fmod(x+1000.0,1.0)*2.0-1.0; + x += sin(x_before_freq_mult * 3.1415926 * modfreq) * modpar1; + x = fmod(x + 1000.0, 1.0) * 2.0 - 1.0; //this is the base function of the profile REALTYPE f; - switch (Php.base.type) { + switch(Php.base.type) { case 1: - f=exp(-(x*x)*basepar); - if (f<0.4) f=0.0; - else f=1.0; + f = exp(-(x * x) * basepar); + if(f < 0.4) + f = 0.0; + else + f = 1.0; break; case 2: - f=exp(-(fabs(x))*sqrt(basepar)); + f = exp(-(fabs(x)) * sqrt(basepar)); break; default: - f=exp(-(x*x)*basepar); + f = exp(-(x * x) * basepar); break; - }; - if (makezero) f=0.0; + } + if(makezero) + f = 0.0; - REALTYPE amp=1.0; - origx=origx*2.0-1.0; + REALTYPE amp = 1.0; + origx = origx * 2.0 - 1.0; //compute the amplitude multiplier - switch (Php.amp.type) { + switch(Php.amp.type) { case 1: - amp=exp(-(origx*origx)*10.0*amppar1); + amp = exp(-(origx * origx) * 10.0 * amppar1); break; case 2: - amp=0.5*(1.0+cos(3.1415926*origx*sqrt(amppar1*4.0+1.0))); + amp = 0.5 * (1.0 + cos(3.1415926 * origx * sqrt(amppar1 * 4.0 + 1.0))); break; case 3: - amp=1.0/(pow(origx*(amppar1*2.0+0.8),14.0)+1.0); + amp = 1.0 / (pow(origx * (amppar1 * 2.0 + 0.8), 14.0) + 1.0); break; - }; + } //apply the amplitude multiplier - REALTYPE finalsmp=f; - if (Php.amp.type!=0) { - switch (Php.amp.mode) { + REALTYPE finalsmp = f; + if(Php.amp.type != 0) + switch(Php.amp.mode) { case 0: - finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2; + finalsmp = amp * (1.0 - amppar2) + finalsmp * amppar2; break; case 1: - finalsmp*=amp*(1.0-amppar2)+amppar2; + finalsmp *= amp * (1.0 - amppar2) + amppar2; break; case 2: - finalsmp=finalsmp/(amp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = finalsmp / (amp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; case 3: - finalsmp=amp/(finalsmp+pow(amppar2,4.0)*20.0+0.0001); + finalsmp = amp / (finalsmp + pow(amppar2, 4.0) * 20.0 + 0.0001); break; - }; - }; + } + ; - smp[i/supersample]+=finalsmp/supersample; - }; + smp[i / supersample] += finalsmp / supersample; + } //normalize the profile (make the max. to be equal to 1.0) - REALTYPE max=0.0; - for (int i=0;imax) max=smp[i]; - }; - if (max<0.00001) max=1.0; - for (int i=0;i max) + max = smp[i]; + } + if(max < 0.00001) + max = 1.0; + for(int i = 0; i < size; i++) + smp[i] /= max; - if (!Php.autoscale) return(0.5); + if(!Php.autoscale) + return 0.5; //compute the estimated perceived bandwidth - REALTYPE sum=0.0; - int i; - for (i=0;i=4.0) break; - }; + REALTYPE sum = 0.0; + int i; + for(i = 0; i < size / 2 - 2; i++) { + sum += smp[i] * smp[i] + smp[size - i - 1] * smp[size - i - 1]; + if(sum >= 4.0) + break; + } - REALTYPE result=1.0-2.0*i/(REALTYPE) size; - return(result); -}; + REALTYPE result = 1.0 - 2.0 * i / (REALTYPE) size; + return result; +} /* * Compute the real bandwidth in cents and returns it @@ -287,340 +306,412 @@ REALTYPE PADnoteParameters::getprofile(REALTYPE *smp,int size) */ REALTYPE PADnoteParameters::setPbandwidth(int Pbandwidth) { - this->Pbandwidth=Pbandwidth; - REALTYPE result=pow(Pbandwidth/1000.0,1.1); - result=pow(10.0,result*4.0)*0.25; - return(result); -}; + this->Pbandwidth = Pbandwidth; + REALTYPE result = pow(Pbandwidth / 1000.0, 1.1); + result = pow(10.0, result * 4.0) * 0.25; + return result; +} /* * Get the harmonic(overtone) position */ REALTYPE PADnoteParameters::getNhr(int n) { - REALTYPE result=1.0; - REALTYPE par1=pow(10.0,-(1.0-Phrpos.par1/255.0)*3.0); - REALTYPE par2=Phrpos.par2/255.0; + REALTYPE result = 1.0; + REALTYPE par1 = pow(10.0, -(1.0 - Phrpos.par1 / 255.0) * 3.0); + REALTYPE par2 = Phrpos.par2 / 255.0; - REALTYPE n0=n-1.0; - REALTYPE tmp=0.0; - int thresh=0; - switch (Phrpos.type) { + REALTYPE n0 = n - 1.0; + REALTYPE tmp = 0.0; + int thresh = 0; + switch(Phrpos.type) { case 1: - thresh=(int)(par2*par2*100.0)+1; - if (nget(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;imax) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; - for (int nh=1;nhSAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; - if (harmonics[nh-1]<1e-4) continue; + for(int nh = 1; nh < OSCIL_SIZE / 2; nh++) { //for each harmonic + REALTYPE realfreq = getNhr(nh) * basefreq; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; + if(harmonics[nh - 1] < 1e-4) + continue; //compute the bandwidth of each harmonic - REALTYPE bandwidthcents=setPbandwidth(Pbandwidth); - REALTYPE bw=(pow(2.0,bandwidthcents/1200.0)-1.0)*basefreq/bwadjust; - REALTYPE power=1.0; - switch (Pbwscale) { + REALTYPE bandwidthcents = setPbandwidth(Pbandwidth); + REALTYPE bw = + (pow(2.0, bandwidthcents / 1200.0) - 1.0) * basefreq / bwadjust; + REALTYPE power = 1.0; + switch(Pbwscale) { case 0: - power=1.0; + power = 1.0; break; case 1: - power=0.0; + power = 0.0; break; case 2: - power=0.25; + power = 0.25; break; case 3: - power=0.5; + power = 0.5; break; case 4: - power=0.75; + power = 0.75; break; case 5: - power=1.5; + power = 1.5; break; case 6: - power=2.0; + power = 2.0; break; case 7: - power=-0.5; + power = -0.5; break; - }; - bw=bw*pow(realfreq/basefreq,power); - int ibw=(int)((bw/(SAMPLE_RATE*0.5)*size))+1; + } + bw = bw * pow(realfreq / basefreq, power); + int ibw = (int)((bw / (SAMPLE_RATE * 0.5) * size)) + 1; - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); - if (ibw>profilesize) {//if the bandwidth is larger than the profilesize - REALTYPE rap=sqrt((REALTYPE)profilesize/(REALTYPE)ibw); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size)-ibw/2; - for (int i=0;i=size) break; - spectrum[spfreq]+=amp*profile[src]*rap; - }; - } else {//if the bandwidth is smaller than the profilesize - REALTYPE rap=sqrt((REALTYPE)ibw/(REALTYPE)profilesize); - REALTYPE ibasefreq=realfreq/(SAMPLE_RATE*0.5)*size; - for (int i=0;i=size-1) break; - spectrum[spfreq]+=amp*profile[i]*rap*(1.0-fspfreq); - spectrum[spfreq+1]+=amp*profile[i]*rap*fspfreq; - }; - }; - }; -}; + if(ibw > profilesize) { //if the bandwidth is larger than the profilesize + REALTYPE rap = sqrt((REALTYPE)profilesize / (REALTYPE)ibw); + int cfreq = + (int) (realfreq / (SAMPLE_RATE * 0.5) * size) - ibw / 2; + for(int i = 0; i < ibw; i++) { + int src = (int)(i * rap * rap); + int spfreq = i + cfreq; + if(spfreq < 0) + continue; + if(spfreq >= size) + break; + spectrum[spfreq] += amp * profile[src] * rap; + } + } + else { //if the bandwidth is smaller than the profilesize + REALTYPE rap = sqrt((REALTYPE)ibw / (REALTYPE)profilesize); + REALTYPE ibasefreq = realfreq / (SAMPLE_RATE * 0.5) * size; + for(int i = 0; i < profilesize; i++) { + REALTYPE idfreq = i / (REALTYPE)profilesize - 0.5; + idfreq *= ibw; + int spfreq = (int) (idfreq + ibasefreq); + REALTYPE fspfreq = fmod(idfreq + ibasefreq, 1.0); + if(spfreq <= 0) + continue; + if(spfreq >= size - 1) + break; + spectrum[spfreq] += amp * profile[i] * rap * (1.0 - fspfreq); + spectrum[spfreq + 1] += amp * profile[i] * rap * fspfreq; + } + } + } +} /* * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random) */ -void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust) +void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust) { - for (int i=0;iget(harmonics,basefreq,false); + oscilgen->get(harmonics, basefreq, false); //normalize - REALTYPE max=0.0; - for (int i=0;imax) max=harmonics[i]; - if (max<0.000001) max=1; - for (int i=0;i max) + max = harmonics[i]; + if(max < 0.000001) + max = 1; + for(int i = 0; i < OSCIL_SIZE / 2; i++) + harmonics[i] /= max; - for (int nh=1;nhSAMPLE_RATE*0.49999) break; - if (realfreq<20.0) break; + if(realfreq > SAMPLE_RATE * 0.49999) + break; + if(realfreq < 20.0) + break; // if (harmonics[nh-1]<1e-4) continue; - REALTYPE amp=harmonics[nh-1]; - if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); - int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size); + REALTYPE amp = harmonics[nh - 1]; + if(resonance->Penabled) + amp *= resonance->getfreqresponse(realfreq); + int cfreq = (int) (realfreq / (SAMPLE_RATE * 0.5) * size); - spectrum[cfreq]=amp+1e-9; - }; + spectrum[cfreq] = amp + 1e-9; + } - if (Pmode!=1) { - int old=0; - for (int k=1;k1e-10) || (k==(size-1)) ) { - int delta=k-old; - REALTYPE val1=spectrum[old]; - REALTYPE val2=spectrum[k]; - REALTYPE idelta=1.0/delta; - for (int i=0;i 1e-10) || (k == (size - 1))) { + int delta = k - old; + REALTYPE val1 = spectrum[old]; + REALTYPE val2 = spectrum[k]; + REALTYPE idelta = 1.0 / delta; + for(int i = 0; i < delta; i++) { + REALTYPE x = idelta * i; + spectrum[old + i] = val1 * (1.0 - x) + val2 * x; + } + old = k; + } + } + } +} /* * Applies the parameters (i.e. computes all the samples, based on parameters); */ void PADnoteParameters::applyparameters(bool lockmutex) { - const int samplesize=(((int) 1)<<(Pquality.samplesize+14)); - int spectrumsize=samplesize/2; + const int samplesize = (((int) 1) << (Pquality.samplesize + 14)); + int spectrumsize = samplesize / 2; REALTYPE spectrum[spectrumsize]; - int profilesize=512; + int profilesize = 512; REALTYPE profile[profilesize]; - REALTYPE bwadjust=getprofile(profile,profilesize); + REALTYPE bwadjust = getprofile(profile, profilesize); // for (int i=0;ifreqs2smps(fftfreqs,newsample.smp);//that's all; here is the only ifft for the whole sample; no windows are used ;-) + newsample.smp[0] = 0.0; + for(int i = 1; i < spectrumsize; i++) { //randomize the phases + REALTYPE phase = RND * 6.29; + fftfreqs.c[i] = spectrum[i] * cos(phase); + fftfreqs.s[i] = spectrum[i] * sin(phase); + } + fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-) //normalize(rms) - REALTYPE rms=0.0; - for (int i=0;iinformation.PADsynth_used=true; + xml->setPadSynth(true); - xml->addparbool("stereo",PStereo); - xml->addpar("mode",Pmode); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addparbool("stereo", PStereo); + xml->addpar("mode", Pmode); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); xml->beginbranch("HARMONIC_PROFILE"); - xml->addpar("base_type",Php.base.type); - xml->addpar("base_par1",Php.base.par1); - xml->addpar("frequency_multiplier",Php.freqmult); - xml->addpar("modulator_par1",Php.modulator.par1); - xml->addpar("modulator_frequency",Php.modulator.freq); - xml->addpar("width",Php.width); - xml->addpar("amplitude_multiplier_type",Php.amp.type); - xml->addpar("amplitude_multiplier_mode",Php.amp.mode); - xml->addpar("amplitude_multiplier_par1",Php.amp.par1); - xml->addpar("amplitude_multiplier_par2",Php.amp.par2); - xml->addparbool("autoscale",Php.autoscale); - xml->addpar("one_half",Php.onehalf); + xml->addpar("base_type", Php.base.type); + xml->addpar("base_par1", Php.base.par1); + xml->addpar("frequency_multiplier", Php.freqmult); + xml->addpar("modulator_par1", Php.modulator.par1); + xml->addpar("modulator_frequency", Php.modulator.freq); + xml->addpar("width", Php.width); + xml->addpar("amplitude_multiplier_type", Php.amp.type); + xml->addpar("amplitude_multiplier_mode", Php.amp.mode); + xml->addpar("amplitude_multiplier_par1", Php.amp.par1); + xml->addpar("amplitude_multiplier_par2", Php.amp.par2); + xml->addparbool("autoscale", Php.autoscale); + xml->addpar("one_half", Php.onehalf); xml->endbranch(); xml->beginbranch("OSCIL"); @@ -632,27 +723,27 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("HARMONIC_POSITION"); - xml->addpar("type",Phrpos.type); - xml->addpar("parameter1",Phrpos.par1); - xml->addpar("parameter2",Phrpos.par2); - xml->addpar("parameter3",Phrpos.par3); + xml->addpar("type", Phrpos.type); + xml->addpar("parameter1", Phrpos.par1); + xml->addpar("parameter2", Phrpos.par2); + xml->addpar("parameter3", Phrpos.par3); xml->endbranch(); xml->beginbranch("SAMPLE_QUALITY"); - xml->addpar("samplesize",Pquality.samplesize); - xml->addpar("basenote",Pquality.basenote); - xml->addpar("octaves",Pquality.oct); - xml->addpar("samples_per_octave",Pquality.smpoct); + xml->addpar("samplesize", Pquality.samplesize); + xml->addpar("basenote", Pquality.basenote); + xml->addpar("octaves", Pquality.oct); + xml->addpar("samples_per_octave", Pquality.smpoct); xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); - xml->addpar("punch_strength",PPunchStrength); - xml->addpar("punch_time",PPunchTime); - xml->addpar("punch_stretch",PPunchStretch); - xml->addpar("punch_velocity_sensing",PPunchVelocitySensing); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); + xml->addpar("punch_strength", PPunchStrength); + xml->addpar("punch_time", PPunchTime); + xml->addpar("punch_stretch", PPunchStretch); + xml->addpar("punch_velocity_sensing", PPunchVelocitySensing); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); @@ -665,11 +756,11 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addpar("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); @@ -681,8 +772,8 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addpar("velocity_sensing_amplitude",PFilterVelocityScale); - xml->addpar("velocity_sensing",PFilterVelocityScaleFunction); + xml->addpar("velocity_sensing_amplitude", PFilterVelocityScale); + xml->addpar("velocity_sensing", PFilterVelocityScaleFunction); xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); @@ -696,65 +787,75 @@ void PADnoteParameters::add2XML(XMLwrapper *xml) FilterLfo->add2XML(xml); xml->endbranch(); xml->endbranch(); -}; +} void PADnoteParameters::getfromXML(XMLwrapper *xml) { - PStereo=xml->getparbool("stereo",PStereo); - Pmode=xml->getpar127("mode",0); - Pbandwidth=xml->getpar("bandwidth",Pbandwidth,0,1000); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + PStereo = xml->getparbool("stereo", PStereo); + Pmode = xml->getpar127("mode", 0); + Pbandwidth = xml->getpar("bandwidth", Pbandwidth, 0, 1000); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); - if (xml->enterbranch("HARMONIC_PROFILE")) { - Php.base.type=xml->getpar127("base_type",Php.base.type); - Php.base.par1=xml->getpar127("base_par1",Php.base.par1); - Php.freqmult=xml->getpar127("frequency_multiplier",Php.freqmult); - Php.modulator.par1=xml->getpar127("modulator_par1",Php.modulator.par1); - Php.modulator.freq=xml->getpar127("modulator_frequency",Php.modulator.freq); - Php.width=xml->getpar127("width",Php.width); - Php.amp.type=xml->getpar127("amplitude_multiplier_type",Php.amp.type); - Php.amp.mode=xml->getpar127("amplitude_multiplier_mode",Php.amp.mode); - Php.amp.par1=xml->getpar127("amplitude_multiplier_par1",Php.amp.par1); - Php.amp.par2=xml->getpar127("amplitude_multiplier_par2",Php.amp.par2); - Php.autoscale=xml->getparbool("autoscale",Php.autoscale); - Php.onehalf=xml->getpar127("one_half",Php.onehalf); + if(xml->enterbranch("HARMONIC_PROFILE")) { + Php.base.type = xml->getpar127("base_type", Php.base.type); + Php.base.par1 = xml->getpar127("base_par1", Php.base.par1); + Php.freqmult = xml->getpar127("frequency_multiplier", + Php.freqmult); + Php.modulator.par1 = xml->getpar127("modulator_par1", + Php.modulator.par1); + Php.modulator.freq = xml->getpar127("modulator_frequency", + Php.modulator.freq); + Php.width = xml->getpar127("width", Php.width); + Php.amp.type = xml->getpar127("amplitude_multiplier_type", + Php.amp.type); + Php.amp.mode = xml->getpar127("amplitude_multiplier_mode", + Php.amp.mode); + Php.amp.par1 = xml->getpar127("amplitude_multiplier_par1", + Php.amp.par1); + Php.amp.par2 = xml->getpar127("amplitude_multiplier_par2", + Php.amp.par2); + Php.autoscale = xml->getparbool("autoscale", Php.autoscale); + Php.onehalf = xml->getpar127("one_half", Php.onehalf); xml->exitbranch(); - }; + } - if (xml->enterbranch("OSCIL")) { + if(xml->enterbranch("OSCIL")) { oscilgen->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("RESONANCE")) { + if(xml->enterbranch("RESONANCE")) { resonance->getfromXML(xml); xml->exitbranch(); - }; + } - if (xml->enterbranch("HARMONIC_POSITION")) { - Phrpos.type=xml->getpar127("type",Phrpos.type); - Phrpos.par1=xml->getpar("parameter1",Phrpos.par1,0,255); - Phrpos.par2=xml->getpar("parameter2",Phrpos.par2,0,255); - Phrpos.par3=xml->getpar("parameter3",Phrpos.par3,0,255); + if(xml->enterbranch("HARMONIC_POSITION")) { + Phrpos.type = xml->getpar127("type", Phrpos.type); + Phrpos.par1 = xml->getpar("parameter1", Phrpos.par1, 0, 255); + Phrpos.par2 = xml->getpar("parameter2", Phrpos.par2, 0, 255); + Phrpos.par3 = xml->getpar("parameter3", Phrpos.par3, 0, 255); xml->exitbranch(); - }; + } - if (xml->enterbranch("SAMPLE_QUALITY")) { - Pquality.samplesize=xml->getpar127("samplesize",Pquality.samplesize); - Pquality.basenote=xml->getpar127("basenote",Pquality.basenote); - Pquality.oct=xml->getpar127("octaves",Pquality.oct); - Pquality.smpoct=xml->getpar127("samples_per_octave",Pquality.smpoct); + if(xml->enterbranch("SAMPLE_QUALITY")) { + Pquality.samplesize = xml->getpar127("samplesize", Pquality.samplesize); + Pquality.basenote = xml->getpar127("basenote", Pquality.basenote); + Pquality.oct = xml->getpar127("octaves", Pquality.oct); + Pquality.smpoct = xml->getpar127("samples_per_octave", + Pquality.smpoct); xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - PPunchStrength=xml->getpar127("punch_strength",PPunchStrength); - PPunchTime=xml->getpar127("punch_time",PPunchTime); - PPunchStretch=xml->getpar127("punch_stretch",PPunchStretch); - PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",PPunchVelocitySensing); + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + PPunchStrength = xml->getpar127("punch_strength", PPunchStrength); + PPunchTime = xml->getpar127("punch_time", PPunchTime); + PPunchStretch = xml->getpar127("punch_stretch", PPunchStretch); + PPunchVelocitySensing = xml->getpar127("punch_velocity_sensing", + PPunchVelocitySensing); xml->enterbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->getfromXML(xml); @@ -765,14 +866,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getpar127("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getpar127("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); xml->enterbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->getfromXML(xml); @@ -782,11 +883,14 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FreqLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",PFilterVelocityScale); - PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",PFilterVelocityScaleFunction); + if(xml->enterbranch("FILTER_PARAMETERS")) { + PFilterVelocityScale = xml->getpar127("velocity_sensing_amplitude", + PFilterVelocityScale); + PFilterVelocityScaleFunction = xml->getpar127( + "velocity_sensing", + PFilterVelocityScaleFunction); xml->enterbranch("FILTER"); GlobalFilter->getfromXML(xml); @@ -800,7 +904,6 @@ void PADnoteParameters::getfromXML(XMLwrapper *xml) FilterLfo->getfromXML(xml); xml->exitbranch(); xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Params/PADnoteParameters.h b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h index eacd676c8..37d598529 100644 --- a/plugins/zynaddsubfx/src/Params/PADnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h @@ -35,136 +35,149 @@ #include "FilterParams.h" #include "Presets.h" #include +#include class PADnoteParameters:public Presets { -public: - PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_); - ~PADnoteParameters(); + public: + PADnoteParameters(FFTwrapper *fft_, pthread_mutex_t *mutex_); + ~PADnoteParameters(); - void defaults(); - void add2XML(XMLwrapper *xml); - void getfromXML(XMLwrapper *xml); + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); - //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth - REALTYPE getprofile(REALTYPE *smp,int size); + //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth + REALTYPE getprofile(REALTYPE *smp, int size); - //parameters + //parameters - //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous - //the harmonic profile is used only on mode 0 - unsigned char Pmode; + //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous + //the harmonic profile is used only on mode 0 + unsigned char Pmode; - //Harmonic profile (the frequency distribution of a single harmonic) - struct { - struct {//base function + //Harmonic profile (the frequency distribution of a single harmonic) + struct { + struct { //base function + unsigned char type; + unsigned char par1; + } base; + unsigned char freqmult; //frequency multiplier of the distribution + struct { //the modulator of the distribution + unsigned char par1; + unsigned char freq; + } modulator; + + unsigned char width; //the width of the resulting function after the modulation + struct { //the amplitude multiplier of the harmonic profile + unsigned char mode; + unsigned char type; + unsigned char par1; + unsigned char par2; + } amp; + bool autoscale; //if the scale of the harmonic profile is computed automaticaly + unsigned char onehalf; //what part of the base function is used to make the distribution + } Php; + + + unsigned int Pbandwidth; //the values are from 0 to 1000 + unsigned char Pbwscale; //how the bandwidth is increased according to the harmonic's frequency + + struct { //where are positioned the harmonics (on integer multimplier or different places) unsigned char type; - unsigned char par1; - }base; - unsigned char freqmult;//frequency multiplier of the distribution - struct {//the modulator of the distribution - unsigned char par1; - unsigned char freq; - }modulator; + unsigned char par1, par2, par3; //0..255 + } Phrpos; - unsigned char width;//the width of the resulting function after the modulation - struct {//the amplitude multiplier of the harmonic profile - unsigned char mode; - unsigned char type; - unsigned char par1; - unsigned char par2; - }amp; - bool autoscale;//if the scale of the harmonic profile is computed automaticaly - unsigned char onehalf;//what part of the base function is used to make the distribution - }Php; + struct { //quality of the samples (how many samples, the length of them,etc.) + unsigned char samplesize; + unsigned char basenote, oct, smpoct; + } Pquality; + //frequency parameters + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - unsigned int Pbandwidth;//the values are from 0 to 1000 - unsigned char Pbwscale;//how the bandwidth is increased according to the harmonic's frequency + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + unsigned short int PDetune; //fine detune + unsigned short int PCoarseDetune; //coarse detune+octave + unsigned char PDetuneType; //detune type - struct {//where are positioned the harmonics (on integer multimplier or different places) - unsigned char type; - unsigned char par1,par2,par3;//0..255 - }Phrpos; + EnvelopeParams *FreqEnvelope; //Frequency Envelope + LFOParams *FreqLfo; //Frequency LFO - struct {//quality of the samples (how many samples, the length of them,etc.) - unsigned char samplesize; - unsigned char basenote,oct,smpoct; - } Pquality; + //Amplitude parameters + unsigned char PStereo; + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; - //frequency parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + unsigned char PVolume; - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; - unsigned short int PDetune;//fine detune - unsigned short int PCoarseDetune;//coarse detune+octave - unsigned char PDetuneType;//detune type + unsigned char PAmpVelocityScaleFunction; - EnvelopeParams *FreqEnvelope; //Frequency Envelope - LFOParams *FreqLfo;//Frequency LFO + EnvelopeParams *AmpEnvelope; - //Amplitude parameters - unsigned char PStereo; - /* Panning - 0 - random - 1 - left - 64 - center - 127 - right */ - unsigned char PPanning; + LFOParams *AmpLfo; - unsigned char PVolume; + unsigned char PPunchStrength, PPunchTime, PPunchStretch, + PPunchVelocitySensing; - unsigned char PAmpVelocityScaleFunction; + //Filter Parameters + FilterParams *GlobalFilter; - EnvelopeParams *AmpEnvelope; + // filter velocity sensing + unsigned char PFilterVelocityScale; - LFOParams *AmpLfo; + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; - unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; - - //Filter Parameters - FilterParams *GlobalFilter; - - // filter velocity sensing - unsigned char PFilterVelocityScale; - - // filter velocity sensing - unsigned char PFilterVelocityScaleFunction; - - EnvelopeParams *FilterEnvelope; - LFOParams *FilterLfo; + EnvelopeParams *FilterEnvelope; + LFOParams *FilterLfo; - REALTYPE setPbandwidth(int Pbandwidth);//returns the BandWidth in cents - REALTYPE getNhr(int n);//gets the n-th overtone position relatively to N harmonic + REALTYPE setPbandwidth(int Pbandwidth); //returns the BandWidth in cents + REALTYPE getNhr(int n); //gets the n-th overtone position relatively to N harmonic - void applyparameters(bool lockmutex); - void export2wav(std::string basefilename); + void applyparameters(bool lockmutex); + void export2wav(std::string basefilename); - OscilGen *oscilgen; - Resonance *resonance; + OscilGen *oscilgen; + Resonance *resonance; - struct { - int size; - REALTYPE basefreq; - REALTYPE *smp; - }sample[PAD_MAX_SAMPLES],newsample; + struct { + int size; + REALTYPE basefreq; + REALTYPE *smp; + } sample[PAD_MAX_SAMPLES], newsample; -private: - void generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); - void deletesamples(); - void deletesample(int n); + private: + void generatespectrum_bandwidthMode(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void generatespectrum_otherModes(REALTYPE *spectrum, + int size, + REALTYPE basefreq, + REALTYPE *profile, + int profilesize, + REALTYPE bwadjust); + void deletesamples(); + void deletesample(int n); - FFTwrapper *fft; - pthread_mutex_t *mutex; + FFTwrapper *fft; + pthread_mutex_t *mutex; }; #endif + diff --git a/plugins/zynaddsubfx/src/Params/Presets.cpp b/plugins/zynaddsubfx/src/Params/Presets.cpp index 40c78c24d..b3cfd1610 100644 --- a/plugins/zynaddsubfx/src/Params/Presets.cpp +++ b/plugins/zynaddsubfx/src/Params/Presets.cpp @@ -26,113 +26,124 @@ Presets::Presets() { - type[0]=0; - nelement=-1; -}; + type[0] = 0; + nelement = -1; +} Presets::~Presets() -{ -}; +{} void Presets::setpresettype(const char *type) { - strcpy(this->type,type); -}; + strcpy(this->type, type); +} void Presets::copy(const char *name) { - XMLwrapper *xml=new XMLwrapper(); + XMLwrapper *xml = new XMLwrapper(); //used only for the clipboard - if (name==NULL) xml->minimal=false; + if(name == NULL) + xml->minimal = false; char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (name==NULL) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(name == NULL) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; xml->beginbranch(type); - if (nelement==-1) add2XML(xml); - else add2XMLsection(xml,nelement); + if(nelement == -1) + add2XML(xml); + else + add2XMLsection(xml, nelement); xml->endbranch(); - if (name==NULL) presetsstore.copyclipboard(xml,type); - else presetsstore.copypreset(xml,type,name); + if(name == NULL) + presetsstore.copyclipboard(xml, type); + else + presetsstore.copypreset(xml, type, name); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} void Presets::paste(int npreset) { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); - if (npreset==0) { - if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); - }; + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); + if(npreset == 0) + if(strstr(type, "Plfo") != NULL) + strcpy(type, "Plfo"); + ; - XMLwrapper *xml=new XMLwrapper(); - if (npreset==0) { - if (!checkclipboardtype()) { - nelement=-1; - delete(xml); + XMLwrapper *xml = new XMLwrapper(); + if(npreset == 0) { + if(!checkclipboardtype()) { + nelement = -1; + delete (xml); return; - }; - if (!presetsstore.pasteclipboard(xml)) { - delete(xml); - nelement=-1; + } + if(!presetsstore.pasteclipboard(xml)) { + delete (xml); + nelement = -1; return; - }; - } else { - if (!presetsstore.pastepreset(xml,npreset)) { - delete(xml); - nelement=-1; + } + } + else { + if(!presetsstore.pastepreset(xml, npreset)) { + delete (xml); + nelement = -1; return; - }; - }; + } + } - if (xml->enterbranch(type)==0) { - nelement=-1; + if(xml->enterbranch(type) == 0) { + nelement = -1; return; - }; - if (nelement==-1) { + } + if(nelement == -1) { defaults(); getfromXML(xml); - } else { + } + else { defaults(nelement); - getfromXMLsection(xml,nelement); - }; + getfromXMLsection(xml, nelement); + } xml->exitbranch(); - delete(xml); - nelement=-1; -}; + delete (xml); + nelement = -1; +} bool Presets::checkclipboardtype() { char type[MAX_PRESETTYPE_SIZE]; - strcpy(type,this->type); - if (nelement!=-1) strcat(type,"n"); + strcpy(type, this->type); + if(nelement != -1) + strcat(type, "n"); - return(presetsstore.checkclipboardtype(type)); -}; + return presetsstore.checkclipboardtype(type); +} void Presets::setelement(int n) { - nelement=n; -}; + nelement = n; +} void Presets::rescanforpresets() { presetsstore.rescanforpresets(type); -}; +} void Presets::deletepreset(int npreset) { presetsstore.deletepreset(npreset); -}; +} diff --git a/plugins/zynaddsubfx/src/Params/Presets.h b/plugins/zynaddsubfx/src/Params/Presets.h index 4f4bf78a4..8e143aed6 100644 --- a/plugins/zynaddsubfx/src/Params/Presets.h +++ b/plugins/zynaddsubfx/src/Params/Presets.h @@ -30,30 +30,30 @@ /**Presets and Clipboard management*/ class Presets { -public: - Presets(); - virtual ~Presets(); + public: + Presets(); + virtual ~Presets(); - void copy(const char *name);/**getXMLdata(); -}; + strcpy(clipboard.type, type); + if(clipboard.data != NULL) + free(clipboard.data); + clipboard.data = xml->getXMLdata(); +} bool PresetsStore::pasteclipboard(XMLwrapper *xml) { - if (clipboard.data!=NULL) xml->putXMLdata(clipboard.data); - else return(false); - return(true); -}; + if(clipboard.data != NULL) + xml->putXMLdata(clipboard.data); + else + return false; + return true; +} bool PresetsStore::checkclipboardtype(char *type) { //makes LFO's compatible - if ((strstr(type,"Plfo")!=NULL)&&(strstr(clipboard.type,"Plfo")!=NULL)) return(true); - return(strcmp(type,clipboard.type)==0); -}; + if((strstr(type, + "Plfo") != NULL) && (strstr(clipboard.type, "Plfo") != NULL)) + return true; + return strcmp(type, clipboard.type) == 0; +} //Presets management void PresetsStore::clearpresets() { - for (int i=0;iname)==NULL)||((p2->name)==NULL)) return(0); + struct PresetsStore::presetstruct *p1 = (PresetsStore::presetstruct *)a; + struct PresetsStore::presetstruct *p2 = (PresetsStore::presetstruct *)b; + if(((p1->name) == NULL) || ((p2->name) == NULL)) + return 0; - return(strcasecmp(p1->name,p2->name)<0); -}; + return strcasecmp(p1->name, p2->name) < 0; +} void PresetsStore::rescanforpresets(char *type) { clearpresets(); - int presetk=0; + int presetk = 0; char ftype[MAX_STRING_SIZE]; - snprintf(ftype,MAX_STRING_SIZE,".%s.xpz",type); + snprintf(ftype, MAX_STRING_SIZE, ".%s.xpz", type); - for (int i=0;id_name; - if (strstr(filename,ftype)==NULL) continue; + while((fn = readdir(dir))) { + const char *filename = fn->d_name; + if(strstr(filename, ftype) == NULL) + continue; - presets[presetk].file=new char [MAX_STRING_SIZE]; - presets[presetk].name=new char [MAX_STRING_SIZE]; - char tmpc=dirname[strlen(dirname)-1]; + presets[presetk].file = new char [MAX_STRING_SIZE]; + presets[presetk].name = new char [MAX_STRING_SIZE]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; - snprintf(presets[presetk].file,MAX_STRING_SIZE,"%s%s%s",dirname,tmps,filename); - snprintf(presets[presetk].name,MAX_STRING_SIZE,"%s",filename); + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; + snprintf(presets[presetk].file, + MAX_STRING_SIZE, + "%s%s%s", + dirname, + tmps, + filename); + snprintf(presets[presetk].name, MAX_STRING_SIZE, "%s", filename); - char *tmp=strstr(presets[presetk].name,ftype); - if (tmp!=NULL) tmp[0]='\0'; + char *tmp = strstr(presets[presetk].name, ftype); + if(tmp != NULL) + tmp[0] = '\0'; presetk++; - if (presetk>=MAX_PRESETS) return; - }; + if(presetk >= MAX_PRESETS) + return; + } closedir(dir); - }; + } //sort the presets - for (int j=0;j='0')&&(c<='9')) continue; - if ((c>='A')&&(c<='Z')) continue; - if ((c>='a')&&(c<='z')) continue; - if ((c=='-')||(c==' ')) continue; - tmpfilename[i]='_'; - }; + for(int i = 0; i < (int) strlen(tmpfilename); i++) { + char c = tmpfilename[i]; + if((c >= '0') && (c <= '9')) + continue; + if((c >= 'A') && (c <= 'Z')) + continue; + if((c >= 'a') && (c <= 'z')) + continue; + if((c == '-') || (c == ' ')) + continue; + tmpfilename[i] = '_'; + } - const char *dirname=config.cfg.presetsDirList[0]; - char tmpc=dirname[strlen(dirname)-1]; + const char *dirname = config.cfg.presetsDirList[0]; + char tmpc = dirname[strlen(dirname) - 1]; const char *tmps; - if ((tmpc=='/')||(tmpc=='\\')) tmps=""; - else tmps="/"; + if((tmpc == '/') || (tmpc == '\\')) + tmps = ""; + else + tmps = "/"; - snprintf(filename,MAX_STRING_SIZE,"%s%s%s.%s.xpz",dirname,tmps,name,type); + snprintf(filename, + MAX_STRING_SIZE, + "%s%s%s.%s.xpz", + dirname, + tmps, + name, + type); xml->saveXMLfile(filename); -}; +} bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return(false); - char *filename=presets[npreset].file; - if (filename==NULL) return(false); - bool result=(xml->loadXMLfile(filename)>=0); - return(result); -}; + if(npreset >= MAX_PRESETS) + return false; + char *filename = presets[npreset].file; + if(filename == NULL) + return false; + bool result = (xml->loadXMLfile(filename) >= 0); + return result; +} void PresetsStore::deletepreset(int npreset) { npreset--; - if (npreset>=MAX_PRESETS) return; - char *filename=presets[npreset].file; - if (filename==NULL) return; + if(npreset >= MAX_PRESETS) + return; + char *filename = presets[npreset].file; + if(filename == NULL) + return; remove(filename); -}; +} diff --git a/plugins/zynaddsubfx/src/Params/PresetsStore.h b/plugins/zynaddsubfx/src/Params/PresetsStore.h index 8ff602beb..c81498231 100644 --- a/plugins/zynaddsubfx/src/Params/PresetsStore.h +++ b/plugins/zynaddsubfx/src/Params/PresetsStore.h @@ -28,36 +28,35 @@ class PresetsStore { -public: - PresetsStore(); - ~PresetsStore(); + public: + PresetsStore(); + ~PresetsStore(); - //Clipboard stuff - void copyclipboard(XMLwrapper *xml,char *type); - bool pasteclipboard(XMLwrapper *xml); - bool checkclipboardtype(char *type); + //Clipboard stuff + void copyclipboard(XMLwrapper *xml, char *type); + bool pasteclipboard(XMLwrapper *xml); + bool checkclipboardtype(char *type); - //presets stuff - void copypreset(XMLwrapper *xml,char *type, const char *name); - bool pastepreset(XMLwrapper *xml, int npreset); - void deletepreset(int npreset); + //presets stuff + void copypreset(XMLwrapper *xml, char *type, const char *name); + bool pastepreset(XMLwrapper *xml, int npreset); + void deletepreset(int npreset); - struct presetstruct { - char *file; - char *name; - }; - presetstruct presets[MAX_PRESETS]; + struct presetstruct { + char *file; + char *name; + }; + presetstruct presets[MAX_PRESETS]; - void rescanforpresets(char *type); + void rescanforpresets(char *type); -private: - struct { - char *data; - char type[MAX_PRESETTYPE_SIZE]; - } clipboard; - - void clearpresets(); + private: + struct { + char *data; + char type[MAX_PRESETTYPE_SIZE]; + } clipboard; + void clearpresets(); }; extern PresetsStore presetsstore; diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp index 963af0911..27fdb46d0 100644 --- a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.cpp @@ -27,59 +27,58 @@ SUBnoteParameters::SUBnoteParameters():Presets() { setpresettype("Psubsyth"); - AmpEnvelope=new EnvelopeParams(64,1); - AmpEnvelope->ADSRinit_dB(0,40,127,25); - FreqEnvelope=new EnvelopeParams(64,0); - FreqEnvelope->ASRinit(30,50,64,60); - BandWidthEnvelope=new EnvelopeParams(64,0); - BandWidthEnvelope->ASRinit_bw(100,70,64,60); + AmpEnvelope = new EnvelopeParams(64, 1); + AmpEnvelope->ADSRinit_dB(0, 40, 127, 25); + FreqEnvelope = new EnvelopeParams(64, 0); + FreqEnvelope->ASRinit(30, 50, 64, 60); + BandWidthEnvelope = new EnvelopeParams(64, 0); + BandWidthEnvelope->ASRinit_bw(100, 70, 64, 60); - GlobalFilter=new FilterParams(2,80,40); - GlobalFilterEnvelope=new EnvelopeParams(0,1); - GlobalFilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + GlobalFilter = new FilterParams(2, 80, 40); + GlobalFilterEnvelope = new EnvelopeParams(0, 1); + GlobalFilterEnvelope->ADSRinit_filter(64, 40, 64, 70, 60, 64); defaults(); -}; +} void SUBnoteParameters::defaults() { - PVolume=96; - PPanning=64; - PAmpVelocityScaleFunction=90; + PVolume = 96; + PPanning = 64; + PAmpVelocityScaleFunction = 90; - Pfixedfreq=0; - PfixedfreqET=0; - Pnumstages=2; - Pbandwidth=40; - Phmagtype=0; - Pbwscale=64; - Pstereo=1; - Pstart=1; + Pfixedfreq = 0; + PfixedfreqET = 0; + Pnumstages = 2; + Pbandwidth = 40; + Phmagtype = 0; + Pbwscale = 64; + Pstereo = 1; + Pstart = 1; - PDetune=8192; - PCoarseDetune=0; - PDetuneType=1; - PFreqEnvelopeEnabled=0; - PBandWidthEnvelopeEnabled=0; + PDetune = 8192; + PCoarseDetune = 0; + PDetuneType = 1; + PFreqEnvelopeEnabled = 0; + PBandWidthEnvelopeEnabled = 0; - for (int n=0;ndefaults(); FreqEnvelope->defaults(); BandWidthEnvelope->defaults(); GlobalFilter->defaults(); GlobalFilterEnvelope->defaults(); - -}; +} @@ -90,154 +89,163 @@ SUBnoteParameters::~SUBnoteParameters() delete (BandWidthEnvelope); delete (GlobalFilter); delete (GlobalFilterEnvelope); -}; +} void SUBnoteParameters::add2XML(XMLwrapper *xml) { - xml->addpar("num_stages",Pnumstages); - xml->addpar("harmonic_mag_type",Phmagtype); - xml->addpar("start",Pstart); + xml->addpar("num_stages", Pnumstages); + xml->addpar("harmonic_mag_type", Phmagtype); + xml->addpar("start", Pstart); xml->beginbranch("HARMONICS"); - for (int i=0;iminimal)) continue; - xml->beginbranch("HARMONIC",i); - xml->addpar("mag",Phmag[i]); - xml->addpar("relbw",Phrelbw[i]); + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if((Phmag[i] == 0) && (xml->minimal)) + continue; + xml->beginbranch("HARMONIC", i); + xml->addpar("mag", Phmag[i]); + xml->addpar("relbw", Phrelbw[i]); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("AMPLITUDE_PARAMETERS"); - xml->addparbool("stereo",Pstereo); - xml->addpar("volume",PVolume); - xml->addpar("panning",PPanning); - xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); + xml->addparbool("stereo", Pstereo); + xml->addpar("volume", PVolume); + xml->addpar("panning", PPanning); + xml->addpar("velocity_sensing", PAmpVelocityScaleFunction); xml->beginbranch("AMPLITUDE_ENVELOPE"); AmpEnvelope->add2XML(xml); xml->endbranch(); xml->endbranch(); xml->beginbranch("FREQUENCY_PARAMETERS"); - xml->addparbool("fixed_freq",Pfixedfreq); - xml->addpar("fixed_freq_et",PfixedfreqET); + xml->addparbool("fixed_freq", Pfixedfreq); + xml->addpar("fixed_freq_et", PfixedfreqET); - xml->addpar("detune",PDetune); - xml->addpar("coarse_detune",PCoarseDetune); - xml->addpar("detune_type",PDetuneType); + xml->addpar("detune", PDetune); + xml->addpar("coarse_detune", PCoarseDetune); + xml->addpar("detune_type", PDetuneType); - xml->addpar("bandwidth",Pbandwidth); - xml->addpar("bandwidth_scale",Pbwscale); + xml->addpar("bandwidth", Pbandwidth); + xml->addpar("bandwidth_scale", Pbwscale); - xml->addparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if ((PFreqEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("freq_envelope_enabled", PFreqEnvelopeEnabled); + if((PFreqEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FREQUENCY_ENVELOPE"); FreqEnvelope->add2XML(xml); xml->endbranch(); - }; + } - xml->addparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if ((PBandWidthEnvelopeEnabled!=0)||(!xml->minimal)) { + xml->addparbool("band_width_envelope_enabled", PBandWidthEnvelopeEnabled); + if((PBandWidthEnvelopeEnabled != 0) || (!xml->minimal)) { xml->beginbranch("BANDWIDTH_ENVELOPE"); BandWidthEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); xml->beginbranch("FILTER_PARAMETERS"); - xml->addparbool("enabled",PGlobalFilterEnabled); - if ((PGlobalFilterEnabled!=0)||(!xml->minimal)) { + xml->addparbool("enabled", PGlobalFilterEnabled); + if((PGlobalFilterEnabled != 0) || (!xml->minimal)) { xml->beginbranch("FILTER"); GlobalFilter->add2XML(xml); xml->endbranch(); - xml->addpar("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - xml->addpar("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + xml->addpar("filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + xml->addpar("filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); xml->beginbranch("FILTER_ENVELOPE"); GlobalFilterEnvelope->add2XML(xml); xml->endbranch(); - }; + } xml->endbranch(); -}; +} void SUBnoteParameters::getfromXML(XMLwrapper *xml) { - Pnumstages=xml->getpar127("num_stages",Pnumstages); - Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); - Pstart=xml->getpar127("start",Pstart); + Pnumstages = xml->getpar127("num_stages", Pnumstages); + Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); + Pstart = xml->getpar127("start", Pstart); - if (xml->enterbranch("HARMONICS")) { - Phmag[0]=0; - for (int i=0;ienterbranch("HARMONIC",i)==0) continue; - Phmag[i]=xml->getpar127("mag",Phmag[i]); - Phrelbw[i]=xml->getpar127("relbw",Phrelbw[i]); + if(xml->enterbranch("HARMONICS")) { + Phmag[0] = 0; + for(int i = 0; i < MAX_SUB_HARMONICS; i++) { + if(xml->enterbranch("HARMONIC", i) == 0) + continue; + Phmag[i] = xml->getpar127("mag", Phmag[i]); + Phrelbw[i] = xml->getpar127("relbw", Phrelbw[i]); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("AMPLITUDE_PARAMETERS")) { - Pstereo=xml->getparbool("stereo",Pstereo); - PVolume=xml->getpar127("volume",PVolume); - PPanning=xml->getpar127("panning",PPanning); - PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); - if (xml->enterbranch("AMPLITUDE_ENVELOPE")) { + if(xml->enterbranch("AMPLITUDE_PARAMETERS")) { + Pstereo = xml->getparbool("stereo", Pstereo); + PVolume = xml->getpar127("volume", PVolume); + PPanning = xml->getpar127("panning", PPanning); + PAmpVelocityScaleFunction = xml->getpar127("velocity_sensing", + PAmpVelocityScaleFunction); + if(xml->enterbranch("AMPLITUDE_ENVELOPE")) { AmpEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FREQUENCY_PARAMETERS")) { - Pfixedfreq=xml->getparbool("fixed_freq",Pfixedfreq); - PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); + if(xml->enterbranch("FREQUENCY_PARAMETERS")) { + Pfixedfreq = xml->getparbool("fixed_freq", Pfixedfreq); + PfixedfreqET = xml->getpar127("fixed_freq_et", PfixedfreqET); - PDetune=xml->getpar("detune",PDetune,0,16383); - PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); - PDetuneType=xml->getpar127("detune_type",PDetuneType); + PDetune = xml->getpar("detune", PDetune, 0, 16383); + PCoarseDetune = xml->getpar("coarse_detune", PCoarseDetune, 0, 16383); + PDetuneType = xml->getpar127("detune_type", PDetuneType); - Pbandwidth=xml->getpar127("bandwidth",Pbandwidth); - Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + Pbandwidth = xml->getpar127("bandwidth", Pbandwidth); + Pbwscale = xml->getpar127("bandwidth_scale", Pbwscale); - PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); - if (xml->enterbranch("FREQUENCY_ENVELOPE")) { + PFreqEnvelopeEnabled = xml->getparbool("freq_envelope_enabled", + PFreqEnvelopeEnabled); + if(xml->enterbranch("FREQUENCY_ENVELOPE")) { FreqEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } - PBandWidthEnvelopeEnabled=xml->getparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); - if (xml->enterbranch("BANDWIDTH_ENVELOPE")) { + PBandWidthEnvelopeEnabled = xml->getparbool( + "band_width_envelope_enabled", + PBandWidthEnvelopeEnabled); + if(xml->enterbranch("BANDWIDTH_ENVELOPE")) { BandWidthEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (xml->enterbranch("FILTER_PARAMETERS")) { - PGlobalFilterEnabled=xml->getparbool("enabled",PGlobalFilterEnabled); - if (xml->enterbranch("FILTER")) { + if(xml->enterbranch("FILTER_PARAMETERS")) { + PGlobalFilterEnabled = xml->getparbool("enabled", PGlobalFilterEnabled); + if(xml->enterbranch("FILTER")) { GlobalFilter->getfromXML(xml); xml->exitbranch(); - }; + } - PGlobalFilterVelocityScaleFunction=xml->getpar127("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); - PGlobalFilterVelocityScale=xml->getpar127("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + PGlobalFilterVelocityScaleFunction = xml->getpar127( + "filter_velocity_sensing", + PGlobalFilterVelocityScaleFunction); + PGlobalFilterVelocityScale = xml->getpar127( + "filter_velocity_sensing_amplitude", + PGlobalFilterVelocityScale); - if (xml->enterbranch("FILTER_ENVELOPE")) { + if(xml->enterbranch("FILTER_ENVELOPE")) { GlobalFilterEnvelope->getfromXML(xml); xml->exitbranch(); - }; + } xml->exitbranch(); - }; -}; - - - + } +} diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h index a0ebd8fde..57bc08004 100644 --- a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h @@ -31,76 +31,74 @@ class SUBnoteParameters:public Presets { -public: - SUBnoteParameters(); - ~SUBnoteParameters(); + public: + SUBnoteParameters(); + ~SUBnoteParameters(); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - //Parameters - //AMPLITUDE PARAMETRERS - unsigned char Pstereo;//0 for mono,1 for stereo - unsigned char PVolume; - unsigned char PPanning; - unsigned char PAmpVelocityScaleFunction; - EnvelopeParams *AmpEnvelope; + //Parameters + //AMPLITUDE PARAMETRERS + unsigned char Pstereo; //0 for mono,1 for stereo + unsigned char PVolume; + unsigned char PPanning; + unsigned char PAmpVelocityScaleFunction; + EnvelopeParams *AmpEnvelope; - //Frequency Parameters - unsigned short int PDetune; - unsigned short int PCoarseDetune; - unsigned char PDetuneType; - unsigned char PFreqEnvelopeEnabled; - EnvelopeParams *FreqEnvelope; - unsigned char PBandWidthEnvelopeEnabled; - EnvelopeParams *BandWidthEnvelope; + //Frequency Parameters + unsigned short int PDetune; + unsigned short int PCoarseDetune; + unsigned char PDetuneType; + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + unsigned char PBandWidthEnvelopeEnabled; + EnvelopeParams *BandWidthEnvelope; - //Filter Parameters (Global) - unsigned char PGlobalFilterEnabled; - FilterParams *GlobalFilter; - unsigned char PGlobalFilterVelocityScale; - unsigned char PGlobalFilterVelocityScaleFunction; - EnvelopeParams *GlobalFilterEnvelope; + //Filter Parameters (Global) + unsigned char PGlobalFilterEnabled; + FilterParams *GlobalFilter; + unsigned char PGlobalFilterVelocityScale; + unsigned char PGlobalFilterVelocityScaleFunction; + EnvelopeParams *GlobalFilterEnvelope; - //Other Parameters + //Other Parameters - //If the base frequency is fixed to 440 Hz - unsigned char Pfixedfreq; + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; - /* Equal temperate (this is used only if the Pfixedfreq is enabled) - If this parameter is 0, the frequency is fixed (to 440 Hz); - if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ - unsigned char PfixedfreqET; + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; - //how many times the filters are applied - unsigned char Pnumstages; + //how many times the filters are applied + unsigned char Pnumstages; - //bandwidth - unsigned char Pbandwidth; + //bandwidth + unsigned char Pbandwidth; - //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) - unsigned char Phmagtype; + //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) + unsigned char Phmagtype; - //Magnitudes - unsigned char Phmag[MAX_SUB_HARMONICS]; + //Magnitudes + unsigned char Phmag[MAX_SUB_HARMONICS]; - //Relative BandWidth ("64"=1.0) - unsigned char Phrelbw[MAX_SUB_HARMONICS]; + //Relative BandWidth ("64"=1.0) + unsigned char Phrelbw[MAX_SUB_HARMONICS]; - //how much the bandwidth is increased according to lower/higher frequency; 64-default - unsigned char Pbwscale; + //how much the bandwidth is increased according to lower/higher frequency; 64-default + unsigned char Pbwscale; - //how the harmonics start("0"=0,"1"=random,"2"=1) - unsigned char Pstart; + //how the harmonics start("0"=0,"1"=random,"2"=1) + unsigned char Pstart; -private: + private: }; #endif - - diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.cpp b/plugins/zynaddsubfx/src/Samples/AuSample.cpp index 5d95390cf..49f3a2887 100644 --- a/plugins/zynaddsubfx/src/Samples/AuSample.cpp +++ b/plugins/zynaddsubfx/src/Samples/AuSample.cpp @@ -20,9 +20,9 @@ */ #include "AuSample.h" -AuSample::AuSample(int length,REALTYPE fill) - : Sample(length,fill) {} +AuSample::AuSample(int length, REALTYPE fill) + :Sample(length, fill) {} -AuSample::AuSample(int length,const REALTYPE *input) - : Sample(length,input) {} +AuSample::AuSample(int length, const REALTYPE *input) + :Sample(length, input) {} diff --git a/plugins/zynaddsubfx/src/Samples/AuSample.h b/plugins/zynaddsubfx/src/Samples/AuSample.h index f82166482..cad4a786c 100644 --- a/plugins/zynaddsubfx/src/Samples/AuSample.h +++ b/plugins/zynaddsubfx/src/Samples/AuSample.h @@ -24,13 +24,12 @@ #include "Sample.h" #include "FqSample.h" -class AuSample : public Sample +class AuSample:public Sample { -public: - AuSample(int length,REALTYPE fill=0); - AuSample(int length,const REALTYPE *input); - FqSample getFqSample();/**\todo implement this*/ - + public: + AuSample(int length, REALTYPE fill = 0); + AuSample(int length, const REALTYPE *input); + FqSample getFqSample(); /**\todo implement this*/ }; #endif diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.cpp b/plugins/zynaddsubfx/src/Samples/FqSample.cpp index 888dd0c45..94774047a 100644 --- a/plugins/zynaddsubfx/src/Samples/FqSample.cpp +++ b/plugins/zynaddsubfx/src/Samples/FqSample.cpp @@ -20,12 +20,12 @@ */ #include "FqSample.h" -FqSample::FqSample(int length,REALTYPE fill) - :Sample(length,fill) +FqSample::FqSample(int length, REALTYPE fill) + :Sample(length, fill) {} -FqSample::FqSample(int length,const REALTYPE *input) - : Sample(length,input) +FqSample::FqSample(int length, const REALTYPE *input) + :Sample(length, input) {} FqSample::~FqSample() diff --git a/plugins/zynaddsubfx/src/Samples/FqSample.h b/plugins/zynaddsubfx/src/Samples/FqSample.h index f81abe20f..fd31535cb 100644 --- a/plugins/zynaddsubfx/src/Samples/FqSample.h +++ b/plugins/zynaddsubfx/src/Samples/FqSample.h @@ -24,14 +24,14 @@ #include "FqSample.h" #include "Sample.h" -class FqSample : public Sample +class FqSample:public Sample { -public: - FqSample(int length,REALTYPE fill=0); - FqSample(int length,const REALTYPE *input); - ~FqSample(); - //FqSample &operator=(const FqSample &smp); - //float *dontuse(){return buffer;}; + public: + FqSample(int length, REALTYPE fill = 0); + FqSample(int length, const REALTYPE *input); + ~FqSample(); + //FqSample &operator=(const FqSample &smp); + //float *dontuse(){return buffer;}; }; #endif diff --git a/plugins/zynaddsubfx/src/Samples/Sample.cpp b/plugins/zynaddsubfx/src/Samples/Sample.cpp index c11bc6d56..ca5bdc128 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.cpp +++ b/plugins/zynaddsubfx/src/Samples/Sample.cpp @@ -24,34 +24,35 @@ /**\TODO start using pointer math here as these will be Frequency called * functions throughout the code*/ Sample::Sample(const Sample &smp) - : bufferSize(smp.bufferSize) + :bufferSize(smp.bufferSize) { - buffer=new REALTYPE[bufferSize]; - for (int i=0;i0) { - buffer=new REALTYPE[length]; - for (int i=0;i 0) { + buffer = new REALTYPE[length]; + for(int i = 0; i < length; ++i) + *(buffer + i) = *(input + i); + } + else { + buffer = new REALTYPE[1]; + bufferSize = 1; + *buffer = 0; } } @@ -62,58 +63,59 @@ Sample::~Sample() void Sample::clear() { - for (int i=0;ibufferSize!=smp.bufferSize) + if(this->bufferSize != smp.bufferSize) return false; - for(int i=0;ibuffer[i]!=smp.buffer[i]) + for(int i = 0; i < bufferSize; ++i) + if(this->buffer[i] != smp.buffer[i]) return false; return true; } -REALTYPE Sample::max()const +REALTYPE Sample::max() const { - REALTYPE max=-1500;//a good low considering that samples should store values -1.0 to 1.0 - for(int i=0;imax) - max=buffer[i]; + REALTYPE max = -1500; //a good low considering that samples should store values -1.0 to 1.0 + for(int i = 0; i < bufferSize; ++i) + if(buffer[i] > max) + max = buffer[i]; return max; } -REALTYPE Sample::min()const +REALTYPE Sample::min() const { - REALTYPE min=1500;//a good high considering that samples should store values -1.0 to 1.0 - for(int i=0;imax) - max=fabs(buffer[i]); + REALTYPE max = 0; + for(int i = 0; i < bufferSize; ++i) + if(fabs(buffer[i]) > max) + max = fabs(buffer[i]); return max; } + diff --git a/plugins/zynaddsubfx/src/Samples/Sample.h b/plugins/zynaddsubfx/src/Samples/Sample.h index c46786d8b..ebdae66e5 100644 --- a/plugins/zynaddsubfx/src/Samples/Sample.h +++ b/plugins/zynaddsubfx/src/Samples/Sample.h @@ -26,45 +26,43 @@ */ class Sample { -public: - Sample(const Sample &smp); - Sample(int length,REALTYPE fill=0); - Sample(int length,const REALTYPE *fill); - ~Sample(); - /**Fills the buffer with zeros*/ - void clear(); - /**States the size of the buffer - * @return the size of the buffer*/ - int size() const { - return bufferSize; - }; - /**Provides the indexing operator for non const Samples*/ - REALTYPE &operator[](int index) { - return *(buffer+index%bufferSize); - }; - /**Provides the indexing operator for const Samples*/ - const REALTYPE &operator[](int index)const { - return *(buffer+index%bufferSize); - }; - /**Provides the assignment operator*/ - void operator=(const Sample &smp); - /**Provides the == operator*/ - bool operator==(const Sample &smp)const; - /**Provides direct access to the buffer to allow for transition - * - * This method is like c_str() from the string class and should be used - * sparingly*/ - const REALTYPE *c_buf() { - return buffer; - }; - REALTYPE max()const; - REALTYPE min()const; - REALTYPE absMax()const; -private: - int bufferSize; - float *buffer; - - + public: + Sample(const Sample &smp); + Sample(int length, REALTYPE fill = 0); + Sample(int length, const REALTYPE *fill); + ~Sample(); + /**Fills the buffer with zeros*/ + void clear(); + /**States the size of the buffer + * @return the size of the buffer*/ + int size() const { + return bufferSize; + } + /**Provides the indexing operator for non const Samples*/ + REALTYPE &operator[](int index) { + return *(buffer + index % bufferSize); + } + /**Provides the indexing operator for const Samples*/ + const REALTYPE &operator[](int index) const { + return *(buffer + index % bufferSize); + } + /**Provides the assignment operator*/ + void operator=(const Sample &smp); + /**Provides the == operator*/ + bool operator==(const Sample &smp) const; + /**Provides direct access to the buffer to allow for transition + * + * This method is like c_str() from the string class and should be used + * sparingly*/ + const REALTYPE *c_buf() { + return buffer; + } + REALTYPE max() const; + REALTYPE min() const; + REALTYPE absMax() const; + private: + int bufferSize; + float *buffer; }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp index 42618c1ce..3bbab6c48 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.cpp @@ -25,68 +25,69 @@ #include MIDIEvents::MIDIEvents() -{ -}; +{} MIDIEvents::~MIDIEvents() -{ -}; +{} /************** Track stuff ***************/ -void MIDIEvents::writeevent(list *l,event *ev) +void MIDIEvents::writeevent(list *l, event *ev) { - listpos *tmp=new listpos; - tmp->next=NULL; - tmp->ev=*ev; - if (l->current!=NULL) l->current->next=tmp; - else l->first=tmp; - l->current=tmp; + listpos *tmp = new listpos; + tmp->next = NULL; + tmp->ev = *ev; + if(l->current != NULL) + l->current->next = tmp; + else + l->first = tmp; + l->current = tmp; // printf("Wx%x ",(int) l->current); // printf("-> %d \n",l->current->ev.deltatime); l->size++; -}; +} -void MIDIEvents::readevent(list *l,event *ev) +void MIDIEvents::readevent(list *l, event *ev) { - if (l->current==NULL) { - ev->type=-1; + if(l->current == NULL) { + ev->type = -1; return; - }; - *ev=l->current->ev; - l->current=l->current->next; + } + *ev = l->current->ev; + l->current = l->current->next; //test - if (l->current!=NULL) { + if(l->current != NULL) { // ev->deltatime=10000; // printf("Rx%d\n",l->current->ev.deltatime); // printf("Rx%x ",(int) l->current); // printf("-> %d (next=%x) \n",(int)l->current->ev.deltatime,(int)l->current->next); - }; - -}; + } +} void MIDIEvents::rewindlist(list *l) { - l->current=l->first; -}; + l->current = l->first; +} void MIDIEvents::deletelist(list *l) { - l->current=l->first; - if (l->current==NULL) return; - while (l->current->next!=NULL) { - listpos *tmp=l->current; - l->current=l->current->next; - delete(tmp); - }; + l->current = l->first; + if(l->current == NULL) + return; + while(l->current->next != NULL) { + listpos *tmp = l->current; + l->current = l->current->next; + delete (tmp); + } deletelistreference(l); -}; +} void MIDIEvents::deletelistreference(list *l) { - l->current=l->first=NULL; - l->size=0; - l->length=0.0; -}; + l->current = l->first = NULL; + l->size = 0; + l->length = 0.0; +} + diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.h b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h index 5b3b6f1e1..222404876 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIEvents.h +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h @@ -31,39 +31,38 @@ class MIDIEvents { friend class MIDIFile; -public: - MIDIEvents(); - ~MIDIEvents(); + public: + MIDIEvents(); + ~MIDIEvents(); -protected: + protected: - /* Events */ - struct event { - int deltatime; - int channel;//on what midi channel is - int type,par1,par2;//type=1 for note, type=2 for controller, type=255 for time messages - } tmpevent; - struct listpos { - event ev; - struct listpos *next; - }; - struct list { - listpos *first,*current; - int size;//how many events are - double length;//in seconds - }; - struct { - list track;//the stored track - list record;//the track being "recorded" from midi - } miditrack[NUM_MIDI_TRACKS]; + /* Events */ + struct event { + int deltatime; + int channel; //on what midi channel is + int type, par1, par2; //type=1 for note, type=2 for controller, type=255 for time messages + } tmpevent; + struct listpos { + event ev; + struct listpos *next; + }; + struct list { + listpos *first, *current; + int size; //how many events are + double length; //in seconds + }; + struct { + list track; //the stored track + list record; //the track being "recorded" from midi + } miditrack[NUM_MIDI_TRACKS]; - void writeevent(list *l,event *ev); - void readevent(list *l,event *ev); - - void rewindlist(list *l); - void deletelist(list *l); - void deletelistreference(list *l); + void writeevent(list *l, event *ev); + void readevent(list *l, event *ev); + void rewindlist(list *l); + void deletelist(list *l); + void deletelistreference(list *l); }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp index 61e748d3a..882d96e02 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.cpp @@ -27,382 +27,395 @@ MIDIFile::MIDIFile() { - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - me=NULL; -}; + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + me = NULL; +} MIDIFile::~MIDIFile() { clearmidifile(); -}; +} int MIDIFile::loadfile(const char *filename) { clearmidifile(); - FILE *file=fopen(filename,"r"); - if (file==NULL) return(-1); + FILE *file = fopen(filename, "r"); + if(file == NULL) + return -1; char header[4]; - ZERO(header,4); - fread(header,4,1,file); + ZERO(header, 4); + fread(header, 4, 1, file); //test to see if this a midi file - if ((header[0]!='M')||(header[1]!='T')||(header[2]!='h')||(header[3]!='d')) { + if((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') + || (header[3] != 'd')) { fclose(file); - return(-1); - }; + return -1; + } //get the filesize - fseek(file,0,SEEK_END); - midifilesize=ftell(file); + fseek(file, 0, SEEK_END); + midifilesize = ftell(file); rewind(file); - midifile=new unsigned char[midifilesize]; - ZERO(midifile,midifilesize); - fread(midifile,midifilesize,1,file); + midifile = new unsigned char[midifilesize]; + ZERO(midifile, midifilesize); + fread(midifile, midifilesize, 1, file); fclose(file); // for (int i=0;ime=me_; + this->me = me_; //read the header - int chunk=getint32();//MThd - if (chunk!=0x4d546864) return(-1); - int size=getint32(); - if (size!=6) return(-1);//header is always 6 bytes long + int chunk = getint32(); //MThd + if(chunk != 0x4d546864) + return -1; + int size = getint32(); + if(size != 6) + return -1; //header is always 6 bytes long - int format=getint16(); - printf("format %d\n",format); + int format = getint16(); + printf("format %d\n", format); - int ntracks=getint16();//this is always 1 if the format is "0" - printf("ntracks %d\n",ntracks); + int ntracks = getint16(); //this is always 1 if the format is "0" + printf("ntracks %d\n", ntracks); - int division=getint16(); - printf("division %d\n",division); - if (division>=0) {//delta time units in each a quater note + int division = getint16(); + printf("division %d\n", division); + if(division >= 0) { //delta time units in each a quater note // tick=???; - } else {//SMPTE (frames/second and ticks/frame) - printf("ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); - }; + } + else //SMPTE (frames/second and ticks/frame) + printf( + "ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); + ; - if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1; + if(ntracks >= NUM_MIDI_TRACKS) + ntracks = NUM_MIDI_TRACKS - 1; - for (int n=0;nme=NULL; - return(0); -}; + this->me = NULL; + return 0; +} //private members int MIDIFile::parsetrack(int ntrack) { - printf("\n--==*Reading track %d **==--\n",ntrack); + printf("\n--==*Reading track %d **==--\n", ntrack); - int chunk=getint32();//MTrk - if (chunk!=0x4d54726b) return(-1); + int chunk = getint32(); //MTrk + if(chunk != 0x4d54726b) + return -1; - int size=getint32(); - printf("size = %d\n",size); + int size = getint32(); + printf("size = %d\n", size); - int oldmidifilek=midifilek; + int oldmidifilek = midifilek; - unsigned char lastmsg=0; - unsigned int dt=0; + unsigned char lastmsg = 0; + unsigned int dt = 0; - while (!midieof) { - unsigned int msgdeltatime=getvarint32(); + while(!midieof) { + unsigned int msgdeltatime = getvarint32(); /// printf("MSGDELTATIME = %d\n",msgdeltatime); // dt+=msgdeltatime; - int msg=peekbyte(); + int msg = peekbyte(); /// printf("raw msg=0x%x ",msg); - if (msg<0x80) { - msg=lastmsg; - } else { - lastmsg=msg; + if(msg < 0x80) + msg = lastmsg; + else { + lastmsg = msg; getbyte(); - }; + } /// printf("msg=0x%x\n",msg); // dt+=msgdeltatime; add_dt(ntrack, msgdeltatime); - unsigned int mtype,mlength; + unsigned int mtype, mlength; - switch (msg) { - case 0x80 ... 0x8f://note on off - parsenoteoff(ntrack,msg & 0x0f,dt); - dt=0; + switch(msg) { + case 0x80 ... 0x8f: //note on off + parsenoteoff(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0x90 ... 0x9f://note on (or note off) - parsenoteon(ntrack,msg & 0x0f,dt); - dt=0; + case 0x90 ... 0x9f: //note on (or note off) + parsenoteon(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xa0 ... 0xaf://aftertouch - ignored + case 0xa0 ... 0xaf: //aftertouch - ignored skipnbytes(2); break; - case 0xb0 ... 0xbf://control change - parsecontrolchange(ntrack,msg & 0x0f,dt); - dt=0; + case 0xb0 ... 0xbf: //control change + parsecontrolchange(ntrack, msg & 0x0f, dt); + dt = 0; break; - case 0xc0 ... 0xcf://program change - ignored + case 0xc0 ... 0xcf: //program change - ignored skipnbytes(1); break; - case 0xd0 ... 0xdf://channel pressure - ignored + case 0xd0 ... 0xdf: //channel pressure - ignored skipnbytes(1); break; - case 0xe0 ... 0xef://channel mode messages + case 0xe0 ... 0xef: //channel mode messages skipnbytes(2); break; - case 0xf0://sysex - ignored - while (getbyte()!=0xf7) { - if (midieof) break; - }; + case 0xf0: //sysex - ignored + while(getbyte() != 0xf7) { + if(midieof) + break; + } break; - case 0xf7://sysex (another type) - ignored + case 0xf7: //sysex (another type) - ignored skipnbytes(getvarint32()); break; - case 0xff://meta-event - mtype=getbyte(); - mlength=getbyte(); - parsemetaevent(mtype,mlength); + case 0xff: //meta-event + mtype = getbyte(); + mlength = getbyte(); + parsemetaevent(mtype, mlength); break; default: getbyte(); - printf("UNKNOWN message! 0x%x\n",msg); - return(-1); + printf("UNKNOWN message! 0x%x\n", msg); + return -1; break; - }; + } - if (midieof) return(-1); + if(midieof) + return -1; - if ((midifilek-oldmidifilek)==size) break; - else if ((midifilek-oldmidifilek)>size) return(-1); + if((midifilek - oldmidifilek) == size) + break; + else + if((midifilek - oldmidifilek) > size) + return -1; // if (size!=6) return(-1);//header is always 6 bytes long - }; + } printf("End Track\n\n"); - return(0); -}; + return 0; +} -void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteoff(char ntrack, char chan, unsigned int dt) { unsigned char note; - note=getbyte(); + note = getbyte(); - unsigned char noteoff_velocity=getbyte();//unused by zynaddsubfx - noteoff_velocity=0; - if (chan>=NUM_MIDI_CHANNELS) return; + unsigned char noteoff_velocity = getbyte(); //unused by zynaddsubfx + noteoff_velocity = 0; + if(chan >= NUM_MIDI_CHANNELS) + return; - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=0; - me->tmpevent.channel=chan; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = 0; + me->tmpevent.channel = chan; - printf("Note off:%d \n",note); + printf("Note off:%d \n", note); ///test // ntrack=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); - -}; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsenoteon(char ntrack, char chan, unsigned int dt) { - unsigned char note,vel; - note=getbyte(); - vel=getbyte(); + unsigned char note, vel; + note = getbyte(); + vel = getbyte(); // printf("ntrack=%d\n",ntrack); - printf("[dt %d ] Note on:%d %d\n",dt,note,vel); + printf("[dt %d ] Note on:%d %d\n", dt, note, vel); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=1; - me->tmpevent.par1=note; - me->tmpevent.par2=vel; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 1; + me->tmpevent.par1 = note; + me->tmpevent.par2 = vel; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} - - -}; - -void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt) +void MIDIFile::parsecontrolchange(char ntrack, char chan, unsigned int dt) { - unsigned char control,value; - control=getbyte(); - value=getbyte(); + unsigned char control, value; + control = getbyte(); + value = getbyte(); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - printf("[dt %d] Control change:%d %d\n",dt,control,value); + printf("[dt %d] Control change:%d %d\n", dt, control, value); - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=2; - me->tmpevent.par1=control;//???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn - me->tmpevent.par2=value; - me->tmpevent.channel=chan; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 2; + me->tmpevent.par1 = control; //???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn + me->tmpevent.par2 = value; + me->tmpevent.channel = chan; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} -}; - -void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt) +void MIDIFile::parsepitchwheel(char ntrack, char chan, unsigned int dt) { - unsigned char valhi,vallo; - vallo=getbyte(); - valhi=getbyte(); + unsigned char valhi, vallo; + vallo = getbyte(); + valhi = getbyte(); - if (chan>=NUM_MIDI_CHANNELS) return; + if(chan >= NUM_MIDI_CHANNELS) + return; - int value=(int)valhi*128+vallo; + int value = (int)valhi * 128 + vallo; - printf("[dt %d] Pitch wheel:%d\n",dt,value); + printf("[dt %d] Pitch wheel:%d\n", dt, value); +} -}; - -void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength) +void MIDIFile::parsemetaevent(unsigned char mtype, unsigned char mlength) { - int oldmidifilek=midifilek; - printf("meta-event type=0x%x length=%d\n",mtype,mlength); + int oldmidifilek = midifilek; + printf("meta-event type=0x%x length=%d\n", mtype, mlength); - midifilek=oldmidifilek+mlength; - -}; + midifilek = oldmidifilek + mlength; +} void MIDIFile::add_dt(char ntrack, unsigned int dt) { - me->tmpevent.deltatime=convertdt(dt); - me->tmpevent.type=255; - me->tmpevent.par1=0; - me->tmpevent.par2=0; - me->tmpevent.channel=0; - me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); -}; + me->tmpevent.deltatime = convertdt(dt); + me->tmpevent.type = 255; + me->tmpevent.par1 = 0; + me->tmpevent.par2 = 0; + me->tmpevent.channel = 0; + me->writeevent(&me->miditrack[(int)ntrack].record, &me->tmpevent); +} unsigned int MIDIFile::convertdt(unsigned int dt) { - double result=dt; - printf("DT=%d\n",dt); + double result = dt; + printf("DT=%d\n", dt); - return((int) (result*15.0)); -}; + return (int) (result * 15.0); +} void MIDIFile::clearmidifile() { - if (midifile!=NULL) delete(midifile); - midifile=NULL; - midifilesize=0; - midifilek=0; - midieof=false; - data.tick=0.05; -}; + if(midifile != NULL) + delete (midifile); + midifile = NULL; + midifilesize = 0; + midifilek = 0; + midieof = false; + data.tick = 0.05; +} unsigned char MIDIFile::getbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } /// printf("(%d) ",midifile[midifilek]); - return(midifile[midifilek++]); -}; + return midifile[midifilek++]; +} unsigned char MIDIFile::peekbyte() { - if (midifilek>=midifilesize) { - midieof=true; - return(0); - }; - return(midifile[midifilek]); -}; + if(midifilek >= midifilesize) { + midieof = true; + return 0; + } + return midifile[midifilek]; +} unsigned int MIDIFile::getint32() { - unsigned int result=0; - for (int i=0;i<4;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned int result = 0; + for(int i = 0; i < 4; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned short int MIDIFile::getint16() { - unsigned short int result=0; - for (int i=0;i<2;i++) { - result=result*256+getbyte(); - }; - if (midieof) result=0; - return(result); -}; + unsigned short int result = 0; + for(int i = 0; i < 2; i++) + result = result * 256 + getbyte(); + ; + if(midieof) + result = 0; + return result; +} unsigned int MIDIFile::getvarint32() { - unsigned long result=0; + unsigned long result = 0; unsigned char b; /// printf("\n[start]"); - if ((result = getbyte()) & 0x80) { + if((result = getbyte()) & 0x80) { result &= 0x7f; - do { - b=getbyte(); + do { + b = getbyte(); result = (result << 7) + (b & 0x7f); - } while (b & 0x80); + } while(b & 0x80); } /// printf("[end - result= %d]\n",result); return result; -}; +} void MIDIFile::skipnbytes(int n) { - midifilek+=n; - if (midifilek>=midifilesize) { - midifilek=midifilesize-1; - midieof=true; - }; -}; + midifilek += n; + if(midifilek >= midifilesize) { + midifilek = midifilesize - 1; + midieof = true; + } +} diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.h b/plugins/zynaddsubfx/src/Seq/MIDIFile.h index 7f831589f..374d98c1c 100644 --- a/plugins/zynaddsubfx/src/Seq/MIDIFile.h +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.h @@ -29,66 +29,64 @@ /**MIDI file loader*/ class MIDIFile { -public: - MIDIFile(); - ~MIDIFile(); + public: + MIDIFile(); + ~MIDIFile(); - /**Loads the given file - * @param filename The name of the file to load - * @return -1 if there is an error, otherwise 0*/ - int loadfile(const char *filename); + /**Loads the given file + * @param filename The name of the file to load + * @return -1 if there is an error, otherwise 0*/ + int loadfile(const char *filename); - //returns -1 if there is an error, otherwise 0 - int parsemidifile(MIDIEvents *me_); + //returns -1 if there is an error, otherwise 0 + int parsemidifile(MIDIEvents *me_); -private: - MIDIEvents *me; + private: + MIDIEvents *me; - unsigned char *midifile; - int midifilesize,midifilek; - bool midieof; + unsigned char *midifile; + int midifilesize, midifilek; + bool midieof; - //returns -1 if there is an error, otherwise 0 - int parsetrack(int ntrack); + //returns -1 if there is an error, otherwise 0 + int parsetrack(int ntrack); - void parsenoteoff(char ntrack,char chan,unsigned int dt); - void parsenoteon(char ntrack,char chan,unsigned int dt); - void parsecontrolchange(char ntrack,char chan,unsigned int dt); - void parsepitchwheel(char ntrack,char chan, unsigned int dt); - void parsemetaevent(unsigned char mtype,unsigned char mlength); + void parsenoteoff(char ntrack, char chan, unsigned int dt); + void parsenoteon(char ntrack, char chan, unsigned int dt); + void parsecontrolchange(char ntrack, char chan, unsigned int dt); + void parsepitchwheel(char ntrack, char chan, unsigned int dt); + void parsemetaevent(unsigned char mtype, unsigned char mlength); - void add_dt(char ntrack, unsigned int dt); + void add_dt(char ntrack, unsigned int dt); - void clearmidifile(); + void clearmidifile(); - //convert the delta-time to internal format - unsigned int convertdt(unsigned int dt); + //convert the delta-time to internal format + unsigned int convertdt(unsigned int dt); - /* Low Level MIDIfile functions */ + /* Low Level MIDIfile functions */ - //get a byte from the midifile - unsigned char getbyte(); + //get a byte from the midifile + unsigned char getbyte(); - //peek the current byte from the midifile - unsigned char peekbyte(); + //peek the current byte from the midifile + unsigned char peekbyte(); - //get a set of 4 bytes from the midifile - unsigned int getint32(); + //get a set of 4 bytes from the midifile + unsigned int getint32(); - //get a word of 2 bytes from the midifile - unsigned short int getint16(); + //get a word of 2 bytes from the midifile + unsigned short int getint16(); - //read a variable length quantity - unsigned int getvarint32(); + //read a variable length quantity + unsigned int getvarint32(); - //skip some bytes - void skipnbytes(int n); - - struct { - double tick;//how many seconds one tick has - - }data; + //skip some bytes + void skipnbytes(int n); + struct { + double tick; //how many seconds one tick has + } data; }; #endif diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp index d0a32f1c4..cedc9249e 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.cpp +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.cpp @@ -33,76 +33,85 @@ Sequencer::Sequencer() { - play=0; - for (int i=0;i1sec) sa elimin nota - if (ntrack==1) printf("_ %f %.2f (%d)\n",nextevent[(int)ntrack].time,playtime[(int)ntrack].abs,nextevent[(int)ntrack].ev.par2); + if(ntrack == 1) + printf("_ %f %.2f (%d)\n", nextevent[(int)ntrack].time, + playtime[(int)ntrack].abs, nextevent[(int)ntrack].ev.par2); - *type=nextevent[(int)ntrack].ev.type; - *par1=nextevent[(int)ntrack].ev.par1; - *par2=nextevent[(int)ntrack].ev.par2; - *midich=nextevent[(int)ntrack].ev.channel; + *type = nextevent[(int)ntrack].ev.type; + *par1 = nextevent[(int)ntrack].ev.par1; + *par2 = nextevent[(int)ntrack].ev.par2; + *midich = nextevent[(int)ntrack].ev.channel; - double dt=nextevent[(int)ntrack].ev.deltatime*0.0001*realplayspeed; - printf("zzzzzzzzzzzzzz[%d] %d\n",ntrack,nextevent[(int)ntrack].ev.deltatime); - nextevent[(int)ntrack].time+=dt; + double dt = nextevent[(int)ntrack].ev.deltatime * 0.0001 * realplayspeed; + printf("zzzzzzzzzzzzzz[%d] %d\n", + ntrack, + nextevent[(int)ntrack].ev.deltatime); + nextevent[(int)ntrack].time += dt; // printf("%f - %d %d \n",nextevent[ntrack].time,par1,par2); - return(0);//?? sau 1 -}; + return 0; //?? sau 1 +} /************** Timer stuff ***************/ void Sequencer::resettime(timestruct *t) { - t->abs=0.0; - t->rel=0.0; + t->abs = 0.0; + t->rel = 0.0; timeval tval; - t->last=0.0; + t->last = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - t->last=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + t->last = tval.tv_sec + tval.tv_usec * 0.000001; #endif - -}; +} void Sequencer::updatecounter(timestruct *t) { timeval tval; - double current=0.0; + double current = 0.0; #ifndef OS_WINDOWS - if (gettimeofday(&tval,NULL)==0) - current=tval.tv_sec+tval.tv_usec*0.000001; + if(gettimeofday(&tval, NULL) == 0) + current = tval.tv_sec + tval.tv_usec * 0.000001; #endif - t->rel=current - t->last; - t->abs+=t->rel; - t->last=current; + t->rel = current - t->last; + t->abs += t->rel; + t->last = current; // printf("%f %f %f\n",t->last,t->abs,t->rel); -}; +} void Sequencer::setplayspeed(int speed) { - playspeed=speed; - realplayspeed=pow(10.0,speed/128.0); -}; + playspeed = speed; + realplayspeed = pow(10.0, speed / 128.0); +} diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.h b/plugins/zynaddsubfx/src/Seq/Sequencer.h index 7798c9943..dd2d75613 100644 --- a/plugins/zynaddsubfx/src/Seq/Sequencer.h +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.h @@ -30,61 +30,60 @@ * \todo restructure some of this code*/ class Sequencer:public MIDIEvents { -public: - /**Constructor*/ - Sequencer(); - /**Destructor*/ - ~Sequencer(); + public: + /**Constructor*/ + Sequencer(); + /**Destructor*/ + ~Sequencer(); - //these functions are called by the master and are ignored if the recorder/player are stopped - void recordnote(char chan, char note, char vel); - void recordcontroller(char chan,unsigned int type,int par); + //these functions are called by the master and are ignored if the recorder/player are stopped + void recordnote(char chan, char note, char vel); + void recordcontroller(char chan, unsigned int type, int par); - /**Gets an event \todo better description - * - * this is only for player - * @return 1 if this must be called at least once more - * 0 if there are no more notes for the current time - * -1 if there are no notes*/ - int getevent(char ntrack, int *midich,int *type,int *par1, int *par2); + /**Gets an event \todo better description + * + * this is only for player + * @return 1 if this must be called at least once more + * 0 if there are no more notes for the current time + * -1 if there are no notes*/ + int getevent(char ntrack, int *midich, int *type, int *par1, int *par2); - /**Imports a given midifile - * @return 0 if ok or -1 if there is a error loading file*/ - int importmidifile(const char *filename); + /**Imports a given midifile + * @return 0 if ok or -1 if there is a error loading file*/ + int importmidifile(const char *filename); - void startplay(); - void stopplay(); + void startplay(); + void stopplay(); - int play; - int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x - void setplayspeed(int speed); + int play; + int playspeed; //viteza de rulare (0.1x-10x), 0=1.0x, 128=10x + void setplayspeed(int speed); -private: + private: - MIDIFile midifile; + MIDIFile midifile; - /* Timer */ - struct timestruct { - double abs;//the time from the begining of the track - double rel;//the time difference between the last and the current event - double last;//the time of the last event (absolute, since 1 Jan 1970) - //these must be double, because the float's precision is too low - //and all these represent the time in seconds - } playtime[NUM_MIDI_TRACKS]; + /* Timer */ + struct timestruct { + double abs; //the time from the begining of the track + double rel; //the time difference between the last and the current event + double last; //the time of the last event (absolute, since 1 Jan 1970) + //these must be double, because the float's precision is too low + //and all these represent the time in seconds + } playtime[NUM_MIDI_TRACKS]; - void resettime(timestruct *t); - void updatecounter(timestruct *t);//this updates the timer values + void resettime(timestruct *t); + void updatecounter(timestruct *t); //this updates the timer values - /* Player only*/ + /* Player only*/ - struct { - event ev; - double time; - } nextevent[NUM_MIDI_TRACKS]; - - double realplayspeed; + struct { + event ev; + double time; + } nextevent[NUM_MIDI_TRACKS]; + double realplayspeed; }; #endif diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.cpp b/plugins/zynaddsubfx/src/Synth/ADnote.cpp index d6a0b7bdf..a70f3feef 100644 --- a/plugins/zynaddsubfx/src/Synth/ADnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/ADnote.cpp @@ -22,402 +22,689 @@ #include #include #include - +#include #include "../globals.h" #include "../Misc/Util.h" #include "ADnote.h" -ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent) +ADnote::ADnote(ADnoteParameters *pars, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool besilent) { - ready=0; + ready = 0; - tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassl=new REALTYPE [SOUND_BUFFER_SIZE]; - bypassr=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwavel = new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwaver = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassl = new REALTYPE [SOUND_BUFFER_SIZE]; + bypassr = new REALTYPE [SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - Legato.silent=besilent; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + Legato.silent = besilent; - partparams=pars; - ctl=ctl_; - portamento=portamento_; - midinote=midinote_; - NoteEnabled=ON; - basefreq=freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; - time=0.0; - stereo=pars->GlobalPar.PStereo; + partparams = pars; + ctl = ctl_; + portamento = portamento_; + midinote = midinote_; + NoteEnabled = ON; + basefreq = freq; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; + time = 0.0; + stereo = pars->GlobalPar.PStereo; - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); - if (pars->GlobalPar.PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; + if(pars->GlobalPar.PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->GlobalPar.PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->GlobalPar.PPunchVelocitySensing)); + REALTYPE time = + pow(10, 3.0 * pars->GlobalPar.PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, + pars->GlobalPar.PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; - for (int nvoice=0;nvoiceVoicePar[nvoice].OscilSmp->newrandseed(rand()); - NoteVoicePar[nvoice].OscilSmp=NULL; - NoteVoicePar[nvoice].FMSmp=NULL; - NoteVoicePar[nvoice].VoiceOut=NULL; + NoteVoicePar[nvoice].OscilSmp = NULL; + NoteVoicePar[nvoice].FMSmp = NULL; + NoteVoicePar[nvoice].VoiceOut = NULL; - NoteVoicePar[nvoice].FMVoice=-1; + NoteVoicePar[nvoice].FMVoice = -1; + unison_size[nvoice] = 1; - if (pars->VoicePar[nvoice].Enabled==0) { - NoteVoicePar[nvoice].Enabled=OFF; + if(pars->VoicePar[nvoice].Enabled == 0) { + NoteVoicePar[nvoice].Enabled = OFF; continue; //the voice is disabled - }; + } - NoteVoicePar[nvoice].Enabled=ON; - NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + unison_stereo_spread[nvoice] = + pars->VoicePar[nvoice].Unison_stereo_spread / 127.0; + int unison = pars->VoicePar[nvoice].Unison_size; + if(unison < 1) + unison = 1; + + //compute unison + unison_size[nvoice] = unison; + + unison_base_freq_rap[nvoice] = new REALTYPE[unison]; + unison_freq_rap[nvoice] = new REALTYPE[unison]; + unison_invert_phase[nvoice] = new bool[unison]; + REALTYPE unison_spread = pars->getUnisonFrequencySpreadCents( + nvoice); + REALTYPE unison_real_spread = pow(2.0, (unison_spread * 0.5) / 1200.0); + REALTYPE unison_vibratto_a = pars->VoicePar[nvoice].Unison_vibratto + / 127.0; //0.0 .. 1.0 + + + switch(unison) { + case 1: + unison_base_freq_rap[nvoice][0] = 1.0; //if the unison is not used, always make the only subvoice to have the default note + break; + case 2: { //unison for 2 subvoices + unison_base_freq_rap[nvoice][0] = 1.0 / unison_real_spread; + unison_base_freq_rap[nvoice][1] = unison_real_spread; + }; + break; + default: { //unison for more than 2 subvoices + REALTYPE unison_values[unison]; + REALTYPE min = -1e-6, max = 1e-6; + for(int k = 0; k < unison; k++) { + REALTYPE step = (k / (REALTYPE) (unison - 1)) * 2.0 - 1.0; //this makes the unison spread more uniform + REALTYPE val = step + (RND * 2.0 - 1.0) / (unison - 1); + unison_values[k] = val; + if(val > max) + max = val; + if(val < min) + min = val; + } + REALTYPE diff = max - min; + for(int k = 0; k < unison; k++) { + unison_values[k] = + (unison_values[k] - (max + min) * 0.5) / diff; //the lowest value will be -1 and the highest will be 1 + unison_base_freq_rap[nvoice][k] = + pow(2.0, (unison_spread * unison_values[k]) / 1200); + } + }; + } + + //unison vibrattos + if(unison > 1) { + for(int k = 0; k < unison; k++) //reduce the frequency difference for larger vibrattos + unison_base_freq_rap[nvoice][k] = 1.0 + + (unison_base_freq_rap[ + nvoice][k] + - 1.0) + * (1.0 - unison_vibratto_a); + ; + } + unison_vibratto[nvoice].step = new REALTYPE[unison]; + unison_vibratto[nvoice].position = new REALTYPE[unison]; + unison_vibratto[nvoice].amplitude = + (unison_real_spread - 1.0) * unison_vibratto_a; + + REALTYPE increments_per_second = SAMPLE_RATE + / (REALTYPE)SOUND_BUFFER_SIZE; + REALTYPE vibratto_base_period = 0.25 + * pow(2.0, + (1.0 + - pars->VoicePar[nvoice]. + Unison_vibratto_speed / 127.0) * 4.0); + for(int k = 0; k < unison; k++) { + unison_vibratto[nvoice].position[k] = RND * 1.8 - 0.9; + REALTYPE vibratto_period = vibratto_base_period * pow( + 2.0, + RND * 2.0 + - 1.0); //make period to vary randomly from 50% to 200% vibratto base period + + REALTYPE m = 4.0 / (vibratto_period * increments_per_second); + if(RND < 0.5) + m = -m; + unison_vibratto[nvoice].step[k] = m; + } + + if(unison == 1) { //no vibratto for a single voice + unison_vibratto[nvoice].step[0] = 0.0; + unison_vibratto[nvoice].position[0] = 0.0; + unison_vibratto[nvoice].amplitude = 0.0; + } + + //phase invert for unison + unison_invert_phase[nvoice][0] = false; + if(unison != 1) { + int inv = pars->VoicePar[nvoice].Unison_invert_phase; + switch(inv) { + case 0: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = false; + break; + case 1: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = (RND > 0.5); + break; + default: for(int k = 0; k < unison; k++) + unison_invert_phase[nvoice][k] = + (k % inv == 0) ? true : false; + break; + } + } + + + oscfreqhi[nvoice] = new int[unison]; + oscfreqlo[nvoice] = new REALTYPE[unison]; + oscfreqhiFM[nvoice] = new unsigned int[unison]; + oscfreqloFM[nvoice] = new REALTYPE[unison]; + oscposhi[nvoice] = new int[unison]; + oscposlo[nvoice] = new REALTYPE[unison]; + oscposhiFM[nvoice] = new unsigned int[unison]; + oscposloFM[nvoice] = new REALTYPE[unison]; + + NoteVoicePar[nvoice].Enabled = ON; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - }; + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; - oscposhi[nvoice]=0; - oscposlo[nvoice]=0.0; - oscposhiFM[nvoice]=0; - oscposloFM[nvoice]=0.0; - NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = 0; + oscposlo[nvoice][k] = 0.0; + oscposhiFM[nvoice][k] = 0; + oscposloFM[nvoice][k] = 0.0; + } + + NoteVoicePar[nvoice].OscilSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //the extra points contains the first point //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice), - pars->VoicePar[nvoice].Presonance); + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int oscposhi_start = + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); //I store the first elments to the last position for speedups - for (int i=0;iVoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - oscposhi[nvoice]%=OSCIL_SIZE; + oscposhi_start += + (int)((pars->VoicePar[nvoice].Poscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + oscposhi_start %= OSCIL_SIZE; + for(int k = 0; k < unison; k++) { + oscposhi[nvoice][k] = oscposhi_start; + oscposhi_start = (int)(RND * (OSCIL_SIZE - 1)); //put random starting point for other subvoices + } - NoteVoicePar[nvoice].FreqLfo=NULL; - NoteVoicePar[nvoice].FreqEnvelope=NULL; + NoteVoicePar[nvoice].FreqLfo = NULL; + NoteVoicePar[nvoice].FreqEnvelope = NULL; - NoteVoicePar[nvoice].AmpLfo=NULL; - NoteVoicePar[nvoice].AmpEnvelope=NULL; + NoteVoicePar[nvoice].AmpLfo = NULL; + NoteVoicePar[nvoice].AmpEnvelope = NULL; - NoteVoicePar[nvoice].VoiceFilter=NULL; - NoteVoicePar[nvoice].FilterEnvelope=NULL; - NoteVoicePar[nvoice].FilterLfo=NULL; + NoteVoicePar[nvoice].VoiceFilterL = NULL; + NoteVoicePar[nvoice].VoiceFilterR = NULL; + NoteVoicePar[nvoice].FilterEnvelope = NULL; + NoteVoicePar[nvoice].FilterLfo = NULL; - NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; - switch (pars->VoicePar[nvoice].PFMEnabled) { + switch(pars->VoicePar[nvoice].PFMEnabled) { case 1: - NoteVoicePar[nvoice].FMEnabled=MORPH; + NoteVoicePar[nvoice].FMEnabled = MORPH; break; case 2: - NoteVoicePar[nvoice].FMEnabled=RING_MOD; + NoteVoicePar[nvoice].FMEnabled = RING_MOD; break; case 3: - NoteVoicePar[nvoice].FMEnabled=PHASE_MOD; + NoteVoicePar[nvoice].FMEnabled = PHASE_MOD; break; case 4: - NoteVoicePar[nvoice].FMEnabled=FREQ_MOD; + NoteVoicePar[nvoice].FMEnabled = FREQ_MOD; break; case 5: - NoteVoicePar[nvoice].FMEnabled=PITCH_MOD; + NoteVoicePar[nvoice].FMEnabled = PITCH_MOD; break; default: - NoteVoicePar[nvoice].FMEnabled=NONE; - }; + NoteVoicePar[nvoice].FMEnabled = NONE; + } - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; - NoteVoicePar[nvoice].FMFreqEnvelope=NULL; - NoteVoicePar[nvoice].FMAmpEnvelope=NULL; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMFreqEnvelope = NULL; + NoteVoicePar[nvoice].FMAmpEnvelope = NULL; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - FMoldsmp[nvoice]=0.0;//this is for FM (integration) + FMoldsmp[nvoice] = new REALTYPE [unison]; + for(int k = 0; k < unison; k++) + FMoldsmp[nvoice][k] = 0.0; //this is for FM (integration) - firsttick[nvoice]=1; - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - }; + firsttick[nvoice] = 1; + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } + + max_unison = 1; + for(int nvoice = 0; nvoice < NUM_VOICES; nvoice++) + if(unison_size[nvoice] > max_unison) + max_unison = unison_size[nvoice]; + ; + + tmpwave_unison = new REALTYPE *[max_unison]; + for(int k = 0; k < max_unison; k++) { + tmpwave_unison[k] = new REALTYPE[SOUND_BUFFER_SIZE]; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwave_unison[k][i] = 0.0; + } initparameters(); - ready=1; -}; - + ready = 1; +} // ADlegatonote: This function is (mostly) a copy of ADnote(...) and // initparameters() stuck together with some lines removed so that it // only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall) +void ADnote::ADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote_, + bool externcall) { - ADnoteParameters *pars=partparams; + ADnoteParameters *pars = partparams; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote_; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote_; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - midinote=midinote_; - basefreq=freq; + portamento = portamento_; + midinote = midinote_; + basefreq = freq; - if (velocity>1.0) velocity=1.0; - this->velocity=velocity; + if(velocity > 1.0) + velocity = 1.0; + this->velocity = velocity; - NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); - bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + NoteGlobalPar.Detune = getdetune(pars->GlobalPar.PDetuneType, + pars->GlobalPar.PCoarseDetune, + pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier = pars->getBandwidthDetuneMultiplier(); - if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + if(pars->GlobalPar.PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->GlobalPar.PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq - pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalPar.GlobalFilter->getfreq() //center freq + + pars->GlobalPar.PFilterVelocityScale + / 127.0 * 6.0 //velocity sensing + * (VelF(velocity, + pars->GlobalPar. + PFilterVelocityScaleFunction) - 1); - for (int nvoice=0;nvoiceVoicePar[nvoice].Pfixedfreq; - NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + NoteVoicePar[nvoice].fixedfreq = pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET = pars->VoicePar[nvoice].PfixedfreqET; //use the Globalpars.detunetype if the detunetype is 0 - if (pars->VoicePar[nvoice].PDetuneType!=0) { - NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - } else { - NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune - NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType - ,0,pars->VoicePar[nvoice].PDetune);//fine detune - }; - if (pars->VoicePar[nvoice].PFMDetuneType!=0) { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - } else { - NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType - ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); - }; + if(pars->VoicePar[nvoice].PDetuneType != 0) { + NoteVoicePar[nvoice].Detune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->VoicePar[nvoice].PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + else { + NoteVoicePar[nvoice].Detune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PCoarseDetune, + 8192); //coarse detune + NoteVoicePar[nvoice].FineDetune = getdetune( + pars->GlobalPar.PDetuneType, + 0, + pars->VoicePar[nvoice].PDetune); //fine detune + } + if(pars->VoicePar[nvoice].PFMDetuneType != 0) + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->VoicePar[nvoice].PFMDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + else + NoteVoicePar[nvoice].FMDetune = getdetune( + pars->GlobalPar.PDetuneType, + pars->VoicePar[nvoice]. + PFMCoarseDetune, + pars->VoicePar[nvoice].PFMDetune); + ; //Get the voice's oscil or external's voice oscil - int vc=nvoice; - if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; - if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + int vc = nvoice; + if(pars->VoicePar[nvoice].Pextoscil != -1) + vc = pars->VoicePar[nvoice].Pextoscil; + if(!pars->GlobalPar.Hrandgrouping) + pars->VoicePar[vc].OscilSmp->newrandseed(rand()); - ///oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance); - pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance);//(gf)Modif of the above line. + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp, + getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); //(gf)Modif of the above line. //I store the first elments to the last position for speedups - for (int i=0;iVoicePar[nvoice].VoiceFilter->getfreq(); - NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + NoteVoicePar[nvoice].FilterCenterPitch = + pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass = + pars->VoicePar[nvoice].Pfilterbypass; - NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMVoice = pars->VoicePar[nvoice].PFMVoice; //Compute the Voice's modulator volume (incl. damping) - REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); + REALTYPE fmvoldamp = pow(440.0 / getvoicebasefreq( + nvoice), + pars->VoicePar[nvoice].PFMVolumeDamp / 64.0 + - 1.0); - switch (NoteVoicePar[nvoice].FMEnabled) { + switch(NoteVoicePar[nvoice].FMEnabled) { case PHASE_MOD: - fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + fmvoldamp = + pow(440.0 / getvoicebasefreq( + nvoice), pars->VoicePar[nvoice].PFMVolumeDamp / 64.0); + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; case FREQ_MOD: - NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + NoteVoicePar[nvoice].FMVolume = + (exp(pars->VoicePar[nvoice].PFMVolume / 127.0 + * FM_AMP_MULTIPLIER) - 1.0) * fmvoldamp * 4.0; break; - // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? - // break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; default: - if (fmvoldamp>1.0) fmvoldamp=1.0; - NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; - }; + if(fmvoldamp > 1.0) + fmvoldamp = 1.0; + NoteVoicePar[nvoice].FMVolume = pars->VoicePar[nvoice].PFMVolume + / 127.0 * fmvoldamp; + } //Voice's modulator velocity sensing - NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + NoteVoicePar[nvoice].FMVolume *= + VelF(velocity, + partparams->VoicePar[nvoice].PFMVelocityScaleFunction); - NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); - }; + NoteVoicePar[nvoice].DelayTicks = + (int)((exp(pars->VoicePar[nvoice].PDelay / 127.0 + * log(50.0)) + - 1.0) / SOUND_BUFFER_SIZE / 10.0 * SAMPLE_RATE); + } /// initparameters(); /////////////// // Altered content of initparameters(): - int nvoice,i,tmp[NUM_VOICES]; + int nvoice, i, tmp[NUM_VOICES]; - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoiceVoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; - newamplitude[nvoice]=1.0; - if ((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].AmpEnvelope!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + newamplitude[nvoice] = 1.0; + if((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].AmpEnvelope != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + ; - if ((partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) - && (NoteVoicePar[nvoice].AmpLfo!=NULL)) { - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if((partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) + && (NoteVoicePar[nvoice].AmpLfo != NULL)) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + ; - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); ///oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; // / oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp); //(gf) Modif of the above line. - for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); ///oscposhiFM[nvoice]%=OSCIL_SIZE; - }; + } - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if ((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) - && (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL)) { - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) + && (NoteVoicePar[nvoice].FMAmpEnvelope != NULL)) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + ; + } - for (nvoice=0;nvoiceGlobalPar.FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope( + partparams->GlobalPar.FreqEnvelope, + basefreq); + NoteGlobalPar.FreqLfo = new LFO(partparams->GlobalPar.FreqLfo, + basefreq); - NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq); + NoteGlobalPar.AmpEnvelope = new Envelope(partparams->GlobalPar.AmpEnvelope, + basefreq); + NoteGlobalPar.AmpLfo = new LFO(partparams->GlobalPar.AmpLfo, basefreq); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 + * pow(0.1, 3.0 + * (1.0 - partparams->GlobalPar.PVolume / 96.0)) //-60 dB .. 0 dB + * VelF( + velocity, + partparams->GlobalPar. + PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter); - if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter); + NoteGlobalPar.GlobalFilterL = new Filter(partparams->GlobalPar.GlobalFilter); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR = new Filter( + partparams->GlobalPar.GlobalFilter); - NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq); - NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterEnvelope = new Envelope( + partparams->GlobalPar.FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(partparams->GlobalPar.FilterLfo, + basefreq); + NoteGlobalPar.FilterQ = partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = + partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); // Forbids the Modulation Voice to be greater or equal than voice - for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + for(i = 0; i < NUM_VOICES; i++) + if(NoteVoicePar[i].FMVoice >= i) + NoteVoicePar[i].FMVoice = -1; // Voice Parameter init - for (nvoice=0;nvoiceVoicePar[nvoice].Type; + NoteVoicePar[nvoice].noisetype = partparams->VoicePar[nvoice].Type; /* Voice Amplitude Parameters Init */ - NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB - *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + NoteVoicePar[nvoice].Volume = + pow(0.1, 3.0 * (1.0 - partparams->VoicePar[nvoice].PVolume / 127.0)) // -60 dB .. 0 dB + * VelF(velocity, + partparams->VoicePar[nvoice].PAmpVelocityScaleFunction); //velocity - if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + if(partparams->VoicePar[nvoice].PVolumeminus != 0) + NoteVoicePar[nvoice].Volume = -NoteVoicePar[nvoice].Volume; - if (partparams->VoicePar[nvoice].PPanning==0) - NoteVoicePar[nvoice].Panning=RND;// random panning - else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + if(partparams->VoicePar[nvoice].PPanning == 0) + NoteVoicePar[nvoice].Panning = RND; // random panning + else + NoteVoicePar[nvoice].Panning = + partparams->VoicePar[nvoice].PPanning / 128.0; - newamplitude[nvoice]=1.0; - if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq); - NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - }; + newamplitude[nvoice] = 1.0; + if(partparams->VoicePar[nvoice].PAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].AmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].AmpEnvelope, + basefreq); + NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); //discard the first envelope sample + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + } - if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) { - NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq); - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); - }; + if(partparams->VoicePar[nvoice].PAmpLfoEnabled != 0) { + NoteVoicePar[nvoice].AmpLfo = new LFO( + partparams->VoicePar[nvoice].AmpLfo, + basefreq); + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); + } /* Voice Frequency Parameters Init */ - if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FreqEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq); + if(partparams->VoicePar[nvoice].PFreqLfoEnabled != 0) + NoteVoicePar[nvoice].FreqLfo = new LFO( + partparams->VoicePar[nvoice].FreqLfo, + basefreq); /* Voice Filter Parameters Init */ - if (partparams->VoicePar[nvoice].PFilterEnabled!=0) { - NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter); - }; + if(partparams->VoicePar[nvoice].PFilterEnabled != 0) { + NoteVoicePar[nvoice].VoiceFilterL = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + NoteVoicePar[nvoice].VoiceFilterR = new Filter( + partparams->VoicePar[nvoice].VoiceFilter); + } - if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFilterEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FilterEnvelope = new Envelope( + partparams->VoicePar[nvoice].FilterEnvelope, + basefreq); - if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0) - NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq); + if(partparams->VoicePar[nvoice].PFilterLfoEnabled != 0) + NoteVoicePar[nvoice].FilterLfo = + new LFO(partparams->VoicePar[nvoice].FilterLfo, basefreq); - NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + NoteVoicePar[nvoice].FilterFreqTracking = + partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); /* Voice Modulation Parameters Init */ - if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)) { + if((NoteVoicePar[nvoice].FMEnabled != NONE) + && (NoteVoicePar[nvoice].FMVoice < 0)) { partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); - NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES]; + NoteVoicePar[nvoice].FMSmp = + new REALTYPE[OSCIL_SIZE + OSCIL_SMP_EXTRA_SAMPLES]; //Perform Anti-aliasing only on MORPH or RING MODULATION - int vc=nvoice; - if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + int vc = nvoice; + if(partparams->VoicePar[nvoice].PextFMoscil != -1) + vc = partparams->VoicePar[nvoice].PextFMoscil; - REALTYPE tmp=1.0; - if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| - (NoteVoicePar[nvoice].FMEnabled==MORPH)|| - (NoteVoicePar[nvoice].FMEnabled==RING_MOD)) { - tmp=getFMvoicebasefreq(nvoice); - }; - if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + REALTYPE tmp = 1.0; + if((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics != 0) + || (NoteVoicePar[nvoice].FMEnabled == MORPH) + || (NoteVoicePar[nvoice].FMEnabled == RING_MOD)) + tmp = getFMvoicebasefreq(nvoice); + ; + if(!partparams->GlobalPar.Hrandgrouping) + partparams->VoicePar[vc].FMSmp->newrandseed(rand()); - oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; - for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); - oscposhiFM[nvoice]%=OSCIL_SIZE; - }; + for(int k = 0; k < unison_size[nvoice]; k++) + oscposhiFM[nvoice][k] = + (oscposhi[nvoice][k] + + partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice] + . + FMSmp, + tmp)) % OSCIL_SIZE; + ; + for(int i = 0; i < OSCIL_SMP_EXTRA_SAMPLES; i++) + NoteVoicePar[nvoice].FMSmp[OSCIL_SIZE + + i] = NoteVoicePar[nvoice].FMSmp[i]; + int oscposhiFM_add = + (int)((partparams->VoicePar[nvoice].PFMoscilphase + - 64.0) / 128.0 * OSCIL_SIZE + OSCIL_SIZE * 4); + for(int k = 0; k < unison_size[nvoice]; k++) { + oscposhiFM[nvoice][k] += oscposhiFM_add; + oscposhiFM[nvoice][k] %= OSCIL_SIZE; + } + } - if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0) - NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq); + if(partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled != 0) + NoteVoicePar[nvoice].FMFreqEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMFreqEnvelope, + basefreq); - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; - if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) { - NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq); - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; + if(partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled != 0) { + NoteVoicePar[nvoice].FMAmpEnvelope = new Envelope( + partparams->VoicePar[nvoice].FMAmpEnvelope, + basefreq); + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } - for (nvoice=0;nvoicebandwidth.relbw * bandwidthDetuneMultiplier; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE pos = unison_vibratto[nvoice].position[k]; + REALTYPE step = unison_vibratto[nvoice].step[k]; + pos += step; + if(pos <= -1.0) { + pos = -1.0; + step = -step; + } + if(pos >= 1.0) { + pos = 1.0; + step = -step; + } + REALTYPE vibratto_val = (pos - 0.333333333 * pos * pos * pos) * 1.5; //make the vibratto lfo smoother + unison_freq_rap[nvoice][k] = 1.0 + + ((unison_base_freq_rap[nvoice][k] + - 1.0) + vibratto_val + * unison_vibratto[nvoice].amplitude) + * relbw; + + unison_vibratto[nvoice].position[k] = pos; + step = unison_vibratto[nvoice].step[k] = step; + } +} + /* * Computes the frequency of an oscillator */ -void ADnote::setfreq(int nvoice,REALTYPE freq) +void ADnote::setfreq(int nvoice, REALTYPE in_freq) { - REALTYPE speed; - freq=fabs(freq); - speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; - F2I(speed,oscfreqhi[nvoice]); - oscfreqlo[nvoice]=speed-floor(speed); -}; + F2I(speed, oscfreqhi[nvoice][k]); + oscfreqlo[nvoice][k] = speed - floor(speed); + } +} /* * Computes the frequency of an modullator oscillator */ -void ADnote::setfreqFM(int nvoice,REALTYPE freq) +void ADnote::setfreqFM(int nvoice, REALTYPE in_freq) { - REALTYPE speed; - freq=fabs(freq); - speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; - if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE freq = fabs(in_freq) * unison_freq_rap[nvoice][k]; + REALTYPE speed = freq * REALTYPE(OSCIL_SIZE) / (REALTYPE) SAMPLE_RATE; + if(speed > OSCIL_SIZE) + speed = OSCIL_SIZE; - F2I(speed,oscfreqhiFM[nvoice]); - oscfreqloFM[nvoice]=speed-floor(speed); -}; + F2I(speed, oscfreqhiFM[nvoice][k]); + oscfreqloFM[nvoice][k] = speed - floor(speed); + } +} /* * Get Voice base frequency */ -REALTYPE ADnote::getvoicebasefreq(int nvoice) +REALTYPE ADnote::getvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+ - NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+ - NoteGlobalPar.Detune/100.0; + REALTYPE detune = NoteVoicePar[nvoice].Detune / 100.0 + + NoteVoicePar[nvoice].FineDetune / 100.0 + * ctl->bandwidth.relbw * bandwidthDetuneMultiplier + + NoteGlobalPar.Detune / 100.0; - if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0)); - else {//the fixed freq is enabled - REALTYPE fixedfreq=440.0; - int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp); - else fixedfreq*=pow(3.0,tmp); - }; - return(fixedfreq*pow(2.0,detune/12.0)); - }; -}; + if(NoteVoicePar[nvoice].fixedfreq == 0) + return this->basefreq * pow(2, detune / 12.0); + else { //the fixed freq is enabled + REALTYPE fixedfreq = 440.0; + int fixedfreqET = NoteVoicePar[nvoice].fixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + fixedfreq *= pow(2.0, tmp); + else + fixedfreq *= pow(3.0, tmp); + } + return fixedfreq * pow(2.0, detune / 12.0); + } +} /* * Get Voice's Modullator base frequency */ -REALTYPE ADnote::getFMvoicebasefreq(int nvoice) +REALTYPE ADnote::getFMvoicebasefreq(int nvoice) const { - REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0; - return(getvoicebasefreq(nvoice)*pow(2,detune/12.0)); -}; + REALTYPE detune = NoteVoicePar[nvoice].FMDetune / 100.0; + return getvoicebasefreq(nvoice) * pow(2, detune / 12.0); +} /* * Computes all the parameters for each tick */ void ADnote::computecurrentparameters() { - int nvoice; - REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + int nvoice; + REALTYPE voicefreq, voicepitch, filterpitch, filterfreq, FMfreq, + FMrelativepitch, globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + if(stereo != 0) + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } //compute parameters for all voices - for (nvoice=0;nvoice0) continue; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled != ON) + continue; + NoteVoicePar[nvoice].DelayTicks -= 1; + if(NoteVoicePar[nvoice].DelayTicks > 0) + continue; + + compute_unison_freq_rap(nvoice); /*******************/ /* Voice Amplitude */ /*******************/ - oldamplitude[nvoice]=newamplitude[nvoice]; - newamplitude[nvoice]=1.0; + oldamplitude[nvoice] = newamplitude[nvoice]; + newamplitude[nvoice] = 1.0; - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); - if (NoteVoicePar[nvoice].AmpLfo!=NULL) - newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + if(NoteVoicePar[nvoice].AmpLfo != NULL) + newamplitude[nvoice] *= NoteVoicePar[nvoice].AmpLfo->amplfoout(); /****************/ /* Voice Filter */ /****************/ - if (NoteVoicePar[nvoice].VoiceFilter!=NULL) { - filterpitch=NoteVoicePar[nvoice].FilterCenterPitch; + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) { + filterpitch = NoteVoicePar[nvoice].FilterCenterPitch; - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + filterpitch += NoteVoicePar[nvoice].FilterEnvelope->envout(); - if (NoteVoicePar[nvoice].FilterLfo!=NULL) - filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout(); + if(NoteVoicePar[nvoice].FilterLfo != NULL) + filterpitch += NoteVoicePar[nvoice].FilterLfo->lfoout(); - filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking; - filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq); + filterfreq = filterpitch + NoteVoicePar[nvoice].FilterFreqTracking; + filterfreq = NoteVoicePar[nvoice].VoiceFilterL->getrealfreq( + filterfreq); - NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq); - }; - - if (NoteVoicePar[nvoice].noisetype==0) {//compute only if the voice isn't noise + NoteVoicePar[nvoice].VoiceFilterL->setfreq(filterfreq); + if(stereo && NoteVoicePar[nvoice].VoiceFilterR) + NoteVoicePar[nvoice].VoiceFilterR->setfreq(filterfreq); + } + if(NoteVoicePar[nvoice].noisetype == 0) { //compute only if the voice isn't noise /*******************/ /* Voice Frequency */ /*******************/ - voicepitch=0.0; - if (NoteVoicePar[nvoice].FreqLfo!=NULL) - voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0 - *ctl->bandwidth.relbw; + voicepitch = 0.0; + if(NoteVoicePar[nvoice].FreqLfo != NULL) + voicepitch += NoteVoicePar[nvoice].FreqLfo->lfoout() / 100.0 + * ctl->bandwidth.relbw; - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0; - voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency - voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller - setfreq(nvoice,voicefreq*portamentofreqrap); + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + voicepitch += NoteVoicePar[nvoice].FreqEnvelope->envout() + / 100.0; + voicefreq = getvoicebasefreq(nvoice) + * pow(2, (voicepitch + globalpitch) / 12.0); //Hz frequency + voicefreq *= ctl->pitchwheel.relfreq; //change the frequency by the controller + setfreq(nvoice, voicefreq * portamentofreqrap); /***************/ /* Modulator */ /***************/ - if (NoteVoicePar[nvoice].FMEnabled!=NONE) { - FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0; - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100; - FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap; - setfreqFM(nvoice,FMfreq); + if(NoteVoicePar[nvoice].FMEnabled != NONE) { + FMrelativepitch = NoteVoicePar[nvoice].FMDetune / 100.0; + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + FMrelativepitch += + NoteVoicePar[nvoice].FMFreqEnvelope->envout() / 100; + FMfreq = + pow(2.0, FMrelativepitch + / 12.0) * voicefreq * portamentofreqrap; + setfreqFM(nvoice, FMfreq); - FMoldamplitude[nvoice]=FMnewamplitude[nvoice]; - FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) - FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); - }; - }; - - }; - time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; -}; + FMoldamplitude[nvoice] = FMnewamplitude[nvoice]; + FMnewamplitude[nvoice] = NoteVoicePar[nvoice].FMVolume + * ctl->fmamp.relamp; + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + FMnewamplitude[nvoice] *= + NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + } + } + } + time += (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; +} /* * Fadein in a way that removes clicks but keep sound "punchy" */ -inline void ADnote::fadein(REALTYPE *smps) +inline void ADnote::fadein(REALTYPE *smps) const { - int zerocrossings=0; - for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} /* * Computes the Oscillator (Without Modulation) - LinearInterpolation */ inline void ADnote::ComputeVoiceOscillator_LinearInterpolation(int nvoice) { - int i,poshi; + int i, poshi; REALTYPE poslo; - poshi=oscposhi[nvoice]; - poslo=oscposlo[nvoice]; - REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; - for (i=0;i=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=oscfreqhi[nvoice]; - poshi&=OSCIL_SIZE-1; - }; - oscposhi[nvoice]=poshi; - oscposlo[nvoice]=poslo; -}; + for(int k = 0; k < unison_size[nvoice]; k++) { + poshi = oscposhi[nvoice][k]; + poslo = oscposlo[nvoice][k]; + int freqhi = oscfreqhi[nvoice][k]; + REALTYPE freqlo = oscfreqlo[nvoice][k]; + REALTYPE *smps = NoteVoicePar[nvoice].OscilSmp; + REALTYPE *tw = tmpwave_unison[k]; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = smps[poshi] * (1.0 - poslo) + smps[poshi + 1] * poslo; + poslo += freqlo; + if(poslo >= 1.0) { + poslo -= 1.0; + poshi++; + } + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} @@ -848,22 +1314,22 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; REALTYPE xm1,x0,x1,x2,a,b,c; for (i=0;i=1.0) { - poslo-=1.0; - poshi++; - }; - poshi+=oscfreqhi[nvoice]; + xm1=smps[poshi]; + x0=smps[poshi+1]; + x1=smps[poshi+2]; + x2=smps[poshi+3]; + a=(3.0 * (x0-x1) - xm1 + x2) / 2.0; + b = 2.0*x1 + xm1 - (5.0*x0 + x2) / 2.0; + c = (x1 - xm1) / 2.0; + tmpwave[i]=(((a * poslo) + b) * poslo + c) * poslo + x0; + printf("a\n"); + //tmpwave[i]=smps[poshi]*(1.0-poslo)+smps[poshi+1]*poslo; + poslo+=oscfreqlo[nvoice]; + if (poslo>=1.0) { + poslo-=1.0; + poshi++; + }; + poshi+=oscfreqhi[nvoice]; poshi&=OSCIL_SIZE-1; }; oscposhi[nvoice]=poshi; @@ -875,182 +1341,269 @@ inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ */ inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(NoteVoicePar[nvoice].FMVoice >= 0) { //if I use VoiceOut[] as modullator - int FMVoice=NoteVoicePar[nvoice].FMVoice; - for (i=0;i=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] = tw[i] * (1.0 - amp) + amp + * (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Ring Modulation) */ inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice) { - int i; + int i; REALTYPE amp; ComputeVoiceOscillator_LinearInterpolation(nvoice); - if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; - if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(FMnewamplitude[nvoice] > 1.0) + FMnewamplitude[nvoice] = 1.0; + if(FMoldamplitude[nvoice] > 1.0) + FMoldamplitude[nvoice] = 1.0; + if(NoteVoicePar[nvoice].FMVoice >= 0) { // if I use VoiceOut[] as modullator - for (i=0;i=1.0) { - posloFM-=1.0; - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; -}; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + amp = INTERPOLATE_AMPLITUDE(FMoldamplitude[nvoice], + FMnewamplitude[nvoice], + i, + SOUND_BUFFER_SIZE); + tw[i] *= (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + + 1] * posloFM) * amp + + (1.0 - amp); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM -= 1.0; + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } +} /* * Computes the Oscillator (Phase Modulation or Frequency Modulation) */ -inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode) +inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode) { - int carposhi; - int i,FMmodfreqhi; - REALTYPE FMmodfreqlo,carposlo; + int carposhi = 0; + int i, FMmodfreqhi = 0; + REALTYPE FMmodfreqlo = 0, carposlo = 0; - if (NoteVoicePar[nvoice].FMVoice>=0) { + if(NoteVoicePar[nvoice].FMVoice >= 0) { //if I use VoiceOut[] as modulator - for (i=0;i=1.0) { - posloFM=fmod(posloFM,1.0); - poshiFM++; - }; - poshiFM+=oscfreqhiFM[nvoice]; - poshiFM&=OSCIL_SIZE-1; - }; - oscposhiFM[nvoice]=poshiFM; - oscposloFM[nvoice]=posloFM; - }; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { + tw[i] = + (NoteVoicePar[nvoice].FMSmp[poshiFM] * (1.0 - posloFM) + + NoteVoicePar[nvoice].FMSmp[poshiFM + 1] * posloFM); + posloFM += freqloFM; + if(posloFM >= 1.0) { + posloFM = fmod(posloFM, 1.0); + poshiFM++; + } + poshiFM += freqhiFM; + poshiFM &= OSCIL_SIZE - 1; + } + oscposhiFM[nvoice][k] = poshiFM; + oscposloFM[nvoice][k] = posloFM; + } + } // Amplitude interpolation - if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])) { - for (i=0;i=1.0) { - carposhi++; - carposlo=fmod(carposlo,1.0); - }; - carposhi&=(OSCIL_SIZE-1); + //carrier + carposhi = poshi + FMmodfreqhi; + carposlo = poslo + FMmodfreqlo; - tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo) - +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo; + if(carposlo >= 1.0) { + carposhi++; + carposlo = fmod(carposlo, 1.0); + } + carposhi &= (OSCIL_SIZE - 1); - oscposlo[nvoice]+=oscfreqlo[nvoice]; - if (oscposlo[nvoice]>=1.0) { - oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0); - oscposhi[nvoice]++; - }; + tw[i] = NoteVoicePar[nvoice].OscilSmp[carposhi] + * (1.0 - carposlo) + + NoteVoicePar[nvoice].OscilSmp[carposhi + + 1] * carposlo; - oscposhi[nvoice]+=oscfreqhi[nvoice]; - oscposhi[nvoice]&=OSCIL_SIZE-1; - }; -}; + poslo += freqlo; + if(poslo >= 1.0) { + poslo = fmod(poslo, 1.0); + poshi++; + } + + poshi += freqhi; + poshi &= OSCIL_SIZE - 1; + } + oscposhi[nvoice][k] = poshi; + oscposlo[nvoice][k] = poslo; + } +} /*Calculeaza Oscilatorul cu PITCH MODULATION*/ inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice) { //TODO -}; +} /* * Computes the Noise */ inline void ADnote::ComputeVoiceNoise(int nvoice) { - for (int i=0;i0)) continue; - if (NoteVoicePar[nvoice].noisetype==0) {//voice mode=sound - switch (NoteVoicePar[nvoice].FMEnabled) { + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if((NoteVoicePar[nvoice].Enabled != ON) + || (NoteVoicePar[nvoice].DelayTicks > 0)) + continue; + if(NoteVoicePar[nvoice].noisetype == 0) //voice mode=sound + switch(NoteVoicePar[nvoice].FMEnabled) { case MORPH: ComputeVoiceOscillatorMorph(nvoice); break; @@ -1087,205 +1638,328 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) ComputeVoiceOscillatorRingModulation(nvoice); break; case PHASE_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,0); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 0); break; case FREQ_MOD: - ComputeVoiceOscillatorFrequencyModulation(nvoice,1); + ComputeVoiceOscillatorFrequencyModulation(nvoice, 1); break; - //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; + //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; default: ComputeVoiceOscillator_LinearInterpolation(nvoice); //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice); - - }; - } else ComputeVoiceNoise(nvoice); + } + else + ComputeVoiceNoise(nvoice); // Voice Processing + + //mix subvoices into voice + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] = 0.0; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] = 0.0; + for(int k = 0; k < unison_size[nvoice]; k++) { + REALTYPE *tw = tmpwave_unison[k]; + if(stereo) { + REALTYPE stereo_pos = 0; + if(unison_size[nvoice] > 1) + stereo_pos = k + / (REALTYPE)(unison_size[nvoice] + - 1) * 2.0 - 1.0; + REALTYPE stereo_spread = unison_stereo_spread[nvoice] * 2.0; //between 0 and 2.0 + if(stereo_spread > 1.0) { + REALTYPE stereo_pos_1 = (stereo_pos >= 0.0) ? 1.0 : -1.0; + stereo_pos = + (2.0 + - stereo_spread) * stereo_pos + + (stereo_spread - 1.0) * stereo_pos_1; + } + else + stereo_pos *= stereo_spread; + ; + if(unison_size[nvoice] == 1) + stereo_pos = 0.0; + REALTYPE panning = (stereo_pos + 1.0) * 0.5; + + + REALTYPE lvol = (1.0 - panning) * 2.0; + if(lvol > 1.0) + lvol = 1.0; + + REALTYPE rvol = panning * 2.0; + if(rvol > 1.0) + rvol = 1.0; + + if(unison_invert_phase[nvoice][k]) { + lvol = -lvol; + rvol = -rvol; + } + + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i] * lvol; + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] += tw[i] * rvol; + } + else + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] += tw[i]; + ; + } + + + REALTYPE unison_amplitude = 1.0 / sqrt(unison_size[nvoice]); //reduce the amplitude for large unison sizes // Amplitude - if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])) { - int rest=SOUND_BUFFER_SIZE; + REALTYPE oldam = oldamplitude[nvoice] * unison_amplitude; + REALTYPE newam = newamplitude[nvoice] * unison_amplitude; + + if(ABOVE_AMPLITUDE_THRESHOLD(oldam, newam)) { + int rest = SOUND_BUFFER_SIZE; //test if the amplitude if raising and the difference is high - if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)) { - rest=10; - if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE; - for (int i=0;i oldam) && ((newam - oldam) > 0.25)) { + rest = 10; + if(rest > SOUND_BUFFER_SIZE) + rest = SOUND_BUFFER_SIZE; + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwavel[i] *= oldam; + if(stereo) + for(int i = 0; i < SOUND_BUFFER_SIZE - rest; i++) + tmpwaver[i] *= oldam; + } // Amplitude interpolation - for (i=0;ifilterout(&tmpwave[0]); + if(NoteVoicePar[nvoice].VoiceFilterL != NULL) + NoteVoicePar[nvoice].VoiceFilterL->filterout(&tmpwavel[0]); + if((stereo) && (NoteVoicePar[nvoice].VoiceFilterR != NULL)) + NoteVoicePar[nvoice].VoiceFilterR->filterout(&tmpwaver[0]); //check if the amplitude envelope is finished, if yes, the voice will be fadeout - if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) { - if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwavel[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + if(stereo) + for(i = 0; i < SOUND_BUFFER_SIZE; i++) + tmpwaver[i] *= 1.0 - (REALTYPE)i + / (REALTYPE)SOUND_BUFFER_SIZE; + } //the voice is killed later - }; + } // Put the ADnote samples in VoiceOut (without appling Global volume, because I wish to use this voice as a modullator) - if (NoteVoicePar[nvoice].VoiceOut!=NULL) - for (i=0;ifinished()!=0) KillVoice(nvoice); - }; - }; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + if(NoteVoicePar[nvoice].AmpEnvelope->finished() != 0) + KillVoice(nvoice); + ; + } //Processing Global parameters NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); - if (stereo==0) { - for (i=0;ifilterout(&outr[0]); + else + NoteGlobalPar.GlobalFilterR->filterout(&outr[0]); - for (i=0;ifinished()!=0) { - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* @@ -1294,28 +1968,33 @@ int ADnote::noteout(REALTYPE *outl,REALTYPE *outr) void ADnote::relasekey() { int nvoice; - for (nvoice=0;nvoicerelasekey(); - if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); - if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); - }; + for(nvoice = 0; nvoice < NUM_VOICES; nvoice++) { + if(NoteVoicePar[nvoice].Enabled == 0) + continue; + if(NoteVoicePar[nvoice].AmpEnvelope != NULL) + NoteVoicePar[nvoice].AmpEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FreqEnvelope != NULL) + NoteVoicePar[nvoice].FreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FilterEnvelope != NULL) + NoteVoicePar[nvoice].FilterEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMFreqEnvelope != NULL) + NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); + if(NoteVoicePar[nvoice].FMAmpEnvelope != NULL) + NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); + } NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); - -}; +} /* * Check if the note is finished */ -int ADnote::finished() +int ADnote::finished() const { - if (NoteEnabled==ON) return(0); - else return(1); -}; - - + if(NoteEnabled == ON) + return 0; + else + return 1; +} diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.h b/plugins/zynaddsubfx/src/Synth/ADnote.h index 1ec25832e..9f494a906 100644 --- a/plugins/zynaddsubfx/src/Synth/ADnote.h +++ b/plugins/zynaddsubfx/src/Synth/ADnote.h @@ -40,240 +40,310 @@ /**The "additive" synthesizer*/ class ADnote //ADDitive note { -public: - ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent);//(gf)Added the besilent parameter to tell it to start silent (if true). - ~ADnote(); + public: + /**Constructor. + * @param pars Note Parameters + * @param ctl_ Pointer to system Controller + * @param freq Base frequency for note + * @param velocity Velocity of note + * @param portamento_ 1 if the note has portamento + * @param midinote_ The midi number of the note + * @param besilent Start silent note if true*/ + ADnote(ADnoteParameters *pars, Controller *ctl_, REALTYPE freq, + REALTYPE velocity, int portamento_, int midinote_, + bool besilent); + /**Destructor*/ + ~ADnote(); - void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall); + /**Alters the playing note for legato effect*/ + void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, + int midinote_, bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr); - void relasekey(); - int finished(); + /**Compute ADnote Samples. + * @return 0 if note is finished*/ + int noteout(REALTYPE *outl, REALTYPE *outr); + + /**Release the key for the note and start release portion of envelopes.*/ + void relasekey(); + /**Return if note is finished. + * @return finished=1 unfinished=0*/ + int finished() const; - /*ready - this is 0 if it is not ready (the parameters has to be computed) - or other value if the parameters has been computed and if it is ready to output*/ - char ready; + /**Nonzero when ready for output(the parameters has been computed) + * zero when parameters need to be computed.*/ + char ready; -private: + private: - void setfreq(int nvoice,REALTYPE freq); - void setfreqFM(int nvoice,REALTYPE freq); - void computecurrentparameters(); - void initparameters(); - void KillVoice(int nvoice); - void KillNote(); - inline REALTYPE getvoicebasefreq(int nvoice); - inline REALTYPE getFMvoicebasefreq(int nvoice); - inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); - inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); - inline void ComputeVoiceOscillatorMorph(int nvoice); - inline void ComputeVoiceOscillatorRingModulation(int nvoice); - inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode);//FMmode=0 for phase modulation, 1 for Frequency modulation - // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); - inline void ComputeVoiceOscillatorPitchModulation(int nvoice); + /**Changes the frequency of an oscillator. + * @param nvoice voice to run computations on + * @param in_freq new frequency*/ + void setfreq(int nvoice, REALTYPE in_freq); + /**Set the frequency of the modulator oscillator*/ + void setfreqFM(int nvoice, REALTYPE in_freq); + /**Computes relative frequency for unison and unison's vibratto. + * Note: Must be called before setfreq* functions.*/ + void compute_unison_freq_rap(int nvoice); + /**Compute parameters for next tick*/ + void computecurrentparameters(); + /**Initializes All Parameters*/ + void initparameters(); + /**Deallocate/Cleanup given voice*/ + void KillVoice(int nvoice); + /**Deallocate Note resources and voice resources*/ + void KillNote(); + /**Get the Voice's base frequency*/ + inline REALTYPE getvoicebasefreq(int nvoice) const; + /**Get modulator's base frequency*/ + inline REALTYPE getFMvoicebasefreq(int nvoice) const; + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo*/ + inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); + /**Compute the Oscillator's samples. + * Affects tmpwave_unison and updates oscposhi/oscposlo + * @todo remove this declaration if it is commented out*/ + inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); + /**Computes the Oscillator samples with morphing. + * updates tmpwave_unison*/ + inline void ComputeVoiceOscillatorMorph(int nvoice); + /**Computes the Ring Modulated Oscillator.*/ + inline void ComputeVoiceOscillatorRingModulation(int nvoice); + /**Computes the Frequency Modulated Oscillator. + * @param FMmode modulation type 0=Phase 1=Frequency*/ + inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice, + int FMmode); //FMmode=0 for phase modulation, 1 for Frequency modulation + // inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); + /**TODO*/ + inline void ComputeVoiceOscillatorPitchModulation(int nvoice); - inline void ComputeVoiceNoise(int nvoice); + /**Generate Noise Samples for Voice*/ + inline void ComputeVoiceNoise(int nvoice); - inline void fadein(REALTYPE *smps); + /**Fadein in a way that removes clicks but keep sound "punchy"*/ + inline void fadein(REALTYPE *smps) const; - //GLOBALS - ADnoteParameters *partparams; - unsigned char stereo;//if the note is stereo (allows note Panning) - int midinote; - REALTYPE velocity,basefreq; + //GLOBALS + ADnoteParameters *partparams; + unsigned char stereo; //if the note is stereo (allows note Panning) + int midinote; + REALTYPE velocity, basefreq; - ONOFFTYPE NoteEnabled; - Controller *ctl; + ONOFFTYPE NoteEnabled; + Controller *ctl; - /*****************************************************************/ - /* GLOBAL PARAMETERS */ - /*****************************************************************/ + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ - struct ADnoteGlobal { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents + struct ADnoteGlobal { + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents - Envelope *FreqEnvelope; - LFO *FreqLfo; + Envelope *FreqEnvelope; + LFO *FreqLfo; - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] - REALTYPE Panning;// [ 0 .. 1 ] + REALTYPE Panning; // [ 0 .. 1 ] - Envelope *AmpEnvelope; - LFO *AmpLfo; + Envelope *AmpEnvelope; + LFO *AmpLfo; + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; + + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; + + + + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoice { + /* If the voice is enabled */ + ONOFFTYPE Enabled; + + /* Voice Type (sound/noise)*/ + int noisetype; + + /* Filter Bypass */ + int filterbypass; + + /* Delay (ticks) */ + int DelayTicks; + + /* Waveform of the Voice */ + REALTYPE *OscilSmp; + + /************************************ + * FREQUENCY PARAMETERS * + ************************************/ + int fixedfreq; //if the frequency is fixed to 440 Hz + int fixedfreqET; //if the "fixed" frequency varies according to the note (ET) + + // cents = basefreq*VoiceDetune + REALTYPE Detune, FineDetune; + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ + + /* Panning 0.0=left, 0.5 - center, 1.0 = right */ + REALTYPE Panning; + REALTYPE Volume; // [-1.0 .. 1.0] + + Envelope *AmpEnvelope; + LFO *AmpLfo; + + /************************* + * FILTER PARAMETERS * + *************************/ + + Filter *VoiceFilterL; + Filter *VoiceFilterR; + + REALTYPE FilterCenterPitch; /* Filter center Pitch*/ + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + LFO *FilterLfo; + + + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ + + FMTYPE FMEnabled; + + int FMVoice; + + // Voice Output used by other voices if use this as modullator + REALTYPE *VoiceOut; + + /* Wave of the Voice */ + REALTYPE *FMSmp; + + REALTYPE FMVolume; + REALTYPE FMDetune; //in cents + + Envelope *FMFreqEnvelope; + Envelope *FMAmpEnvelope; + } NoteVoicePar[NUM_VOICES]; + + + /********************************************************/ + /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ + /********************************************************/ + + //time from the start of the note + REALTYPE time; + + //the size of unison for a single voice + int unison_size[NUM_VOICES]; + + //the stereo spread of the unison subvoices (0.0=mono,1.0=max) + REALTYPE unison_stereo_spread[NUM_VOICES]; + + //fractional part (skip) + REALTYPE *oscposlo[NUM_VOICES], *oscfreqlo[NUM_VOICES]; + + //integer part (skip) + int *oscposhi[NUM_VOICES], *oscfreqhi[NUM_VOICES]; + + //fractional part (skip) of the Modullator + REALTYPE *oscposloFM[NUM_VOICES], *oscfreqloFM[NUM_VOICES]; + + //the unison base_value + REALTYPE *unison_base_freq_rap[NUM_VOICES]; + + //how the unison subvoice's frequency is changed (1.0 for no change) + REALTYPE *unison_freq_rap[NUM_VOICES]; + + //which subvoice has phase inverted + bool *unison_invert_phase[NUM_VOICES]; + + //unison vibratto struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; - - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; - - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; - - Envelope *FilterEnvelope; - - LFO *FilterLfo; - } NoteGlobalPar; + REALTYPE amplitude; //amplitude which be added to unison_freq_rap + REALTYPE *step; //value which increments the position + REALTYPE *position; //between -1.0 and 1.0 + } unison_vibratto[NUM_VOICES]; + //integer part (skip) of the Modullator + unsigned int *oscposhiFM[NUM_VOICES], *oscfreqhiFM[NUM_VOICES]; - /***********************************************************/ - /* VOICE PARAMETERS */ - /***********************************************************/ - struct ADnoteVoice { - /* If the voice is enabled */ - ONOFFTYPE Enabled; + //used to compute and interpolate the amplitudes of voices and modullators + REALTYPE oldamplitude[NUM_VOICES], + newamplitude[NUM_VOICES], + FMoldamplitude[NUM_VOICES], + FMnewamplitude[NUM_VOICES]; - /* Voice Type (sound/noise)*/ - int noisetype; + //used by Frequency Modulation (for integration) + REALTYPE *FMoldsmp[NUM_VOICES]; - /* Filter Bypass */ - int filterbypass; + //temporary buffer + REALTYPE *tmpwavel; + REALTYPE *tmpwaver; + int max_unison; + REALTYPE **tmpwave_unison; - /* Delay (ticks) */ - int DelayTicks; + //Filter bypass samples + REALTYPE *bypassl, *bypassr; - /* Waveform of the Voice */ - REALTYPE *OscilSmp; + //interpolate the amplitudes + REALTYPE globaloldamplitude, globalnewamplitude; - /************************************ - * FREQUENCY PARAMETERS * - ************************************/ - int fixedfreq;//if the frequency is fixed to 440 Hz - int fixedfreqET;//if the "fixed" frequency varies according to the note (ET) + //1 - if it is the fitst tick (used to fade in the sound) + char firsttick[NUM_VOICES]; - // cents = basefreq*VoiceDetune - REALTYPE Detune,FineDetune; + //1 if the note has portamento + int portamento; - Envelope *FreqEnvelope; - LFO *FreqLfo; + //how the fine detunes are made bigger or smaller + REALTYPE bandwidthDetuneMultiplier; - - /*************************** - * AMPLITUDE PARAMETERS * - ***************************/ - - /* Panning 0.0=left, 0.5 - center, 1.0 = right */ - REALTYPE Panning; - REALTYPE Volume;// [-1.0 .. 1.0] - - Envelope *AmpEnvelope; - LFO *AmpLfo; - - /************************* - * FILTER PARAMETERS * - *************************/ - - Filter *VoiceFilter; - - REALTYPE FilterCenterPitch;/* Filter center Pitch*/ - REALTYPE FilterFreqTracking; - - Envelope *FilterEnvelope; - LFO *FilterLfo; - - - /**************************** - * MODULLATOR PARAMETERS * - ****************************/ - - FMTYPE FMEnabled; - - int FMVoice; - - // Voice Output used by other voices if use this as modullator - REALTYPE *VoiceOut; - - /* Wave of the Voice */ - REALTYPE *FMSmp; - - REALTYPE FMVolume; - REALTYPE FMDetune; //in cents - - Envelope *FMFreqEnvelope; - Envelope *FMAmpEnvelope; - } NoteVoicePar[NUM_VOICES]; - - - /********************************************************/ - /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ - /********************************************************/ - - //time from the start of the note - REALTYPE time; - - //fractional part (skip) - REALTYPE oscposlo[NUM_VOICES],oscfreqlo[NUM_VOICES]; - - //integer part (skip) - int oscposhi[NUM_VOICES],oscfreqhi[NUM_VOICES]; - - //fractional part (skip) of the Modullator - REALTYPE oscposloFM[NUM_VOICES],oscfreqloFM[NUM_VOICES]; - - //integer part (skip) of the Modullator - unsigned short int oscposhiFM[NUM_VOICES],oscfreqhiFM[NUM_VOICES]; - - //used to compute and interpolate the amplitudes of voices and modullators - REALTYPE oldamplitude[NUM_VOICES], - newamplitude[NUM_VOICES], - FMoldamplitude[NUM_VOICES], - FMnewamplitude[NUM_VOICES]; - - //used by Frequency Modulation (for integration) - REALTYPE FMoldsmp[NUM_VOICES]; - - //temporary buffer - REALTYPE *tmpwave; - - //Filter bypass samples - REALTYPE *bypassl,*bypassr; - - //interpolate the amplitudes - REALTYPE globaloldamplitude,globalnewamplitude; - - //1 - if it is the fitst tick (used to fade in the sound) - char firsttick[NUM_VOICES]; - - //1 if the note has portamento - int portamento; - - //how the fine detunes are made bigger or smaller - REALTYPE bandwidthDetuneMultiplier; - - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; #endif - - - diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.cpp b/plugins/zynaddsubfx/src/Synth/Envelope.cpp index 83450e31a..ce8456481 100644 --- a/plugins/zynaddsubfx/src/Synth/Envelope.cpp +++ b/plugins/zynaddsubfx/src/Synth/Envelope.cpp @@ -23,64 +23,71 @@ #include #include "Envelope.h" -Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq) +Envelope::Envelope(EnvelopeParams *envpars, REALTYPE basefreq) { int i; - envpoints=envpars->Penvpoints; - if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS; - envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain; - forcedrelase=envpars->Pforcedrelease; - envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0); - linearenvelope=envpars->Plinearenvelope; + envpoints = envpars->Penvpoints; + if(envpoints > MAX_ENVELOPE_POINTS) + envpoints = MAX_ENVELOPE_POINTS; + envsustain = (envpars->Penvsustain == 0) ? -1 : envpars->Penvsustain; + forcedrelase = envpars->Pforcedrelease; + envstretch = pow(440.0 / basefreq, envpars->Penvstretch / 64.0); + linearenvelope = envpars->Plinearenvelope; - if (envpars->Pfreemode==0) envpars->converttofree(); + if(envpars->Pfreemode == 0) + envpars->converttofree(); - REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + REALTYPE bufferdt = SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - int mode=envpars->Envmode; + int mode = envpars->Envmode; //for amplitude envelopes - if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope - if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear + if((mode == 1) && (linearenvelope == 0)) + mode = 2; //change to log envelope + if((mode == 2) && (linearenvelope != 0)) + mode = 1; //change to linear - for (i=0;igetdt(i)/1000.0*envstretch; - if (tmp>bufferdt) envdt[i]=bufferdt/tmp; - else envdt[i]=2.0;//any value larger than 1 + for(i = 0; i < MAX_ENVELOPE_POINTS; i++) { + REALTYPE tmp = envpars->getdt(i) / 1000.0 * envstretch; + if(tmp > bufferdt) + envdt[i] = bufferdt / tmp; + else + envdt[i] = 2.0; //any value larger than 1 - switch (mode) { + switch(mode) { case 2: - envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB; + envval[i] = (1.0 - envpars->Penvval[i] / 127.0) * MIN_ENVELOPE_DB; break; case 3: - envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0; - if (envpars->Penvval[i]<64) envval[i]=-envval[i]; + envval[i] = + (pow(2, 6.0 + * fabs(envpars->Penvval[i] - 64.0) / 64.0) - 1.0) * 100.0; + if(envpars->Penvval[i] < 64) + envval[i] = -envval[i]; break; case 4: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru) + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 6.0; //6 octaves (filtru) break; case 5: - envval[i]=(envpars->Penvval[i]-64.0)/64.0*10; + envval[i] = (envpars->Penvval[i] - 64.0) / 64.0 * 10; break; default: - envval[i]=envpars->Penvval[i]/127.0; - }; + envval[i] = envpars->Penvval[i] / 127.0; + } + } - }; + envdt[0] = 1.0; - envdt[0]=1.0; - - currentpoint=1;//the envelope starts from 1 - keyreleased=0; - t=0.0; - envfinish=0; - inct=envdt[1]; - envoutval=0.0; -}; + currentpoint = 1; //the envelope starts from 1 + keyreleased = 0; + t = 0.0; + envfinish = 0; + inct = envdt[1]; + envoutval = 0.0; +} Envelope::~Envelope() -{ -}; +{} /* @@ -88,10 +95,12 @@ Envelope::~Envelope() */ void Envelope::relasekey() { - if (keyreleased==1) return; - keyreleased=1; - if (forcedrelase!=0) t=0.0; -}; + if(keyreleased == 1) + return; + keyreleased = 1; + if(forcedrelase != 0) + t = 0.0; +} /* * Envelope Output @@ -100,46 +109,54 @@ REALTYPE Envelope::envout() { REALTYPE out; - if (envfinish!=0) {//if the envelope is finished - envoutval=envval[envpoints-1]; - return(envoutval); - }; - if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now - envoutval=envval[envsustain]; - return(envoutval); - }; + if(envfinish != 0) { //if the envelope is finished + envoutval = envval[envpoints - 1]; + return envoutval; + } + if((currentpoint == envsustain + 1) && (keyreleased == 0)) { //if it is sustaining now + envoutval = envval[envsustain]; + return envoutval; + } - if ((keyreleased!=0) && (forcedrelase!=0)) {//do the forced release + if((keyreleased != 0) && (forcedrelase != 0)) { //do the forced release + int tmp = (envsustain < 0) ? (envpoints - 1) : (envsustain + 1); //if there is no sustain point, use the last point for release - int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release + if(envdt[tmp] < 0.00000001) + out = envval[tmp]; + else + out = envoutval + (envval[tmp] - envoutval) * t; + t += envdt[tmp] * envstretch; - if (envdt[tmp]<0.00000001) out=envval[tmp]; - else out=envoutval+(envval[tmp]-envoutval)*t; - t+=envdt[tmp]*envstretch; + if(t >= 1.0) { + currentpoint = envsustain + 2; + forcedrelase = 0; + t = 0.0; + inct = envdt[currentpoint]; + if((currentpoint >= envpoints) || (envsustain < 0)) + envfinish = 1; + } + return out; + } + if(inct >= 1.0) + out = envval[currentpoint]; + else + out = + envval[currentpoint + - 1] + (envval[currentpoint] - envval[currentpoint - 1]) * t; - if (t>=1.0) { - currentpoint=envsustain+2; - forcedrelase=0; - t=0.0; - inct=envdt[currentpoint]; - if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1; - }; - return(out); - }; - if (inct>=1.0) out=envval[currentpoint]; - else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t; + t += inct; + if(t >= 1.0) { + if(currentpoint >= envpoints - 1) + envfinish = 1; + else + currentpoint++; + t = 0.0; + inct = envdt[currentpoint]; + } - t+=inct; - if (t>=1.0) { - if (currentpoint>=envpoints-1) envfinish=1; - else currentpoint++; - t=0.0; - inct=envdt[currentpoint]; - }; - - envoutval=out; - return (out); -}; + envoutval = out; + return out; +} /* * Envelope Output (dB) @@ -147,30 +164,35 @@ REALTYPE Envelope::envout() REALTYPE Envelope::envout_dB() { REALTYPE out; - if (linearenvelope!=0) return (envout()); + if(linearenvelope != 0) + return envout(); - if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated - REALTYPE v1=dB2rap(envval[0]); - REALTYPE v2=dB2rap(envval[1]); - out=v1+(v2-v1)*t; + if((currentpoint == 1) && ((keyreleased == 0) || (forcedrelase == 0))) { //first point is always lineary interpolated + REALTYPE v1 = dB2rap(envval[0]); + REALTYPE v2 = dB2rap(envval[1]); + out = v1 + (v2 - v1) * t; - t+=inct; - if (t>=1.0) { - t=0.0; - inct=envdt[2]; + t += inct; + if(t >= 1.0) { + t = 0.0; + inct = envdt[2]; currentpoint++; - out=v2; - }; + out = v2; + } - if (out>0.001) envoutval=rap2dB(out); - else envoutval=-40.0; - } else out=dB2rap(envout()); + if(out > 0.001) + envoutval = rap2dB(out); + else + envoutval = -40.0; + } + else + out = dB2rap(envout()); - return(out); -}; + return out; +} int Envelope::finished() { - return(envfinish); -}; + return envfinish; +} diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.h b/plugins/zynaddsubfx/src/Synth/Envelope.h index 60a17ed49..1a15813a7 100644 --- a/plugins/zynaddsubfx/src/Synth/Envelope.h +++ b/plugins/zynaddsubfx/src/Synth/Envelope.h @@ -30,35 +30,35 @@ /**Implementation of a general Envelope*/ class Envelope { -public: + public: - /**Constructor*/ - Envelope(EnvelopeParams *envpars,REALTYPE basefreq); - /**Destructor*/ - ~Envelope(); - void relasekey(); - REALTYPE envout(); - REALTYPE envout_dB(); - /**Determines the status of the Envelope - * - *\todo see if this can be changed to use a boolean - * @return returns 1 if the envelope is finished*/ - int finished(); -private: - int envpoints; - int envsustain;//"-1" means disabled - REALTYPE envdt[MAX_ENVELOPE_POINTS];//millisecons - REALTYPE envval[MAX_ENVELOPE_POINTS];// [0.0 .. 1.0] - REALTYPE envstretch; - int linearenvelope; + /**Constructor*/ + Envelope(EnvelopeParams *envpars, REALTYPE basefreq); + /**Destructor*/ + ~Envelope(); + void relasekey(); + REALTYPE envout(); + REALTYPE envout_dB(); + /**Determines the status of the Envelope + * + *\todo see if this can be changed to use a boolean + * @return returns 1 if the envelope is finished*/ + int finished(); + private: + int envpoints; + int envsustain; //"-1" means disabled + REALTYPE envdt[MAX_ENVELOPE_POINTS]; //millisecons + REALTYPE envval[MAX_ENVELOPE_POINTS]; // [0.0 .. 1.0] + REALTYPE envstretch; + int linearenvelope; - int currentpoint; //current envelope point (starts from 1) - int forcedrelase; - char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ - char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ - REALTYPE t; // the time from the last point - REALTYPE inct;// the time increment - REALTYPE envoutval;//used to do the forced release + int currentpoint; //current envelope point (starts from 1) + int forcedrelase; + char keyreleased; //if the key was released /** \todo figure out WHY IS THIS A CHAR*/ + char envfinish; /** \todo figure out WHY IS THIS A CHAR*/ + REALTYPE t; // the time from the last point + REALTYPE inct; // the time increment + REALTYPE envoutval; //used to do the forced release }; diff --git a/plugins/zynaddsubfx/src/Synth/LFO.cpp b/plugins/zynaddsubfx/src/Synth/LFO.cpp index 3c1d9962a..a7d00232b 100644 --- a/plugins/zynaddsubfx/src/Synth/LFO.cpp +++ b/plugins/zynaddsubfx/src/Synth/LFO.cpp @@ -27,59 +27,68 @@ #include "LFO.h" -LFO::LFO(LFOParams *lfopars,REALTYPE basefreq) +LFO::LFO(LFOParams *lfopars, REALTYPE basefreq) { - if (lfopars->Pstretch==0) lfopars->Pstretch=1; - REALTYPE lfostretch=pow(basefreq/440.0,(lfopars->Pstretch-64.0)/63.0);//max 2x/octave + if(lfopars->Pstretch == 0) + lfopars->Pstretch = 1; + REALTYPE lfostretch = pow(basefreq / 440.0, + (lfopars->Pstretch - 64.0) / 63.0); //max 2x/octave - REALTYPE lfofreq=(pow(2,lfopars->Pfreq*10.0)-1.0)/12.0*lfostretch; - incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + REALTYPE lfofreq = + (pow(2, lfopars->Pfreq * 10.0) - 1.0) / 12.0 * lfostretch; + incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; - if (lfopars->Pcontinous==0) { - if (lfopars->Pstartphase==0) x=RND; - else x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0,1.0); - } else { - REALTYPE tmp=fmod(lfopars->time*incx,1.0); - x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0+tmp,1.0); - }; + if(lfopars->Pcontinous == 0) { + if(lfopars->Pstartphase == 0) + x = RND; + else + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0, 1.0); + } + else { + REALTYPE tmp = fmod(lfopars->time * incx, 1.0); + x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0 + tmp, 1.0); + } //Limit the Frequency(or else...) - if (incx>0.49999999) incx=0.499999999; + if(incx > 0.49999999) + incx = 0.499999999; - lfornd=lfopars->Prandomness/127.0; - if (lfornd<0.0) lfornd=0.0; - else if (lfornd>1.0) lfornd=1.0; + lfornd = lfopars->Prandomness / 127.0; + if(lfornd < 0.0) + lfornd = 0.0; + else + if(lfornd > 1.0) + lfornd = 1.0; // lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; - lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0; + lfofreqrnd = pow(lfopars->Pfreqrand / 127.0, 2.0) * 4.0; - switch (lfopars->fel) { + switch(lfopars->fel) { case 1: - lfointensity=lfopars->Pintensity/127.0; + lfointensity = lfopars->Pintensity / 127.0; break; case 2: - lfointensity=lfopars->Pintensity/127.0*4.0; - break;//in octave + lfointensity = lfopars->Pintensity / 127.0 * 4.0; + break; //in octave default: - lfointensity=pow(2,lfopars->Pintensity/127.0*11.0)-1.0;//in centi - x-=0.25;//chance the starting phase + lfointensity = pow(2, lfopars->Pintensity / 127.0 * 11.0) - 1.0; //in centi + x -= 0.25; //chance the starting phase break; - }; + } - amp1=(1-lfornd)+lfornd*RND; - amp2=(1-lfornd)+lfornd*RND; - lfotype=lfopars->PLFOtype; - lfodelay=lfopars->Pdelay/127.0*4.0;//0..4 sec - incrnd=nextincrnd=1.0; - freqrndenabled=(lfopars->Pfreqrand!=0); + amp1 = (1 - lfornd) + lfornd * RND; + amp2 = (1 - lfornd) + lfornd * RND; + lfotype = lfopars->PLFOtype; + lfodelay = lfopars->Pdelay / 127.0 * 4.0; //0..4 sec + incrnd = nextincrnd = 1.0; + freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); - computenextincrnd();//twice because I want incrnd & nextincrnd to be random -}; + computenextincrnd(); //twice because I want incrnd & nextincrnd to be random +} LFO::~LFO() -{ -}; +{} /* * LFO out @@ -87,53 +96,67 @@ LFO::~LFO() REALTYPE LFO::lfoout() { REALTYPE out; - switch (lfotype) { + switch(lfotype) { case 1: //LFO_TRIANGLE - if ((x>=0.0)&&(x<0.25)) out=4.0*x; - else if ((x>0.25)&&(x<0.75)) out=2-4*x; - else out=4.0*x-4.0; + if((x >= 0.0) && (x < 0.25)) + out = 4.0 * x; + else + if((x > 0.25) && (x < 0.75)) + out = 2 - 4 * x; + else + out = 4.0 * x - 4.0; break; case 2: //LFO_SQUARE - if (x<0.5) out=-1; - else out=1; + if(x < 0.5) + out = -1; + else + out = 1; break; case 3: //LFO_RAMPUP - out=(x-0.5)*2.0; + out = (x - 0.5) * 2.0; break; case 4: //LFO_RAMPDOWN - out=(0.5-x)*2.0; + out = (0.5 - x) * 2.0; break; case 5: //LFO_EXP_DOWN 1 - out=pow(0.05,x)*2.0-1.0; + out = pow(0.05, x) * 2.0 - 1.0; break; case 6: //LFO_EXP_DOWN 2 - out=pow(0.001,x)*2.0-1.0; + out = pow(0.001, x) * 2.0 - 1.0; break; default: - out=cos(x*2.0*PI);//LFO_SINE - }; + out = cos(x * 2.0 * PI); //LFO_SINE + } - if ((lfotype==0)||(lfotype==1)) out*=lfointensity*(amp1+x*(amp2-amp1)); - else out*=lfointensity*amp2; - if (lfodelay<0.00001) { - if (freqrndenabled==0) x+=incx; + if((lfotype == 0) || (lfotype == 1)) + out *= lfointensity * (amp1 + x * (amp2 - amp1)); + else + out *= lfointensity * amp2; + if(lfodelay < 0.00001) { + if(freqrndenabled == 0) + x += incx; else { - float tmp=(incrnd*(1.0-x)+nextincrnd*x); - if (tmp>1.0) tmp=1.0; - else if (tmp<0.0) tmp=0.0; - x+=incx*tmp; - }; - if (x>=1) { - x=fmod(x,1.0); - amp1=amp2; - amp2=(1-lfornd)+lfornd*RND; + float tmp = (incrnd * (1.0 - x) + nextincrnd * x); + if(tmp > 1.0) + tmp = 1.0; + else + if(tmp < 0.0) + tmp = 0.0; + x += incx * tmp; + } + if(x >= 1) { + x = fmod(x, 1.0); + amp1 = amp2; + amp2 = (1 - lfornd) + lfornd * RND; computenextincrnd(); - }; - } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; - return(out); -}; + } + } + else + lfodelay -= (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; + return out; +} /* * LFO out (for amplitude) @@ -141,17 +164,21 @@ REALTYPE LFO::lfoout() REALTYPE LFO::amplfoout() { REALTYPE out; - out=1.0-lfointensity+lfoout(); - if (out<-1.0) out=-1.0; - else if (out>1.0) out=1.0; - return(out); -}; + out = 1.0 - lfointensity + lfoout(); + if(out < -1.0) + out = -1.0; + else + if(out > 1.0) + out = 1.0; + return out; +} void LFO::computenextincrnd() { - if (freqrndenabled==0) return; - incrnd=nextincrnd; - nextincrnd=pow(0.5,lfofreqrnd)+RND*(pow(2.0,lfofreqrnd)-1.0); -}; + if(freqrndenabled == 0) + return; + incrnd = nextincrnd; + nextincrnd = pow(0.5, lfofreqrnd) + RND * (pow(2.0, lfofreqrnd) - 1.0); +} diff --git a/plugins/zynaddsubfx/src/Synth/LFO.h b/plugins/zynaddsubfx/src/Synth/LFO.h index 12d01325d..9dd984bcf 100644 --- a/plugins/zynaddsubfx/src/Synth/LFO.h +++ b/plugins/zynaddsubfx/src/Synth/LFO.h @@ -29,31 +29,30 @@ /**Class for creating Low Frequency Ocillators*/ class LFO { -public: - /**Constructor - * - * @param lfopars pointer to a LFOParams object - * @param basefreq base frequency of LFO - */ - LFO(LFOParams *lfopars, REALTYPE basefreq); - /**Deconstructor*/ - ~LFO(); - REALTYPE lfoout(); - REALTYPE amplfoout(); -private: - REALTYPE x; - REALTYPE incx,incrnd,nextincrnd; - REALTYPE amp1,amp2;// used for randomness - REALTYPE lfointensity; - REALTYPE lfornd,lfofreqrnd; - REALTYPE lfodelay; - /**\todo see if an enum would be better here*/ - char lfotype; - int freqrndenabled; + public: + /**Constructor + * + * @param lfopars pointer to a LFOParams object + * @param basefreq base frequency of LFO + */ + LFO(LFOParams *lfopars, REALTYPE basefreq); + /**Deconstructor*/ + ~LFO(); + REALTYPE lfoout(); + REALTYPE amplfoout(); + private: + REALTYPE x; + REALTYPE incx, incrnd, nextincrnd; + REALTYPE amp1, amp2; // used for randomness + REALTYPE lfointensity; + REALTYPE lfornd, lfofreqrnd; + REALTYPE lfodelay; + /**\todo see if an enum would be better here*/ + char lfotype; + int freqrndenabled; - void computenextincrnd(); - + void computenextincrnd(); }; #endif diff --git a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp index 2e67d51dc..bbd62f3bb 100644 --- a/plugins/zynaddsubfx/src/Synth/OscilGen.cpp +++ b/plugins/zynaddsubfx/src/Synth/OscilGen.cpp @@ -27,21 +27,22 @@ #include "OscilGen.h" #include "../Effects/Distorsion.h" -OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets() +OscilGen::OscilGen(FFTwrapper *fft_, Resonance *res_):Presets() { setpresettype("Poscilgen"); - fft=fft_; - res=res_; - tmpsmps = new REALTYPE[OSCIL_SIZE]; - newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE/2); - newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2); - newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2); + fft = fft_; + res = res_; - randseed=1; - ADvsPAD=false; + tmpsmps = new REALTYPE[OSCIL_SIZE]; + newFFTFREQS(&outoscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&oscilFFTfreqs, OSCIL_SIZE / 2); + newFFTFREQS(&basefuncFFTfreqs, OSCIL_SIZE / 2); + + randseed = 1; + ADvsPAD = false; defaults(); -}; +} OscilGen::~OscilGen() { @@ -49,237 +50,271 @@ OscilGen::~OscilGen() deleteFFTFREQS(&outoscilFFTfreqs); deleteFFTFREQS(&basefuncFFTfreqs); deleteFFTFREQS(&oscilFFTfreqs); -}; +} void OscilGen::defaults() { + oldbasefunc = 0; + oldbasepar = 64; + oldhmagtype = 0; + oldwaveshapingfunction = 0; + oldwaveshaping = 64; + oldbasefuncmodulation = 0; + oldharmonicshift = 0; + oldbasefuncmodulationpar1 = 0; + oldbasefuncmodulationpar2 = 0; + oldbasefuncmodulationpar3 = 0; + oldmodulation = 0; + oldmodulationpar1 = 0; + oldmodulationpar2 = 0; + oldmodulationpar3 = 0; - oldbasefunc=0; - oldbasepar=64; - oldhmagtype=0; - oldwaveshapingfunction=0; - oldwaveshaping=64; - oldbasefuncmodulation=0; - oldharmonicshift=0; - oldbasefuncmodulationpar1=0; - oldbasefuncmodulationpar2=0; - oldbasefuncmodulationpar3=0; - oldmodulation=0; - oldmodulationpar1=0; - oldmodulationpar2=0; - oldmodulationpar3=0; + for(int i = 0; i < MAX_AD_HARMONICS; i++) { + hmag[i] = 0.0; + hphase[i] = 0.0; + Phmag[i] = 64; + Phphase[i] = 64; + } + Phmag[0] = 127; + Phmagtype = 0; + if(ADvsPAD) + Prand = 127; //max phase randomness (usefull if the oscil will be imported to a ADsynth from a PADsynth + else + Prand = 64; //no randomness - for (int i=0;ismps2freqs(oscil,freqs); - delete(fft); + get(oscil, -1.0); + FFTwrapper *fft = new FFTwrapper(OSCIL_SIZE); + fft->smps2freqs(oscil, freqs); + delete (fft); - REALTYPE max=0.0; + REALTYPE max = 0.0; - mag[0]=0; - phase[0]=0; - for (int i=0;i127) Phphase[i]=127; + Phphase[i] = 64 - (int) (64.0 * newphase / PI); + if(Phphase[i] > 127) + Phphase[i] = 127; - if (Phmag[i]==64) Phphase[i]=64; - }; + if(Phmag[i] == 64) + Phphase[i] = 64; + } deleteFFTFREQS(&freqs); prepare(); -}; +} /* * Base Functions - START */ -REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_pulse(REALTYPE x, REALTYPE a) { - return((fmod(x,1.0)0.99999) a=0.99999; - x=fmod(x,1); - if (x 0.99999) + a = 0.99999; + x = fmod(x, 1); + if(x < a) + return x / a * 2.0 - 1.0; + else + return (1.0 - x) / (1.0 - a) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_triangle(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_triangle(REALTYPE x, REALTYPE a) { - x=fmod(x+0.25,1); - a=1-a; - if (a<0.00001) a=0.00001; - if (x<0.5) x=x*4-1.0; - else x=(1.0-x)*4-1.0; - x/=-a; - if (x<-1.0) x=-1.0; - if (x>1.0) x=1.0; - return(x); -}; + x = fmod(x + 0.25, 1); + a = 1 - a; + if(a < 0.00001) + a = 0.00001; + if(x < 0.5) + x = x * 4 - 1.0; + else + x = (1.0 - x) * 4 - 1.0; + x /= -a; + if(x < -1.0) + x = -1.0; + if(x > 1.0) + x = 1.0; + return x; +} -REALTYPE OscilGen::basefunc_power(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_power(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(pow(x,exp((a-0.5)*10.0))*2.0-1.0); -}; + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return pow(x, exp((a - 0.5) * 10.0)) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_gauss(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_gauss(REALTYPE x, REALTYPE a) { - x=fmod(x,1)*2.0-1.0; - if (a<0.00001) a=0.00001; - return(exp(-x*x*(exp(a*8)+5.0))*2.0-1.0); -}; + x = fmod(x, 1) * 2.0 - 1.0; + if(a < 0.00001) + a = 0.00001; + return exp(-x * x * (exp(a * 8) + 5.0)) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_diode(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_diode(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - a=a*2.0-1.0; - x=cos((x+0.5)*2.0*PI)-a; - if (x<0.0) x=0.0; - return(x/(1.0-a)*2-1.0); -}; + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + a = a * 2.0 - 1.0; + x = cos((x + 0.5) * 2.0 * PI) - a; + if(x < 0.0) + x = 0.0; + return x / (1.0 - a) * 2 - 1.0; +} -REALTYPE OscilGen::basefunc_abssine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_abssine(REALTYPE x, REALTYPE a) { - x=fmod(x,1); - if (a<0.00001) a=0.00001; - else if (a>0.99999) a=0.99999; - return(sin(pow(x,exp((a-0.5)*5.0))*PI)*2.0-1.0); -}; + x = fmod(x, 1); + if(a < 0.00001) + a = 0.00001; + else + if(a > 0.99999) + a = 0.99999; + return sin(pow(x, exp((a - 0.5) * 5.0)) * PI) * 2.0 - 1.0; +} -REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x, REALTYPE a) { - if (a<0.00001) a=0.00001; - x=(fmod(x,1)-0.5)*exp((a-0.5)*log(128)); - if (x<-0.5) x=-0.5; - else if (x>0.5) x=0.5; - x=sin(x*PI*2.0); - return(x); -}; + if(a < 0.00001) + a = 0.00001; + x = (fmod(x, 1) - 0.5) * exp((a - 0.5) * log(128)); + if(x < -0.5) + x = -0.5; + else + if(x > 0.5) + x = 0.5; + x = sin(x * PI * 2.0); + return x; +} -REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*4; - if (a>0.0) a*=2; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-sin(b*PI)); -}; + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 4; + if(a > 0.0) + a *= 2; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -sin(b * PI); +} -REALTYPE OscilGen::basefunc_chirp(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_chirp(REALTYPE x, REALTYPE a) { - x=fmod(x,1.0)*2.0*PI; - a=(a-0.5)*4; - if (a<0.0) a*=2.0; - a=pow(3.0,a); - return(sin(x/2.0)*sin(a*x*x)); -}; + x = fmod(x, 1.0) * 2.0 * PI; + a = (a - 0.5) * 4; + if(a < 0.0) + a *= 2.0; + a = pow(3.0, a); + return sin(x / 2.0) * sin(a * x * x); +} -REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x, REALTYPE a) { - x=fmod(x+0.5,1)*2.0-1.0; - a=(a-0.5)*9; - a=pow(3.0,a); - REALTYPE b=pow(fabs(x),a); - if (x<0) b=-b; - return(-pow(sin(b*PI),2)); -}; + x = fmod(x + 0.5, 1) * 2.0 - 1.0; + a = (a - 0.5) * 9; + a = pow(3.0, a); + REALTYPE b = pow(fabs(x), a); + if(x < 0) + b = -b; + return -pow(sin(b * PI), 2); +} -REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x, REALTYPE a) { - a=a*a*a*30.0+1.0; - return(cos(acos(x*2.0-1.0)*a)); -}; + a = a * a * a * 30.0 + 1.0; + return cos(acos(x * 2.0 - 1.0) * a); +} -REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) +REALTYPE OscilGen::basefunc_sqr(REALTYPE x, REALTYPE a) { - a=a*a*a*a*160.0+0.001; - return(-atan(sin(x*2.0*PI)*a)); -}; + a = a * a * a * a * 160.0 + 0.001; + return -atan(sin(x * 2.0 * PI) * a); +} /* * Base Functions - END */ @@ -290,223 +325,266 @@ REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a) */ void OscilGen::getbasefunction(REALTYPE *smps) { - int i; - REALTYPE par=(Pbasefuncpar+0.5)/128.0; - if (Pbasefuncpar==64) par=0.5; + int i; + REALTYPE par = (Pbasefuncpar + 0.5) / 128.0; + if(Pbasefuncpar == 64) + par = 0.5; - REALTYPE basefuncmodulationpar1=Pbasefuncmodulationpar1/127.0, - basefuncmodulationpar2=Pbasefuncmodulationpar2/127.0, - basefuncmodulationpar3=Pbasefuncmodulationpar3/127.0; + REALTYPE basefuncmodulationpar1 = Pbasefuncmodulationpar1 / 127.0, + basefuncmodulationpar2 = Pbasefuncmodulationpar2 / 127.0, + basefuncmodulationpar3 = Pbasefuncmodulationpar3 / 127.0; - switch (Pbasefuncmodulation) { + switch(Pbasefuncmodulation) { case 1: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); - if (basefuncmodulationpar3<0.9999) basefuncmodulationpar3=-1.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = + floor((pow(2, basefuncmodulationpar3 * 5.0) - 1.0)); + if(basefuncmodulationpar3 < 0.9999) + basefuncmodulationpar3 = -1.0; break; case 2: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; - basefuncmodulationpar3=1.0+floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 5.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 1.0 + + floor((pow(2, basefuncmodulationpar3 + * 5.0) - 1.0)); break; case 3: - basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*7.0)-1.0)/10.0; - basefuncmodulationpar3=0.01+(pow(2,basefuncmodulationpar3*16.0)-1.0)/10.0; + basefuncmodulationpar1 = + (pow(2, basefuncmodulationpar1 * 7.0) - 1.0) / 10.0; + basefuncmodulationpar3 = 0.01 + + (pow(2, basefuncmodulationpar3 + * 16.0) - 1.0) / 10.0; break; - }; + } // printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3); - for (i=0;ipow(2,(1.0-par)*10)?0.0:1.0)*par2+(1.0-par2);//lp2 + tmp = pow(par2, 0.33); + gain = + (i + 1 > + pow(2, (1.0 - par) * 10) ? 0.0 : 1.0) * par2 + (1.0 - par2); //lp2 break; case 7: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(i+1>pow(2,(1.0-par)*7)?1.0:0.0)*par2+(1.0-par2);//hp2 - if (Pfilterpar1==0) gain=1.0; + gain = + (i + 1 > + pow(2, (1.0 - par) * 7) ? 1.0 : 0.0) * par2 + (1.0 - par2); //hp2 + if(Pfilterpar1 == 0) + gain = 1.0; break; case 8: - tmp=pow(par2,0.33); + tmp = pow(par2, 0.33); //tmp=1.0-(1.0-par2)*(1.0-par2); - gain=(fabs(pow(2,(1.0-par)*7)-i)>i/2+1?0.0:1.0)*par2+(1.0-par2);//bp2 + gain = + (fabs(pow(2, + (1.0 + - par) + * 7) - i) > i / 2 + 1 ? 0.0 : 1.0) * par2 + (1.0 - par2); //bp2 break; case 9: - tmp=pow(par2,0.33); - gain=(fabs(pow(2,(1.0-par)*7)-i)1.0) x=1.0; - tmp=pow(1.0-par2,2.0); - gain=cos(x*PI)*(1.0-tmp)+1.01+tmp;//low shelf + p2 = 1.0 - par + 0.2; + x = i / (64.0 * p2 * p2); + if(x < 0.0) + x = 0.0; + else + if(x > 1.0) + x = 1.0; + tmp = pow(1.0 - par2, 2.0); + gain = cos(x * PI) * (1.0 - tmp) + 1.01 + tmp; //low shelf break; case 13: - tmp=(int) (pow(2.0,(1.0-par)*7.2)); - gain=1.0; - if (i==(int) (tmp)) gain=pow(2.0,par2*par2*8.0); + tmp = (int) (pow(2.0, (1.0 - par) * 7.2)); + gain = 1.0; + if(i == (int) (tmp)) + gain = pow(2.0, par2 * par2 * 8.0); break; - }; + } - oscilFFTfreqs.s[i]*=gain; - oscilFFTfreqs.c[i]*=gain; - REALTYPE tmp=oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]+ - oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i]; - if (maxsmps2freqs(tmpsmps,basefuncFFTfreqs); - basefuncFFTfreqs.c[0]=0.0; - } else { - for (int i=0;ismps2freqs(tmpsmps, basefuncFFTfreqs); + basefuncFFTfreqs.c[0] = 0.0; + } + else { + for(int i = 0; i < OSCIL_SIZE / 2; i++) { + basefuncFFTfreqs.s[i] = 0.0; + basefuncFFTfreqs.c[i] = 0.0; + } //in this case basefuncFFTfreqs_ are not used } - oscilprepared=0; - oldbasefunc=Pcurrentbasefunc; - oldbasepar=Pbasefuncpar; - oldbasefuncmodulation=Pbasefuncmodulation; - oldbasefuncmodulationpar1=Pbasefuncmodulationpar1; - oldbasefuncmodulationpar2=Pbasefuncmodulationpar2; - oldbasefuncmodulationpar3=Pbasefuncmodulationpar3; -}; + oscilprepared = 0; + oldbasefunc = Pcurrentbasefunc; + oldbasepar = Pbasefuncpar; + oldbasefuncmodulation = Pbasefuncmodulation; + oldbasefuncmodulationpar1 = Pbasefuncmodulationpar1; + oldbasefuncmodulationpar2 = Pbasefuncmodulationpar2; + oldbasefuncmodulationpar3 = Pbasefuncmodulationpar3; +} /* * Waveshape @@ -515,32 +593,36 @@ void OscilGen::waveshape() { int i; - oldwaveshapingfunction=Pwaveshapingfunction; - oldwaveshaping=Pwaveshaping; - if (Pwaveshapingfunction==0) return; + oldwaveshapingfunction = Pwaveshapingfunction; + oldwaveshaping = Pwaveshaping; + if(Pwaveshapingfunction == 0) + return; - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[0] = 0.0; //remove the DC //reduce the amplitude of the freqs near the nyquist - for (i=1;ifreqs2smps(oscilFFTfreqs,tmpsmps); + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); //Normalize - REALTYPE max=0.0; - for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} /* @@ -550,79 +632,91 @@ void OscilGen::modulation() { int i; - oldmodulation=Pmodulation; - oldmodulationpar1=Pmodulationpar1; - oldmodulationpar2=Pmodulationpar2; - oldmodulationpar3=Pmodulationpar3; - if (Pmodulation==0) return; + oldmodulation = Pmodulation; + oldmodulationpar1 = Pmodulationpar1; + oldmodulationpar2 = Pmodulationpar2; + oldmodulationpar3 = Pmodulationpar3; + if(Pmodulation == 0) + return; - REALTYPE modulationpar1=Pmodulationpar1/127.0, - modulationpar2=0.5-Pmodulationpar2/127.0, - modulationpar3=Pmodulationpar3/127.0; + REALTYPE modulationpar1 = Pmodulationpar1 / 127.0, + modulationpar2 = 0.5 - Pmodulationpar2 / 127.0, + modulationpar3 = Pmodulationpar3 / 127.0; - switch (Pmodulation) { + switch(Pmodulation) { case 1: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=floor((pow(2,modulationpar3*5.0)-1.0)); - if (modulationpar3<0.9999) modulationpar3=-1.0; + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = floor((pow(2, modulationpar3 * 5.0) - 1.0)); + if(modulationpar3 < 0.9999) + modulationpar3 = -1.0; break; case 2: - modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; - modulationpar3=1.0+floor((pow(2,modulationpar3*5.0)-1.0)); + modulationpar1 = (pow(2, modulationpar1 * 7.0) - 1.0) / 100.0; + modulationpar3 = 1.0 + floor((pow(2, modulationpar3 * 5.0) - 1.0)); break; case 3: - modulationpar1=(pow(2,modulationpar1*9.0)-1.0)/100.0; - modulationpar3=0.01+(pow(2,modulationpar3*16.0)-1.0)/10.0; + modulationpar1 = (pow(2, modulationpar1 * 9.0) - 1.0) / 100.0; + modulationpar3 = 0.01 + (pow(2, modulationpar3 * 16.0) - 1.0) / 10.0; break; - }; + } - oscilFFTfreqs.c[0]=0.0;//remove the DC + oscilFFTfreqs.c[0] = 0.0; //remove the DC //reduce the amplitude of the freqs near the nyquist - for (i=1;ifreqs2smps(oscilFFTfreqs,tmpsmps); - int extra_points=2; - REALTYPE *in=new REALTYPE[OSCIL_SIZE+extra_points]; + for(i = 1; i < OSCIL_SIZE / 8; i++) { + REALTYPE tmp = i / (OSCIL_SIZE / 8.0); + oscilFFTfreqs.s[OSCIL_SIZE / 2 - i] *= tmp; + oscilFFTfreqs.c[OSCIL_SIZE / 2 - i] *= tmp; + } + fft->freqs2smps(oscilFFTfreqs, tmpsmps); + int extra_points = 2; + REALTYPE *in = new REALTYPE[OSCIL_SIZE + extra_points]; //Normalize - REALTYPE max=0.0; - for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT -}; + fft->smps2freqs(tmpsmps, oscilFFTfreqs); //perform FFT +} @@ -631,477 +725,534 @@ void OscilGen::modulation() */ void OscilGen::spectrumadjust() { - if (Psatype==0) return; - REALTYPE par=Psapar/127.0; - switch (Psatype) { + if(Psatype == 0) + return; + REALTYPE par = Psapar / 127.0; + switch(Psatype) { case 1: - par=1.0-par*2.0; - if (par>=0.0) par=pow(5.0,par); - else par=pow(8.0,par); + par = 1.0 - par * 2.0; + if(par >= 0.0) + par = pow(5.0, par); + else + par = pow(8.0, par); break; case 2: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; case 3: - par=pow(10.0,(1.0-par)*3.0)*0.25; + par = pow(10.0, (1.0 - par) * 3.0) * 0.25; break; - }; + } - REALTYPE max=0.0; - for (int i=0;i1.0) mag=1.0; + mag /= par; + if(mag > 1.0) + mag = 1.0; break; - }; - oscilFFTfreqs.c[i]=mag*cos(phase); - oscilFFTfreqs.s[i]=mag*sin(phase); - }; - -}; + } + oscilFFTfreqs.c[i] = mag * cos(phase); + oscilFFTfreqs.s[i] = mag * sin(phase); + } +} void OscilGen::shiftharmonics() { - if (Pharmonicshift==0) return; + if(Pharmonicshift == 0) + return; - REALTYPE hc,hs; - int harmonicshift=-Pharmonicshift; + REALTYPE hc, hs; + int harmonicshift = -Pharmonicshift; - if (harmonicshift>0) { - for (int i=OSCIL_SIZE/2-2;i>=0;i--) { - int oldh=i-harmonicshift; - if (oldh<0) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - }; - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - } else { - for (int i=0;i=(OSCIL_SIZE/2-1)) { - hc=0.0; - hs=0.0; - } else { - hc=oscilFFTfreqs.c[oldh+1]; - hs=oscilFFTfreqs.s[oldh+1]; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; + if(harmonicshift > 0) { + for(int i = OSCIL_SIZE / 2 - 2; i >= 0; i--) { + int oldh = i - harmonicshift; + if(oldh < 0) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + } + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } + else { + for(int i = 0; i < OSCIL_SIZE / 2 - 1; i++) { + int oldh = i + abs(harmonicshift); + if(oldh >= (OSCIL_SIZE / 2 - 1)) { + hc = 0.0; + hs = 0.0; + } + else { + hc = oscilFFTfreqs.c[oldh + 1]; + hs = oscilFFTfreqs.s[oldh + 1]; + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } - oscilFFTfreqs.c[i+1]=hc; - oscilFFTfreqs.s[i+1]=hs; - }; - }; + oscilFFTfreqs.c[i + 1] = hc; + oscilFFTfreqs.s[i + 1] = hs; + } + } - oscilFFTfreqs.c[0]=0.0; -}; + oscilFFTfreqs.c[0] = 0.0; +} /* * Prepare the Oscillator */ void OscilGen::prepare() { - int i,j,k; - REALTYPE a,b,c,d,hmagnew; + int i, j, k; + REALTYPE a, b, c, d, hmagnew; - if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)|| - (oldbasefuncmodulation!=Pbasefuncmodulation)|| - (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| - (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| - (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) + || (oldbasefuncmodulation != Pbasefuncmodulation) + || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) + || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) + || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) changebasefunction(); - for (i=0;i=OSCIL_SIZE/2) break; - a=basefuncFFTfreqs.c[i]; - b=basefuncFFTfreqs.s[i]; - c=hmag[j]*cos(hphase[j]*k); - d=hmag[j]*sin(hphase[j]*k); - oscilFFTfreqs.c[k]+=a*c-b*d; - oscilFFTfreqs.s[k]+=a*d+b*c; - }; - }; + for(i = 0; i < OSCIL_SIZE / 2; i++) { + oscilFFTfreqs.c[i] = 0.0; + oscilFFTfreqs.s[i] = 0.0; + } + if(Pcurrentbasefunc == 0) { //the sine case + for(i = 0; i < MAX_AD_HARMONICS; i++) { + oscilFFTfreqs.c[i + 1] = -hmag[i] * sin(hphase[i] * (i + 1)) / 2.0; + oscilFFTfreqs.s[i + 1] = hmag[i] * cos(hphase[i] * (i + 1)) / 2.0; + } + } + else { + for(j = 0; j < MAX_AD_HARMONICS; j++) { + if(Phmag[j] == 64) + continue; + for(i = 1; i < OSCIL_SIZE / 2; i++) { + k = i * (j + 1); + if(k >= OSCIL_SIZE / 2) + break; + a = basefuncFFTfreqs.c[i]; + b = basefuncFFTfreqs.s[i]; + c = hmag[j] * cos(hphase[j] * k); + d = hmag[j] * sin(hphase[j] * k); + oscilFFTfreqs.c[k] += a * c - b * d; + oscilFFTfreqs.s[k] += a * d + b * c; + } + } + } - }; - - if (Pharmonicshiftfirst!=0) shiftharmonics(); + if(Pharmonicshiftfirst != 0) + shiftharmonics(); - if (Pfilterbeforews==0) { + if(Pfilterbeforews == 0) { waveshape(); oscilfilter(); - } else { + } + else { oscilfilter(); waveshape(); - }; + } modulation(); spectrumadjust(); - if (Pharmonicshiftfirst==0) shiftharmonics(); + if(Pharmonicshiftfirst == 0) + shiftharmonics(); - oscilFFTfreqs.c[0]=0.0; + oscilFFTfreqs.c[0] = 0.0; - oldhmagtype=Phmagtype; - oldharmonicshift=Pharmonicshift+Pharmonicshiftfirst*256; + oldhmagtype = Phmagtype; + oldharmonicshift = Pharmonicshift + Pharmonicshiftfirst * 256; - oscilprepared=1; -}; + oscilprepared = 1; +} -void OscilGen::adaptiveharmonic(FFTFREQS f,REALTYPE freq) +void OscilGen::adaptiveharmonic(FFTFREQS f, REALTYPE freq) { - if ((Padaptiveharmonics==0)/*||(freq<1.0)*/) return; - if (freq<1.0) freq=440.0; + if((Padaptiveharmonics == 0) /*||(freq<1.0)*/) + return; + if(freq < 1.0) + freq = 440.0; FFTFREQS inf; - newFFTFREQS(&inf,OSCIL_SIZE/2); - for (int i=0;i1.0) { - rap=1.0/rap; - down=true; - }; + bool down = false; + if(rap > 1.0) { + rap = 1.0 / rap; + down = true; + } - for (int i=0;i=(OSCIL_SIZE/2-2)) { + if(high >= (OSCIL_SIZE / 2 - 2)) break; - } else { - if (down) { - f.c[high]+=inf.c[i]*(1.0-low); - f.s[high]+=inf.s[i]*(1.0-low); - f.c[high+1]+=inf.c[i]*low; - f.s[high+1]+=inf.s[i]*low; - } else { - hc=inf.c[high]*(1.0-low)+inf.c[high+1]*low; - hs=inf.s[high]*(1.0-low)+inf.s[high+1]*low; - }; - if (fabs(hc)<0.000001) hc=0.0; - if (fabs(hs)<0.000001) hs=0.0; - }; + else { + if(down) { + f.c[high] += inf.c[i] * (1.0 - low); + f.s[high] += inf.s[i] * (1.0 - low); + f.c[high + 1] += inf.c[i] * low; + f.s[high + 1] += inf.s[i] * low; + } + else { + hc = inf.c[high] * (1.0 - low) + inf.c[high + 1] * low; + hs = inf.s[high] * (1.0 - low) + inf.s[high + 1] * low; + } + if(fabs(hc) < 0.000001) + hc = 0.0; + if(fabs(hs) < 0.000001) + hs = 0.0; + } - if (!down) { - if (i==0) {//corect the aplitude of the first harmonic - hc*=rap; - hs*=rap; - }; - f.c[i]=hc; - f.s[i]=hs; - }; - }; + if(!down) { + if(i == 0) { //corect the aplitude of the first harmonic + hc *= rap; + hs *= rap; + } + f.c[i] = hc; + f.s[i] = hs; + } + } - f.c[1]+=f.c[0]; - f.s[1]+=f.s[0]; - f.c[0]=0.0; - f.s[0]=0.0; + f.c[1] += f.c[0]; + f.s[1] += f.s[0]; + f.c[0] = 0.0; + f.s[0] = 0.0; deleteFFTFREQS(&inf); -}; +} -void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f,int size) +void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f, int size) { - if (Padaptiveharmonics<=1) return; - REALTYPE *inf=new REALTYPE[size]; - REALTYPE par=Padaptiveharmonicspar*0.01; - par=1.0-pow((1.0-par),1.5); + if(Padaptiveharmonics <= 1) + return; + REALTYPE *inf = new REALTYPE[size]; + REALTYPE par = Padaptiveharmonicspar * 0.01; + par = 1.0 - pow((1.0 - par), 1.5); - for (int i=0;iget(smps,freqHz,0)); -}; + return this->get(smps, freqHz, 0); +} void OscilGen::newrandseed(unsigned int randseed) { - this->randseed=randseed; -}; + this->randseed = randseed; +} /* * Get the oscillator function */ -short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance) +short int OscilGen::get(REALTYPE *smps, REALTYPE freqHz, int resonance) { int i; - int nyquist,outpos; + int nyquist, outpos; - if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)||(oldhmagtype!=Phmagtype) - ||(oldwaveshaping!=Pwaveshaping)||(oldwaveshapingfunction!=Pwaveshapingfunction)) oscilprepared=0; - if (oldfilterpars!=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216) { - oscilprepared=0; - oldfilterpars=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216; - }; - if (oldsapars!=Psatype*256+Psapar) { - oscilprepared=0; - oldsapars=Psatype*256+Psapar; - }; + if((oldbasepar != Pbasefuncpar) || (oldbasefunc != Pcurrentbasefunc) + || (oldhmagtype != Phmagtype) + || (oldwaveshaping != Pwaveshaping) + || (oldwaveshapingfunction != Pwaveshapingfunction)) + oscilprepared = 0; + if(oldfilterpars != Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216) { + oscilprepared = 0; + oldfilterpars = Pfiltertype * 256 + Pfilterpar1 + Pfilterpar2 * 65536 + + Pfilterbeforews * 16777216; + } + if(oldsapars != Psatype * 256 + Psapar) { + oscilprepared = 0; + oldsapars = Psatype * 256 + Psapar; + } - if ((oldbasefuncmodulation!=Pbasefuncmodulation)|| - (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| - (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| - (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) - oscilprepared=0; + if((oldbasefuncmodulation != Pbasefuncmodulation) + || (oldbasefuncmodulationpar1 != Pbasefuncmodulationpar1) + || (oldbasefuncmodulationpar2 != Pbasefuncmodulationpar2) + || (oldbasefuncmodulationpar3 != Pbasefuncmodulationpar3)) + oscilprepared = 0; - if ((oldmodulation!=Pmodulation)|| - (oldmodulationpar1!=Pmodulationpar1)|| - (oldmodulationpar2!=Pmodulationpar2)|| - (oldmodulationpar3!=Pmodulationpar3)) - oscilprepared=0; + if((oldmodulation != Pmodulation) + || (oldmodulationpar1 != Pmodulationpar1) + || (oldmodulationpar2 != Pmodulationpar2) + || (oldmodulationpar3 != Pmodulationpar3)) + oscilprepared = 0; - if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; + if(oldharmonicshift != Pharmonicshift + Pharmonicshiftfirst * 256) + oscilprepared = 0; - if (oscilprepared!=1) prepare(); + if(oscilprepared != 1) + prepare(); - outpos=(int)((RND*2.0-1.0)*(REALTYPE) OSCIL_SIZE*(Prand-64.0)/64.0); - outpos=(outpos+2*OSCIL_SIZE) % OSCIL_SIZE; + outpos = + (int)((RND * 2.0 - 1.0) * (REALTYPE) OSCIL_SIZE * (Prand - 64.0) / 64.0); + outpos = (outpos + 2 * OSCIL_SIZE) % OSCIL_SIZE; - for (i=0;iOSCIL_SIZE/2) nyquist=OSCIL_SIZE/2; + nyquist = (int)(0.5 * SAMPLE_RATE / fabs(freqHz)) + 2; + if(ADvsPAD) + nyquist = (int)(OSCIL_SIZE / 2); + if(nyquist > OSCIL_SIZE / 2) + nyquist = OSCIL_SIZE / 2; - int realnyquist=nyquist; + int realnyquist = nyquist; - if (Padaptiveharmonics!=0) nyquist=OSCIL_SIZE/2; - for (i=1;i64)&&(freqHz>=0.0)&&(!ADvsPAD)) { - REALTYPE rnd,angle,a,b,c,d; - rnd=PI*pow((Prand-64.0)/64.0,2.0); - for (i=1;i 64) && (freqHz >= 0.0) && (!ADvsPAD)) { + REALTYPE rnd, angle, a, b, c, d; + rnd = PI * pow((Prand - 64.0) / 64.0, 2.0); + for(i = 1; i < nyquist - 1; i++) { //to Nyquist only for AntiAliasing + angle = rnd * i * RND; + a = outoscilFFTfreqs.c[i]; + b = outoscilFFTfreqs.s[i]; + c = cos(angle); + d = sin(angle); + outoscilFFTfreqs.c[i] = a * c - b * d; + outoscilFFTfreqs.s[i] = a * d + b * c; + } + } //Harmonic Amplitude Randomness - if ((freqHz>0.1)&&(!ADvsPAD)) { - unsigned int realrnd=rand(); + if((freqHz > 0.1) && (!ADvsPAD)) { + unsigned int realrnd = rand(); srand(randseed); - REALTYPE power=Pamprandpower/127.0; - REALTYPE normalize=1.0/(1.2-power); - switch (Pamprandtype) { + REALTYPE power = Pamprandpower / 127.0; + REALTYPE normalize = 1.0 / (1.2 - power); + switch(Pamprandtype) { case 1: - power=power*2.0-0.5; - power=pow(15.0,power); - for (i=1;i0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz); + if((freqHz > 0.1) && (resonance != 0)) + res->applyres(nyquist - 1, outoscilFFTfreqs, freqHz); //Full RMS normalize - REALTYPE sum=0; - for (int j=1;j0.1)) {//in this case the smps will contain the freqs - for (i=1;ifreqs2smps(outoscilFFTfreqs,smps); - for (i=0;i 0.1)) //in this case the smps will contain the freqs + for(i = 1; i < OSCIL_SIZE / 2; i++) + smps[i - 1] = sqrt(outoscilFFTfreqs.c[i] * outoscilFFTfreqs.c[i] + + outoscilFFTfreqs.s[i] * outoscilFFTfreqs.s[i]); + else { + fft->freqs2smps(outoscilFFTfreqs, smps); + for(i = 0; i < OSCIL_SIZE; i++) + smps[i] *= 0.25; //correct the amplitude + } - if (Prand<64) return(outpos); - else return(0); -}; + if(Prand < 64) + return outpos; + else + return 0; +} /* * Get the spectrum of the oscillator for the UI */ -void OscilGen::getspectrum(int n, REALTYPE *spc,int what) +void OscilGen::getspectrum(int n, REALTYPE *spc, int what) { - if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + if(n > OSCIL_SIZE / 2) + n = OSCIL_SIZE / 2; - for (int i=1;ifreqs2smps(basefuncFFTfreqs,smps); - } else getbasefunction(smps);//the sine case -}; + if(Pcurrentbasefunc != 0) + fft->freqs2smps(basefuncFFTfreqs, smps); + else + getbasefunction(smps); //the sine case +} void OscilGen::add2XML(XMLwrapper *xml) { - xml->addpar("harmonic_mag_type",Phmagtype); + xml->addpar("harmonic_mag_type", Phmagtype); - xml->addpar("base_function",Pcurrentbasefunc); - xml->addpar("base_function_par",Pbasefuncpar); - xml->addpar("base_function_modulation",Pbasefuncmodulation); - xml->addpar("base_function_modulation_par1",Pbasefuncmodulationpar1); - xml->addpar("base_function_modulation_par2",Pbasefuncmodulationpar2); - xml->addpar("base_function_modulation_par3",Pbasefuncmodulationpar3); + xml->addpar("base_function", Pcurrentbasefunc); + xml->addpar("base_function_par", Pbasefuncpar); + xml->addpar("base_function_modulation", Pbasefuncmodulation); + xml->addpar("base_function_modulation_par1", Pbasefuncmodulationpar1); + xml->addpar("base_function_modulation_par2", Pbasefuncmodulationpar2); + xml->addpar("base_function_modulation_par3", Pbasefuncmodulationpar3); - xml->addpar("modulation",Pmodulation); - xml->addpar("modulation_par1",Pmodulationpar1); - xml->addpar("modulation_par2",Pmodulationpar2); - xml->addpar("modulation_par3",Pmodulationpar3); + xml->addpar("modulation", Pmodulation); + xml->addpar("modulation_par1", Pmodulationpar1); + xml->addpar("modulation_par2", Pmodulationpar2); + xml->addpar("modulation_par3", Pmodulationpar3); - xml->addpar("wave_shaping",Pwaveshaping); - xml->addpar("wave_shaping_function",Pwaveshapingfunction); + xml->addpar("wave_shaping", Pwaveshaping); + xml->addpar("wave_shaping_function", Pwaveshapingfunction); - xml->addpar("filter_type",Pfiltertype); - xml->addpar("filter_par1",Pfilterpar1); - xml->addpar("filter_par2",Pfilterpar2); - xml->addpar("filter_before_wave_shaping",Pfilterbeforews); + xml->addpar("filter_type", Pfiltertype); + xml->addpar("filter_par1", Pfilterpar1); + xml->addpar("filter_par2", Pfilterpar2); + xml->addpar("filter_before_wave_shaping", Pfilterbeforews); - xml->addpar("spectrum_adjust_type",Psatype); - xml->addpar("spectrum_adjust_par",Psapar); + xml->addpar("spectrum_adjust_type", Psatype); + xml->addpar("spectrum_adjust_par", Psapar); - xml->addpar("rand",Prand); - xml->addpar("amp_rand_type",Pamprandtype); - xml->addpar("amp_rand_power",Pamprandpower); + xml->addpar("rand", Prand); + xml->addpar("amp_rand_type", Pamprandtype); + xml->addpar("amp_rand_power", Pamprandpower); - xml->addpar("harmonic_shift",Pharmonicshift); - xml->addparbool("harmonic_shift_first",Pharmonicshiftfirst); + xml->addpar("harmonic_shift", Pharmonicshift); + xml->addparbool("harmonic_shift_first", Pharmonicshiftfirst); - xml->addpar("adaptive_harmonics",Padaptiveharmonics); - xml->addpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq); - xml->addpar("adaptive_harmonics_power",Padaptiveharmonicspower); + xml->addpar("adaptive_harmonics", Padaptiveharmonics); + xml->addpar("adaptive_harmonics_base_frequency", Padaptiveharmonicsbasefreq); + xml->addpar("adaptive_harmonics_power", Padaptiveharmonicspower); xml->beginbranch("HARMONICS"); - for (int n=0;nbeginbranch("HARMONIC",n+1); - xml->addpar("mag",Phmag[n]); - xml->addpar("phase",Phphase[n]); + for(int n = 0; n < MAX_AD_HARMONICS; n++) { + if((Phmag[n] == 64) && (Phphase[n] == 64)) + continue; + xml->beginbranch("HARMONIC", n + 1); + xml->addpar("mag", Phmag[n]); + xml->addpar("phase", Phphase[n]); xml->endbranch(); - }; + } xml->endbranch(); - if (Pcurrentbasefunc==127) { - REALTYPE max=0.0; + if(Pcurrentbasefunc == 127) { + REALTYPE max = 0.0; - for (int i=0;ibeginbranch("BASE_FUNCTION"); - for (int i=1;i0.00001)&&(fabs(xs)>0.00001)) { - xml->beginbranch("BF_HARMONIC",i); - xml->addparreal("cos",xc); - xml->addparreal("sin",xs); + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + REALTYPE xc = basefuncFFTfreqs.c[i] / max; + REALTYPE xs = basefuncFFTfreqs.s[i] / max; + if((fabs(xs) > 0.00001) && (fabs(xs) > 0.00001)) { + xml->beginbranch("BF_HARMONIC", i); + xml->addparreal("cos", xc); + xml->addparreal("sin", xs); xml->endbranch(); - }; - }; + } + } xml->endbranch(); - }; -}; + } +} void OscilGen::getfromXML(XMLwrapper *xml) { + Phmagtype = xml->getpar127("harmonic_mag_type", Phmagtype); - Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); + Pcurrentbasefunc = xml->getpar127("base_function", Pcurrentbasefunc); + Pbasefuncpar = xml->getpar127("base_function_par", Pbasefuncpar); - Pcurrentbasefunc=xml->getpar127("base_function",Pcurrentbasefunc); - Pbasefuncpar=xml->getpar127("base_function_par",Pbasefuncpar); + Pbasefuncmodulation = xml->getpar127("base_function_modulation", + Pbasefuncmodulation); + Pbasefuncmodulationpar1 = xml->getpar127("base_function_modulation_par1", + Pbasefuncmodulationpar1); + Pbasefuncmodulationpar2 = xml->getpar127("base_function_modulation_par2", + Pbasefuncmodulationpar2); + Pbasefuncmodulationpar3 = xml->getpar127("base_function_modulation_par3", + Pbasefuncmodulationpar3); - Pbasefuncmodulation=xml->getpar127("base_function_modulation",Pbasefuncmodulation); - Pbasefuncmodulationpar1=xml->getpar127("base_function_modulation_par1",Pbasefuncmodulationpar1); - Pbasefuncmodulationpar2=xml->getpar127("base_function_modulation_par2",Pbasefuncmodulationpar2); - Pbasefuncmodulationpar3=xml->getpar127("base_function_modulation_par3",Pbasefuncmodulationpar3); + Pmodulation = xml->getpar127("modulation", Pmodulation); + Pmodulationpar1 = xml->getpar127("modulation_par1", + Pmodulationpar1); + Pmodulationpar2 = xml->getpar127("modulation_par2", + Pmodulationpar2); + Pmodulationpar3 = xml->getpar127("modulation_par3", + Pmodulationpar3); - Pmodulation=xml->getpar127("modulation",Pmodulation); - Pmodulationpar1=xml->getpar127("modulation_par1",Pmodulationpar1); - Pmodulationpar2=xml->getpar127("modulation_par2",Pmodulationpar2); - Pmodulationpar3=xml->getpar127("modulation_par3",Pmodulationpar3); + Pwaveshaping = xml->getpar127("wave_shaping", Pwaveshaping); + Pwaveshapingfunction = xml->getpar127("wave_shaping_function", + Pwaveshapingfunction); - Pwaveshaping=xml->getpar127("wave_shaping",Pwaveshaping); - Pwaveshapingfunction=xml->getpar127("wave_shaping_function",Pwaveshapingfunction); + Pfiltertype = xml->getpar127("filter_type", Pfiltertype); + Pfilterpar1 = xml->getpar127("filter_par1", Pfilterpar1); + Pfilterpar2 = xml->getpar127("filter_par2", Pfilterpar2); + Pfilterbeforews = xml->getpar127("filter_before_wave_shaping", + Pfilterbeforews); - Pfiltertype=xml->getpar127("filter_type",Pfiltertype); - Pfilterpar1=xml->getpar127("filter_par1",Pfilterpar1); - Pfilterpar2=xml->getpar127("filter_par2",Pfilterpar2); - Pfilterbeforews=xml->getpar127("filter_before_wave_shaping",Pfilterbeforews); + Psatype = xml->getpar127("spectrum_adjust_type", Psatype); + Psapar = xml->getpar127("spectrum_adjust_par", Psapar); - Psatype=xml->getpar127("spectrum_adjust_type",Psatype); - Psapar=xml->getpar127("spectrum_adjust_par",Psapar); + Prand = xml->getpar127("rand", Prand); + Pamprandtype = xml->getpar127("amp_rand_type", Pamprandtype); + Pamprandpower = xml->getpar127("amp_rand_power", Pamprandpower); - Prand=xml->getpar127("rand",Prand); - Pamprandtype=xml->getpar127("amp_rand_type",Pamprandtype); - Pamprandpower=xml->getpar127("amp_rand_power",Pamprandpower); + Pharmonicshift = xml->getpar("harmonic_shift", + Pharmonicshift, + -64, + 64); + Pharmonicshiftfirst = xml->getparbool("harmonic_shift_first", + Pharmonicshiftfirst); - Pharmonicshift=xml->getpar("harmonic_shift",Pharmonicshift,-64,64); - Pharmonicshiftfirst=xml->getparbool("harmonic_shift_first",Pharmonicshiftfirst); - - Padaptiveharmonics=xml->getpar("adaptive_harmonics",Padaptiveharmonics,0,127); - Padaptiveharmonicsbasefreq=xml->getpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq,0,255); - Padaptiveharmonicspower=xml->getpar("adaptive_harmonics_power",Padaptiveharmonicspower,0,200); + Padaptiveharmonics = xml->getpar("adaptive_harmonics", + Padaptiveharmonics, + 0, + 127); + Padaptiveharmonicsbasefreq = xml->getpar( + "adaptive_harmonics_base_frequency", + Padaptiveharmonicsbasefreq, + 0, + 255); + Padaptiveharmonicspower = xml->getpar("adaptive_harmonics_power", + Padaptiveharmonicspower, + 0, + 200); - if (xml->enterbranch("HARMONICS")) { - Phmag[0]=64; - Phphase[0]=64; - for (int n=0;nenterbranch("HARMONIC",n+1)==0) continue; - Phmag[n]=xml->getpar127("mag",64); - Phphase[n]=xml->getpar127("phase",64); + if(xml->enterbranch("HARMONICS")) { + Phmag[0] = 64; + Phphase[0] = 64; + for(int n = 0; n < MAX_AD_HARMONICS; n++) { + if(xml->enterbranch("HARMONIC", n + 1) == 0) + continue; + Phmag[n] = xml->getpar127("mag", 64); + Phphase[n] = xml->getpar127("phase", 64); xml->exitbranch(); - }; + } xml->exitbranch(); - }; + } - if (Pcurrentbasefunc!=0) changebasefunction(); + if(Pcurrentbasefunc != 0) + changebasefunction(); - if (xml->enterbranch("BASE_FUNCTION")) { - for (int i=1;ienterbranch("BF_HARMONIC",i)) { - basefuncFFTfreqs.c[i]=xml->getparreal("cos",0.0); - basefuncFFTfreqs.s[i]=xml->getparreal("sin",0.0); + if(xml->enterbranch("BASE_FUNCTION")) { + for(int i = 1; i < OSCIL_SIZE / 2; i++) { + if(xml->enterbranch("BF_HARMONIC", i)) { + basefuncFFTfreqs.c[i] = xml->getparreal("cos", 0.0); + basefuncFFTfreqs.s[i] = xml->getparreal("sin", 0.0); xml->exitbranch(); - }; - - - }; + } + } xml->exitbranch(); - REALTYPE max=0.0; + REALTYPE max = 0.0; - basefuncFFTfreqs.c[0]=0.0; - for (int i=0;ivelocity=velocity; - finished_=false; + pars = parameters; + portamento = portamento_; + ctl = ctl_; + this->velocity = velocity; + finished_ = false; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - }; - - firsttime=true; - released=false; - realfreq=basefreq; - NoteGlobalPar.Detune=getdetune(pars->PDetuneType - ,pars->PCoarseDetune,pars->PDetune); + firsttime = true; + released = false; + realfreq = basefreq; + NoteGlobalPar.Detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;isample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); // printf("(mindist=%g) %i %g %g\n",mindist,i,dist,pars->sample[i].basefreq); - if (distsample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - poshi_l=(int)(RND*(size-1)); - if (pars->PStereo!=0) poshi_r=(poshi_l+size/2)%size; - else poshi_r=poshi_l; - poslo=0.0; + poshi_l = (int)(RND * (size - 1)); + if(pars->PStereo != 0) + poshi_r = (poshi_l + size / 2) % size; + else + poshi_r = poshi_l; + poslo = 0.0; - tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpwave = new REALTYPE [SOUND_BUFFER_SIZE]; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - if (pars->PPunchStrength!=0) { - NoteGlobalPar.Punch.Enabled=1; - NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 - NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->PPunchStrength/127.0)-1.0) - *VelF(velocity,pars->PPunchVelocitySensing) ); - REALTYPE time=pow(10,3.0*pars->PPunchTime/127.0)/10000.0;//0.1 .. 100 ms - REALTYPE stretch=pow(440.0/freq,pars->PPunchStretch/64.0); - NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); - } else NoteGlobalPar.Punch.Enabled=0; + if(pars->PPunchStrength != 0) { + NoteGlobalPar.Punch.Enabled = 1; + NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue = + ((pow(10, 1.5 * pars->PPunchStrength / 127.0) - 1.0) + * VelF(velocity, + pars->PPunchVelocitySensing)); + REALTYPE time = pow(10, 3.0 * pars->PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms + REALTYPE stretch = pow(440.0 / freq, pars->PPunchStretch / 64.0); + NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch); + } + else + NoteGlobalPar.Punch.Enabled = 0; - NoteGlobalPar.FreqEnvelope=new Envelope(pars->FreqEnvelope,basefreq); - NoteGlobalPar.FreqLfo=new LFO(pars->FreqLfo,basefreq); + NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq); + NoteGlobalPar.FreqLfo = new LFO(pars->FreqLfo, basefreq); - NoteGlobalPar.AmpEnvelope=new Envelope(pars->AmpEnvelope,basefreq); - NoteGlobalPar.AmpLfo=new LFO(pars->AmpLfo,basefreq); + NoteGlobalPar.AmpEnvelope = new Envelope(pars->AmpEnvelope, basefreq); + NoteGlobalPar.AmpLfo = new LFO(pars->AmpLfo, basefreq); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.GlobalFilterL=new Filter(pars->GlobalFilter); - NoteGlobalPar.GlobalFilterR=new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterL = new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterR = new Filter(pars->GlobalFilter); - NoteGlobalPar.FilterEnvelope=new Envelope(pars->FilterEnvelope,basefreq); - NoteGlobalPar.FilterLfo=new LFO(pars->FilterLfo,basefreq); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterEnvelope = new Envelope(pars->FilterEnvelope, + basefreq); + NoteGlobalPar.FilterLfo = new LFO(pars->FilterLfo, basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - ready=1;///sa il pun pe asta doar cand e chiar gata + ready = 1; ///sa il pun pe asta doar cand e chiar gata - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; -}; + } +} // PADlegatonote: This function is (mostly) a copy of PADnote(...) // with some lines removed so that it only alter the already playing // note (to perform legato). It is possible I left stuff that is not // required for this. -void PADnote::PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void PADnote::PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { - PADnoteParameters *parameters=pars; + PADnoteParameters *parameters = pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; - this->velocity=velocity; - finished_=false; + portamento = portamento_; + this->velocity = velocity; + finished_ = false; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } - released=false; - realfreq=basefreq; + released = false; + realfreq = basefreq; - getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + getdetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune); //find out the closest note - REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); - REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); - nsample=0; - for (int i=1;isample[i].smp==NULL) break; - REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0)); + REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001)); + nsample = 0; + for(int i = 1; i < PAD_MAX_SAMPLES; i++) { + if(pars->sample[i].smp == NULL) + break; + REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001)); - if (distsample[nsample].size; - if (size==0) size=1; + int size = pars->sample[nsample].size; + if(size == 0) + size = 1; - if (pars->PPanning==0) NoteGlobalPar.Panning=RND; - else NoteGlobalPar.Panning=pars->PPanning/128.0; + if(pars->PPanning == 0) + NoteGlobalPar.Panning = RND; + else + NoteGlobalPar.Panning = pars->PPanning / 128.0; - NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - pars->PFilterVelocityScale/127.0*6.0* //velocity sensing - (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + pars->PFilterVelocityScale / 127.0 + * 6.0 //velocity sensing + * (VelF(velocity, + pars-> + PFilterVelocityScaleFunction) - 1); - NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB - *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB + * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing - NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output - globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output + globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope-> + envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); - NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + NoteGlobalPar.FilterQ = pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking( + basefreq); - if (parameters->sample[nsample].smp==NULL) { - finished_=true; + if(parameters->sample[nsample].smp == NULL) { + finished_ = true; return; - }; + } // End of the PADlegatonote function. -}; +} PADnote::~PADnote() @@ -246,282 +298,317 @@ PADnote::~PADnote() delete (NoteGlobalPar.FilterEnvelope); delete (NoteGlobalPar.FilterLfo); delete [] tmpwave; -}; +} inline void PADnote::fadein(REALTYPE *smps) { - int zerocrossings=0; - for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + int zerocrossings = 0; + for(int i = 1; i < SOUND_BUFFER_SIZE; i++) + if((smps[i - 1] < 0.0) && (smps[i] > 0.0)) + zerocrossings++; //this is only the possitive crossings - REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; - if (tmp<8.0) tmp=8.0; + REALTYPE tmp = (SOUND_BUFFER_SIZE - 1.0) / (zerocrossings + 1) / 3.0; + if(tmp < 8.0) + tmp = 8.0; int n; - F2I(tmp,n);//how many samples is the fade-in - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (int i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(int i = 0; i < n; i++) { //fade-in + REALTYPE tmp = 0.5 - cos((REALTYPE)i / (REALTYPE) n * PI) * 0.5; + smps[i] *= tmp; + } +} void PADnote::computecurrentparameters() { - REALTYPE globalpitch,globalfilterpitch; - globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ - NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod+NoteGlobalPar.Detune); - globaloldamplitude=globalnewamplitude; - globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + REALTYPE globalpitch, globalfilterpitch; + globalpitch = 0.01 * (NoteGlobalPar.FreqEnvelope->envout() + + NoteGlobalPar.FreqLfo->lfoout() + * ctl->modwheel.relmod + NoteGlobalPar.Detune); + globaloldamplitude = globalnewamplitude; + globalnewamplitude = NoteGlobalPar.Volume + * NoteGlobalPar.AmpEnvelope->envout_dB() + * NoteGlobalPar.AmpLfo->amplfoout(); - globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() - +NoteGlobalPar.FilterCenterPitch; + globalfilterpitch = NoteGlobalPar.FilterEnvelope->envout() + + NoteGlobalPar.FilterLfo->lfoout() + + NoteGlobalPar.FilterCenterPitch; - REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq - +NoteGlobalPar.FilterFreqTracking; + REALTYPE tmpfilterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + NoteGlobalPar.FilterFreqTracking; - tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + tmpfilterfreq = NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); - REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; - NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); - NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + REALTYPE globalfilterq = NoteGlobalPar.FilterQ * ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq, globalfilterq); + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq, globalfilterq); //compute the portamento, if it is used by this note - REALTYPE portamentofreqrap=1.0; - if (portamento!=0) {//this voice use portamento - portamentofreqrap=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + REALTYPE portamentofreqrap = 1.0; + if(portamento != 0) { //this voice use portamento + portamentofreqrap = ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - realfreq=basefreq*portamentofreqrap*pow(2.0,globalpitch/12.0)*ctl->pitchwheel.relfreq; -}; + realfreq = basefreq * portamentofreqrap + * pow(2.0, globalpitch / 12.0) * ctl->pitchwheel.relfreq; +} -int PADnote::Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) +int PADnote::Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - for (int i=0;i=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; - outl[i]=smps[poshi_l]*(1.0-poslo)+smps[poshi_l+1]*poslo; - outr[i]=smps[poshi_r]*(1.0-poslo)+smps[poshi_r+1]*poslo; - }; - return(1); -}; -int PADnote::Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo) + outl[i] = smps[poshi_l] * (1.0 - poslo) + smps[poshi_l + 1] * poslo; + outr[i] = smps[poshi_r] * (1.0 - poslo) + smps[poshi_r + 1] * poslo; + } + return 1; +} +int PADnote::Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo) { - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - finished_=true; - return(1); - }; - int size=pars->sample[nsample].size; - REALTYPE xm1,x0,x1,x2,a,b,c; - for (int i=0;i=1.0) { - poshi_l+=1; - poshi_r+=1; - poslo-=1.0; - }; - if (poshi_l>=size) poshi_l%=size; - if (poshi_r>=size) poshi_r%=size; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + finished_ = true; + return 1; + } + int size = pars->sample[nsample].size; + REALTYPE xm1, x0, x1, x2, a, b, c; + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + poshi_l += freqhi; + poshi_r += freqhi; + poslo += freqlo; + if(poslo >= 1.0) { + poshi_l += 1; + poshi_r += 1; + poslo -= 1.0; + } + if(poshi_l >= size) + poshi_l %= size; + if(poshi_r >= size) + poshi_r %= size; //left - xm1=smps[poshi_l]; - x0=smps[poshi_l + 1]; - x1=smps[poshi_l + 2]; - x2=smps[poshi_l + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_l]; + x0 = smps[poshi_l + 1]; + x1 = smps[poshi_l + 2]; + x2 = smps[poshi_l + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outl[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; //right - xm1=smps[poshi_r]; - x0=smps[poshi_r + 1]; - x1=smps[poshi_r + 2]; - x2=smps[poshi_r + 3]; - a = (3.0 * (x0-x1) - xm1 + x2)*0.5; - b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; - c = (x1 - xm1)*0.5; + xm1 = smps[poshi_r]; + x0 = smps[poshi_r + 1]; + x1 = smps[poshi_r + 2]; + x2 = smps[poshi_r + 3]; + a = (3.0 * (x0 - x1) - xm1 + x2) * 0.5; + b = 2.0 * x1 + xm1 - (5.0 * x0 + x2) * 0.5; + c = (x1 - xm1) * 0.5; outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; - }; - return(1); -}; + } + return 1; +} -int PADnote::noteout(REALTYPE *outl,REALTYPE *outr) +int PADnote::noteout(REALTYPE *outl, REALTYPE *outr) { computecurrentparameters(); - REALTYPE *smps=pars->sample[nsample].smp; - if (smps==NULL) { - for (int i=0;isample[nsample].basefreq; + REALTYPE *smps = pars->sample[nsample].smp; + if(smps == NULL) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { + outl[i] = 0.0; + outr[i] = 0.0; + } + return 1; + } + REALTYPE smpfreq = pars->sample[nsample].basefreq; - REALTYPE freqrap=realfreq/smpfreq; - int freqhi=(int) (floor(freqrap)); - REALTYPE freqlo=freqrap-floor(freqrap); + REALTYPE freqrap = realfreq / smpfreq; + int freqhi = (int) (floor(freqrap)); + REALTYPE freqlo = freqrap - floor(freqrap); - if (config.cfg.Interpolation) Compute_Cubic(outl,outr,freqhi,freqlo); - else Compute_Linear(outl,outr,freqhi,freqlo); + if(config.cfg.Interpolation) + Compute_Cubic(outl, outr, freqhi, freqlo); + else + Compute_Linear(outl, outr, freqhi, freqlo); - if (firsttime) { + if(firsttime) { fadein(outl); fadein(outr); - firsttime=false; - }; + firsttime = false; + } NoteGlobalPar.GlobalFilterL->filterout(outl); NoteGlobalPar.GlobalFilterR->filterout(outr); //Apply the punch - if (NoteGlobalPar.Punch.Enabled!=0) { - for (int i=0;ifinished()!=0) { - for (int i=0;ifinished() != 0) { + for(int i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } + finished_ = 1; + } - return(1); -}; + return 1; +} int PADnote::finished() { - return(finished_); -}; + return finished_; +} void PADnote::relasekey() { NoteGlobalPar.FreqEnvelope->relasekey(); NoteGlobalPar.FilterEnvelope->relasekey(); NoteGlobalPar.AmpEnvelope->relasekey(); -}; +} diff --git a/plugins/zynaddsubfx/src/Synth/PADnote.h b/plugins/zynaddsubfx/src/Synth/PADnote.h index 4722857f0..956353218 100644 --- a/plugins/zynaddsubfx/src/Synth/PADnote.h +++ b/plugins/zynaddsubfx/src/Synth/PADnote.h @@ -32,95 +32,112 @@ /**The "pad" synthesizer*/ class PADnote { -public: - PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent); - ~PADnote(); + public: + PADnote(PADnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~PADnote(); - void PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + void PADlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr); - int finished(); - void relasekey(); + int noteout(REALTYPE *outl, REALTYPE *outr); + int finished(); + void relasekey(); - int ready; + int ready; -private: - void fadein(REALTYPE *smps); - void computecurrentparameters(); - bool finished_; - PADnoteParameters *pars; + private: + void fadein(REALTYPE *smps); + void computecurrentparameters(); + bool finished_; + PADnoteParameters *pars; - int poshi_l,poshi_r; - REALTYPE poslo; + int poshi_l, poshi_r; + REALTYPE poslo; - REALTYPE basefreq; - bool firsttime,released; + REALTYPE basefreq; + bool firsttime, released; - int nsample,portamento; + int nsample, portamento; - int Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); - int Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); + int Compute_Linear(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); + int Compute_Cubic(REALTYPE *outl, + REALTYPE *outr, + int freqhi, + REALTYPE freqlo); - struct { - /****************************************** - * FREQUENCY GLOBAL PARAMETERS * - ******************************************/ - REALTYPE Detune;//cents - - Envelope *FreqEnvelope; - LFO *FreqLfo; - - /******************************************** - * AMPLITUDE GLOBAL PARAMETERS * - ********************************************/ - REALTYPE Volume;// [ 0 .. 1 ] - - REALTYPE Panning;// [ 0 .. 1 ] - - Envelope *AmpEnvelope; - LFO *AmpLfo; - struct { - int Enabled; - REALTYPE initialvalue,dt,t; - } Punch; + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune; //cents - /****************************************** - * FILTER GLOBAL PARAMETERS * - ******************************************/ - Filter *GlobalFilterL,*GlobalFilterR; + Envelope *FreqEnvelope; + LFO *FreqLfo; - REALTYPE FilterCenterPitch;//octaves - REALTYPE FilterQ; - REALTYPE FilterFreqTracking; + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume; // [ 0 .. 1 ] - Envelope *FilterEnvelope; + REALTYPE Panning; // [ 0 .. 1 ] - LFO *FilterLfo; - } NoteGlobalPar; + Envelope *AmpEnvelope; + LFO *AmpLfo; + + struct { + int Enabled; + REALTYPE initialvalue, dt, t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL, *GlobalFilterR; + + REALTYPE FilterCenterPitch; //octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; - REALTYPE globaloldamplitude,globalnewamplitude,velocity,realfreq; - REALTYPE *tmpwave; - Controller *ctl; + REALTYPE globaloldamplitude, globalnewamplitude, velocity, realfreq; + REALTYPE *tmpwave; + Controller *ctl; - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; #endif + diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.cpp b/plugins/zynaddsubfx/src/Synth/Resonance.cpp index fcf043d3a..4e12572a3 100644 --- a/plugins/zynaddsubfx/src/Synth/Resonance.cpp +++ b/plugins/zynaddsubfx/src/Synth/Resonance.cpp @@ -30,68 +30,79 @@ Resonance::Resonance():Presets() { setpresettype("Presonance"); defaults(); -}; +} Resonance::~Resonance() -{ -}; +{} void Resonance::defaults() { - Penabled=0; - PmaxdB=20; - Pcenterfreq=64;//1 kHz - Poctavesfreq=64; - Pprotectthefundamental=0; - ctlcenter=1.0; - ctlbw=1.0; - for (int i=0;i=N_RES_POINTS)) return; - Prespoints[n]=p; -}; + if((n < 0) || (n >= N_RES_POINTS)) + return; + Prespoints[n] = p; +} /* * Apply the resonance to FFT data */ -void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq) +void Resonance::applyres(int n, FFTFREQS fftdata, REALTYPE freq) { - if (Penabled==0) return;//if the resonance is disabled - REALTYPE sum=0.0, - l1=log(getfreqx(0.0)*ctlcenter), - l2=log(2.0)*getoctavesfreq()*ctlbw; + if(Penabled == 0) + return; //if the resonance is disabled + REALTYPE sum = 0.0, + l1 = log(getfreqx(0.0) * ctlcenter), + l2 = log(2.0) * getoctavesfreq() * ctlbw; - for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; - int kx2=kx1+1; - if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; - REALTYPE y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + x *= N_RES_POINTS; + REALTYPE dx = x - floor(x); + x = floor(x); + int kx1 = (int)x; + if(kx1 >= N_RES_POINTS) + kx1 = N_RES_POINTS - 1; + int kx2 = kx1 + 1; + if(kx2 >= N_RES_POINTS) + kx2 = N_RES_POINTS - 1; + REALTYPE y = + (Prespoints[kx1] + * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; - y=pow(10.0,y*PmaxdB/20.0); + y = pow(10.0, y * PmaxdB / 20.0); - if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0; + if((Pprotectthefundamental != 0) && (i == 1)) + y = 1.0; - fftdata.c[i]*=y; - fftdata.s[i]*=y; - }; -}; + fftdata.c[i] *= y; + fftdata.s[i] *= y; + } +} /* * Gets the response at the frequency "freq" @@ -99,25 +110,33 @@ void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq) REALTYPE Resonance::getfreqresponse(REALTYPE freq) { - REALTYPE l1=log(getfreqx(0.0)*ctlcenter), - l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0; + REALTYPE l1 = log(getfreqx(0.0) * ctlcenter), + l2 = log(2.0) * getoctavesfreq() * ctlbw, sum = 0.0; - for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; - int kx2=kx1+1; - if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; - REALTYPE result=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; - result=pow(10.0,result*PmaxdB/20.0); - return(result); -}; + REALTYPE x = (log(freq) - l1) / l2; //compute where the n-th hamonics fits to the graph + if(x < 0.0) + x = 0.0; + x *= N_RES_POINTS; + REALTYPE dx = x - floor(x); + x = floor(x); + int kx1 = (int)x; + if(kx1 >= N_RES_POINTS) + kx1 = N_RES_POINTS - 1; + int kx2 = kx1 + 1; + if(kx2 >= N_RES_POINTS) + kx2 = N_RES_POINTS - 1; + REALTYPE result = + (Prespoints[kx1] + * (1.0 - dx) + Prespoints[kx2] * dx) / 127.0 - sum / 127.0; + result = pow(10.0, result * PmaxdB / 20.0); + return result; +} /* @@ -125,129 +144,139 @@ REALTYPE Resonance::getfreqresponse(REALTYPE freq) */ void Resonance::smooth() { - REALTYPE old=Prespoints[0]; - for (int i=0;i0;i--) { - old=old*0.4+Prespoints[i]*0.6; - Prespoints[i]=(int) old+1; - if (Prespoints[i]>127) Prespoints[i]=127; - }; -}; + REALTYPE old = Prespoints[0]; + for(int i = 0; i < N_RES_POINTS; i++) { + old = old * 0.4 + Prespoints[i] * 0.6; + Prespoints[i] = (int) old; + } + old = Prespoints[N_RES_POINTS - 1]; + for(int i = N_RES_POINTS - 1; i > 0; i--) { + old = old * 0.4 + Prespoints[i] * 0.6; + Prespoints[i] = (int) old + 1; + if(Prespoints[i] > 127) + Prespoints[i] = 127; + } +} /* * Randomize the resonance function */ void Resonance::randomize(int type) { - int r=(int)(RND*127.0); - for (int i=0;i1.0) x=1.0; - REALTYPE octf=pow(2.0,getoctavesfreq()); - return(getcenterfreq()/sqrt(octf)*pow(octf,x)); -}; + if(x > 1.0) + x = 1.0; + REALTYPE octf = pow(2.0, getoctavesfreq()); + return getcenterfreq() / sqrt(octf) * pow(octf, x); +} /* * Get the x coordinate from frequency (used by the UI) */ REALTYPE Resonance::getfreqpos(REALTYPE freq) { - return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); -}; + return (log(freq) - log(getfreqx(0.0))) / log(2.0) / getoctavesfreq(); +} /* * Get the center frequency of the resonance graph */ REALTYPE Resonance::getcenterfreq() { - return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); -}; + return 10000.0 * pow(10, -(1.0 - Pcenterfreq / 127.0) * 2.0); +} /* * Get the number of octave that the resonance functions applies to */ REALTYPE Resonance::getoctavesfreq() { - return(0.25+10.0*Poctavesfreq/127.0); -}; + return 0.25 + 10.0 * Poctavesfreq / 127.0; +} -void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par) +void Resonance::sendcontroller(MidiControllers ctl, REALTYPE par) { - if (ctl==C_resonance_center) ctlcenter=par; - else ctlbw=par; -}; + if(ctl == C_resonance_center) + ctlcenter = par; + else + ctlbw = par; +} void Resonance::add2XML(XMLwrapper *xml) { - xml->addparbool("enabled",Penabled); + xml->addparbool("enabled", Penabled); - if ((Penabled==0)&&(xml->minimal)) return; + if((Penabled == 0) && (xml->minimal)) + return; - xml->addpar("max_db",PmaxdB); - xml->addpar("center_freq",Pcenterfreq); - xml->addpar("octaves_freq",Poctavesfreq); - xml->addparbool("protect_fundamental_frequency",Pprotectthefundamental); - xml->addpar("resonance_points",N_RES_POINTS); - for (int i=0;ibeginbranch("RESPOINT",i); - xml->addpar("val",Prespoints[i]); + xml->addpar("max_db", PmaxdB); + xml->addpar("center_freq", Pcenterfreq); + xml->addpar("octaves_freq", Poctavesfreq); + xml->addparbool("protect_fundamental_frequency", Pprotectthefundamental); + xml->addpar("resonance_points", N_RES_POINTS); + for(int i = 0; i < N_RES_POINTS; i++) { + xml->beginbranch("RESPOINT", i); + xml->addpar("val", Prespoints[i]); xml->endbranch(); - }; -}; + } +} void Resonance::getfromXML(XMLwrapper *xml) { - Penabled=xml->getparbool("enabled",Penabled); + Penabled = xml->getparbool("enabled", Penabled); - PmaxdB=xml->getpar127("max_db",PmaxdB); - Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); - Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); - Pprotectthefundamental=xml->getparbool("protect_fundamental_frequency",Pprotectthefundamental); - for (int i=0;ienterbranch("RESPOINT",i)==0) continue; - Prespoints[i]=xml->getpar127("val",Prespoints[i]); + PmaxdB = xml->getpar127("max_db", PmaxdB); + Pcenterfreq = xml->getpar127("center_freq", Pcenterfreq); + Poctavesfreq = xml->getpar127("octaves_freq", Poctavesfreq); + Pprotectthefundamental = xml->getparbool("protect_fundamental_frequency", + Pprotectthefundamental); + for(int i = 0; i < N_RES_POINTS; i++) { + if(xml->enterbranch("RESPOINT", i) == 0) + continue; + Prespoints[i] = xml->getpar127("val", Prespoints[i]); xml->exitbranch(); - }; -}; - + } +} diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.h b/plugins/zynaddsubfx/src/Synth/Resonance.h index 458ace0c4..6df43093d 100644 --- a/plugins/zynaddsubfx/src/Synth/Resonance.h +++ b/plugins/zynaddsubfx/src/Synth/Resonance.h @@ -31,39 +31,40 @@ class Resonance:public Presets { -public: - Resonance(); - ~Resonance(); - void setpoint(int n,unsigned char p); - void applyres(int n,FFTFREQS fftdata,REALTYPE freq); - void smooth(); - void interpolatepeaks(int type); - void randomize(int type); + public: + Resonance(); + ~Resonance(); + void setpoint(int n, unsigned char p); + void applyres(int n, FFTFREQS fftdata, REALTYPE freq); + void smooth(); + void interpolatepeaks(int type); + void randomize(int type); - void add2XML(XMLwrapper *xml); - void defaults(); - void getfromXML(XMLwrapper *xml); + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); - REALTYPE getfreqpos(REALTYPE freq); - REALTYPE getfreqx(REALTYPE x); - REALTYPE getfreqresponse(REALTYPE freq); - REALTYPE getcenterfreq(); - REALTYPE getoctavesfreq(); - void sendcontroller(MidiControllers ctl,REALTYPE par); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + REALTYPE getfreqresponse(REALTYPE freq); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + void sendcontroller(MidiControllers ctl, REALTYPE par); - //parameters - unsigned char Penabled; //if the ressonance is enabled - unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function - unsigned char PmaxdB; //how many dB the signal may be amplified - unsigned char Pcenterfreq,Poctavesfreq; //the center frequency of the res. func., and the number of octaves - unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low + //parameters + unsigned char Penabled; //if the ressonance is enabled + unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function + unsigned char PmaxdB; //how many dB the signal may be amplified + unsigned char Pcenterfreq, Poctavesfreq; //the center frequency of the res. func., and the number of octaves + unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low - //controllers - REALTYPE ctlcenter;//center frequency(relative) - REALTYPE ctlbw;//bandwidth(relative) + //controllers + REALTYPE ctlcenter; //center frequency(relative) + REALTYPE ctlbw; //bandwidth(relative) -private: + private: }; #endif + diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp index b3666229d..0a3affba5 100644 --- a/plugins/zynaddsubfx/src/Synth/SUBnote.cpp +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.cpp @@ -27,420 +27,491 @@ #include "SUBnote.h" #include "../Misc/Util.h" -SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent) +SUBnote::SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent) { - ready=0; + ready = 0; - tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE]; - tmprnd=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpsmp = new REALTYPE[SOUND_BUFFER_SIZE]; + tmprnd = new REALTYPE[SOUND_BUFFER_SIZE]; // Initialise some legato-specific vars - Legato.msg=LM_Norm; - Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. - if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) - Legato.fade.step=(1.0/Legato.fade.length); - Legato.decounter=-10; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - Legato.silent=besilent; + Legato.msg = LM_Norm; + Legato.fade.length = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok. + if(Legato.fade.length < 1) + Legato.fade.length = 1; // (if something's fishy) + Legato.fade.step = (1.0 / Legato.fade.length); + Legato.decounter = -10; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + Legato.silent = besilent; - pars=parameters; - ctl=ctl_; - portamento=portamento_; - NoteEnabled=ON; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; - numstages=pars->Pnumstages; - stereo=pars->Pstereo; - start=pars->Pstart; - firsttick=1; + pars = parameters; + ctl = ctl_; + portamento = portamento_; + NoteEnabled = ON; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; + numstages = pars->Pnumstages; + stereo = pars->Pstereo; + start = pars->Pstart; + firsttick = 1; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune // basefreq*=ctl->pitchwheel.relfreq;//pitch wheel //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); - GlobalFilterL=NULL; - GlobalFilterR=NULL; - GlobalFilterEnvelope=NULL; + GlobalFilterL = NULL; + GlobalFilterR = NULL; + GlobalFilterEnvelope = NULL; //select only harmonics that desire to compute - numharmonics=0; - for (int n=0;nPhmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[numharmonics++]=n; - }; - firstnumharmonics=numharmonics;//(gf)Useful in legato mode. + numharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[numharmonics++] = n; + } + firstnumharmonics = numharmonics; //(gf)Useful in legato mode. - if (numharmonics==0) { - NoteEnabled=OFF; + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } - lfilter=new bpfilter[numstages*numharmonics]; - if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics]; + lfilter = new bpfilter[numstages * numharmonics]; + if(stereo != 0) + rfilter = new bpfilter[numstages * numharmonics]; //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; + REALTYPE reduceamp = 0.0; - for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; - for (int nph=0;nphPfixedfreq==0) initparameters(basefreq); - else initparameters(basefreq/440.0*freq); + oldpitchwheel = 0; + oldbandwidth = 64; + if(pars->Pfixedfreq == 0) + initparameters(basefreq); + else + initparameters(basefreq / 440.0 * freq); - oldamplitude=newamplitude; - ready=1; -}; + oldamplitude = newamplitude; + ready = 1; +} // SUBlegatonote: This function is (mostly) a copy of SUBnote(...) and // initparameters(...) stuck together with some lines removed so that // it only alter the already playing note (to perform legato). It is // possible I left stuff that is not required for this. -void SUBnote::SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall) +void SUBnote::SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall) { //SUBnoteParameters *parameters=pars; //Controller *ctl_=ctl; // Manage legato stuff - if (externcall) Legato.msg=LM_Norm; - if (Legato.msg!=LM_CatchUp) { - Legato.lastfreq=Legato.param.freq; - Legato.param.freq=freq; - Legato.param.vel=velocity; - Legato.param.portamento=portamento_; - Legato.param.midinote=midinote; - if (Legato.msg==LM_Norm) { - if (Legato.silent) { - Legato.fade.m=0.0; - Legato.msg=LM_FadeIn; - } else { - Legato.fade.m=1.0; - Legato.msg=LM_FadeOut; + if(externcall) + Legato.msg = LM_Norm; + if(Legato.msg != LM_CatchUp) { + Legato.lastfreq = Legato.param.freq; + Legato.param.freq = freq; + Legato.param.vel = velocity; + Legato.param.portamento = portamento_; + Legato.param.midinote = midinote; + if(Legato.msg == LM_Norm) { + if(Legato.silent) { + Legato.fade.m = 0.0; + Legato.msg = LM_FadeIn; + } + else { + Legato.fade.m = 1.0; + Legato.msg = LM_FadeOut; return; } } - if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + if(Legato.msg == LM_ToNorm) + Legato.msg = LM_Norm; } - portamento=portamento_; + portamento = portamento_; - volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB - volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); - if (pars->PPanning!=0) panning=pars->PPanning/127.0; - else panning=RND; + volume = pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)); //-60 dB .. 0 dB + volume *= VelF(velocity, pars->PAmpVelocityScaleFunction); + if(pars->PPanning != 0) + panning = pars->PPanning / 127.0; + else + panning = RND; ///start=pars->Pstart; int pos[MAX_SUB_HARMONICS]; - if (pars->Pfixedfreq==0) basefreq=freq; + if(pars->Pfixedfreq == 0) + basefreq = freq; else { - basefreq=440.0; - int fixedfreqET=pars->PfixedfreqET; - if (fixedfreqET!=0) {//if the frequency varies according the keyboard note - REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); - if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); - else basefreq*=pow(3.0,tmp); - }; - }; - REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); - basefreq*=pow(2.0,detune/1200.0);//detune + basefreq = 440.0; + int fixedfreqET = pars->PfixedfreqET; + if(fixedfreqET != 0) { //if the frequency varies according the keyboard note + REALTYPE tmp = + (midinote + - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0); + if(fixedfreqET <= 64) + basefreq *= pow(2.0, tmp); + else + basefreq *= pow(3.0, tmp); + } + } + REALTYPE detune = getdetune(pars->PDetuneType, + pars->PCoarseDetune, + pars->PDetune); + basefreq *= pow(2.0, detune / 1200.0); //detune //global filter - GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq - (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing - (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + GlobalFilterCenterPitch = pars->GlobalFilter->getfreq() //center freq + + (pars->PGlobalFilterVelocityScale / 127.0 * 6.0) //velocity sensing + * (VelF(velocity, + pars->PGlobalFilterVelocityScaleFunction) + - 1); - int legatonumharmonics=0; - for (int n=0;nPhmag[n]==0)continue; - if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq - pos[legatonumharmonics++]=n; - }; - if (legatonumharmonics>firstnumharmonics) numharmonics=firstnumharmonics; - else numharmonics=legatonumharmonics; + int legatonumharmonics = 0; + for(int n = 0; n < MAX_SUB_HARMONICS; n++) { + if(pars->Phmag[n] == 0) + continue; + if(n * basefreq > SAMPLE_RATE / 2.0) + break; //remove the freqs above the Nyquist freq + pos[legatonumharmonics++] = n; + } + if(legatonumharmonics > firstnumharmonics) + numharmonics = firstnumharmonics; + else + numharmonics = legatonumharmonics; - if (numharmonics==0) { - NoteEnabled=OFF; + if(numharmonics == 0) { + NoteEnabled = OFF; return; - }; + } //how much the amplitude is normalised (because the harmonics) - REALTYPE reduceamp=0.0; + REALTYPE reduceamp = 0.0; - for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + REALTYPE bw = + pow(10, (pars->Pbandwidth - 127.0) / 127.0 * 4) * numstages; //Bandwidth Scale - bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + bw *= pow(1000 / freq, (pars->Pbwscale - 64.0) / 64.0 * 3.0); //Relative BandWidth - bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + bw *= pow(100, (pars->Phrelbw[pos[n]] - 64.0) / 64.0); - if (bw>25.0) bw=25.0; + if(bw > 25.0) + bw = 25.0; //try to keep same amplitude on all freqs and bw. (empirically) - REALTYPE gain=sqrt(1500.0/(bw*freq)); + REALTYPE gain = sqrt(1500.0 / (bw * freq)); - REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hmagnew = 1.0 - pars->Phmag[pos[n]] / 127.0; REALTYPE hgain; - switch (pars->Phmagtype) { + switch(pars->Phmagtype) { case 1: - hgain=exp(hmagnew*log(0.01)); + hgain = exp(hmagnew * log(0.01)); break; case 2: - hgain=exp(hmagnew*log(0.001)); + hgain = exp(hmagnew * log(0.001)); break; case 3: - hgain=exp(hmagnew*log(0.0001)); + hgain = exp(hmagnew * log(0.0001)); break; case 4: - hgain=exp(hmagnew*log(0.00001)); + hgain = exp(hmagnew * log(0.00001)); break; default: - hgain=1.0-hmagnew; - }; - gain*=hgain; - reduceamp+=hgain; + hgain = 1.0 - hmagnew; + } + gain *= hgain; + reduceamp += hgain; - for (int nph=0;nphPfixedfreq==0) freq=basefreq; - else freq*=basefreq/440.0; + if(pars->Pfixedfreq == 0) + freq = basefreq; + else + freq *= basefreq / 440.0; /////////////// // Altered initparameters(...) content: - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } // end of the altered initparameters function content. /////////////// - oldamplitude=newamplitude; + oldamplitude = newamplitude; // End of the SUBlegatonote function. -}; +} SUBnote::~SUBnote() { - if (NoteEnabled!=OFF) KillNote(); + if(NoteEnabled != OFF) + KillNote(); delete [] tmpsmp; delete [] tmprnd; -}; +} /* * Kill the note */ void SUBnote::KillNote() { - if (NoteEnabled!=OFF) { + if(NoteEnabled != OFF) { delete [] lfilter; - lfilter=NULL; - if (stereo!=0) delete [] rfilter; - rfilter=NULL; - delete(AmpEnvelope); - if (FreqEnvelope!=NULL) delete(FreqEnvelope); - if (BandWidthEnvelope!=NULL) delete(BandWidthEnvelope); - NoteEnabled=OFF; - }; - -}; + lfilter = NULL; + if(stereo != 0) + delete [] rfilter; + rfilter = NULL; + delete (AmpEnvelope); + if(FreqEnvelope != NULL) + delete (FreqEnvelope); + if(BandWidthEnvelope != NULL) + delete (BandWidthEnvelope); + NoteEnabled = OFF; + } +} /* * Compute the filters coefficients */ -void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain) +void SUBnote::computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain) { - if (freq>SAMPLE_RATE/2.0-200.0) { - freq=SAMPLE_RATE/2.0-200.0; - }; + if(freq > SAMPLE_RATE / 2.0 - 200.0) + freq = SAMPLE_RATE / 2.0 - 200.0; + ; - REALTYPE omega=2.0*PI*freq/SAMPLE_RATE; - REALTYPE sn=sin(omega); - REALTYPE cs=cos(omega); - REALTYPE alpha=sn*sinh(LOG_2/2.0*bw*omega/sn); + REALTYPE omega = 2.0 * PI * freq / SAMPLE_RATE; + REALTYPE sn = sin(omega); + REALTYPE cs = cos(omega); + REALTYPE alpha = sn * sinh(LOG_2 / 2.0 * bw * omega / sn); - if (alpha>1) alpha=1; - if (alpha>bw) alpha=bw; + if(alpha > 1) + alpha = 1; + if(alpha > bw) + alpha = bw; - filter.b0=alpha/(1.0+alpha)*filter.amp*gain; - filter.b2=-alpha/(1.0+alpha)*filter.amp*gain; - filter.a1=-2.0*cs/(1.0+alpha); - filter.a2=(1.0-alpha)/(1.0+alpha); - -}; + filter.b0 = alpha / (1.0 + alpha) * filter.amp * gain; + filter.b2 = -alpha / (1.0 + alpha) * filter.amp * gain; + filter.a1 = -2.0 * cs / (1.0 + alpha); + filter.a2 = (1.0 - alpha) / (1.0 + alpha); +} /* * Initialise the filters */ -void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag) +void SUBnote::initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag) { - filter.xn1=0.0; - filter.xn2=0.0; + filter.xn1 = 0.0; + filter.xn2 = 0.0; - if (start==0) { - filter.yn1=0.0; - filter.yn2=0.0; - } else { - REALTYPE a=0.1*mag;//empirically - REALTYPE p=RND*2.0*PI; - if (start==1) a*=RND; - filter.yn1=a*cos(p); - filter.yn2=a*cos(p+freq*2.0*PI/SAMPLE_RATE); + if(start == 0) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + else { + REALTYPE a = 0.1 * mag; //empirically + REALTYPE p = RND * 2.0 * PI; + if(start == 1) + a *= RND; + filter.yn1 = a * cos(p); + filter.yn2 = a * cos(p + freq * 2.0 * PI / SAMPLE_RATE); //correct the error of computation the start amplitude //at very high frequencies - if (freq>SAMPLE_RATE*0.96) { - filter.yn1=0.0; - filter.yn2=0.0; + if(freq > SAMPLE_RATE * 0.96) { + filter.yn1 = 0.0; + filter.yn2 = 0.0; + } + } - }; - }; - - filter.amp=amp; - filter.freq=freq; - filter.bw=bw; - computefiltercoefs(filter,freq,bw,1.0); -}; + filter.amp = amp; + filter.freq = freq; + filter.bw = bw; + computefiltercoefs(filter, freq, bw, 1.0); +} /* * Do the filtering */ -void SUBnote::filter(bpfilter &filter,REALTYPE *smps) +void SUBnote::filter(bpfilter &filter, REALTYPE *smps) { - int i; + int i; REALTYPE out; - for (i=0;iAmpEnvelope,freq); - if (pars->PFreqEnvelopeEnabled!=0) FreqEnvelope=new Envelope(pars->FreqEnvelope,freq); - else FreqEnvelope=NULL; - if (pars->PBandWidthEnvelopeEnabled!=0) BandWidthEnvelope=new Envelope(pars->BandWidthEnvelope,freq); - else BandWidthEnvelope=NULL; - if (pars->PGlobalFilterEnabled!=0) { - globalfiltercenterq=pars->GlobalFilter->getq(); - GlobalFilterL=new Filter(pars->GlobalFilter); - if (stereo!=0) GlobalFilterR=new Filter(pars->GlobalFilter); - GlobalFilterEnvelope=new Envelope(pars->GlobalFilterEnvelope,freq); - GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); - }; + AmpEnvelope = new Envelope(pars->AmpEnvelope, freq); + if(pars->PFreqEnvelopeEnabled != 0) + FreqEnvelope = new Envelope(pars->FreqEnvelope, freq); + else + FreqEnvelope = NULL; + if(pars->PBandWidthEnvelopeEnabled != 0) + BandWidthEnvelope = new Envelope(pars->BandWidthEnvelope, freq); + else + BandWidthEnvelope = NULL; + if(pars->PGlobalFilterEnabled != 0) { + globalfiltercenterq = pars->GlobalFilter->getq(); + GlobalFilterL = new Filter(pars->GlobalFilter); + if(stereo != 0) + GlobalFilterR = new Filter(pars->GlobalFilter); + GlobalFilterEnvelope = new Envelope(pars->GlobalFilterEnvelope, + freq); + GlobalFilterFreqTracking = pars->GlobalFilter->getfreqtracking(basefreq); + } computecurrentparameters(); -}; +} /* @@ -448,213 +519,249 @@ void SUBnote::initparameters(REALTYPE freq) */ void SUBnote::computecurrentparameters() { - if ((FreqEnvelope!=NULL)||(BandWidthEnvelope!=NULL)|| - (oldpitchwheel!=ctl->pitchwheel.data)|| - (oldbandwidth!=ctl->bandwidth.data)|| - (portamento!=0)) { - REALTYPE envfreq=1.0; - REALTYPE envbw=1.0; - REALTYPE gain=1.0; + if((FreqEnvelope != NULL) || (BandWidthEnvelope != NULL) + || (oldpitchwheel != ctl->pitchwheel.data) + || (oldbandwidth != ctl->bandwidth.data) + || (portamento != 0)) { + REALTYPE envfreq = 1.0; + REALTYPE envbw = 1.0; + REALTYPE gain = 1.0; - if (FreqEnvelope!=NULL) { - envfreq=FreqEnvelope->envout()/1200; - envfreq=pow(2.0,envfreq); - }; - envfreq*=ctl->pitchwheel.relfreq;//pitch wheel - if (portamento!=0) {//portamento is used - envfreq*=ctl->portamento.freqrap; - if (ctl->portamento.used==0) {//the portamento has finished - portamento=0;//this note is no longer "portamented" - }; - }; + if(FreqEnvelope != NULL) { + envfreq = FreqEnvelope->envout() / 1200; + envfreq = pow(2.0, envfreq); + } + envfreq *= ctl->pitchwheel.relfreq; //pitch wheel + if(portamento != 0) { //portamento is used + envfreq *= ctl->portamento.freqrap; + if(ctl->portamento.used == 0) //the portamento has finished + portamento = 0; //this note is no longer "portamented" + ; + } - if (BandWidthEnvelope!=NULL) { - envbw=BandWidthEnvelope->envout(); - envbw=pow(2,envbw); - }; - envbw*=ctl->bandwidth.relbw;//bandwidth controller + if(BandWidthEnvelope != NULL) { + envbw = BandWidthEnvelope->envout(); + envbw = pow(2, envbw); + } + envbw *= ctl->bandwidth.relbw; //bandwidth controller - REALTYPE tmpgain=1.0/sqrt(envbw*envfreq); + REALTYPE tmpgain = 1.0 / sqrt(envbw * envfreq); - for (int n=0;nbandwidth.data; - oldpitchwheel=ctl->pitchwheel.data; - }; - newamplitude=volume*AmpEnvelope->envout_dB()*2.0; + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs(lfilter[nph + n * numstages], + lfilter[nph + n * numstages].freq * envfreq, + lfilter[nph + n * numstages].bw * envbw, + gain); + } + } + if(stereo != 0) + for(int n = 0; n < numharmonics; n++) { + for(int nph = 0; nph < numstages; nph++) { + if(nph == 0) + gain = tmpgain; + else + gain = 1.0; + computefiltercoefs( + rfilter[nph + n * numstages], + rfilter[nph + n + * numstages].freq * envfreq, + rfilter[nph + n * numstages].bw * envbw, + gain); + } + } + ; + oldbandwidth = ctl->bandwidth.data; + oldpitchwheel = ctl->pitchwheel.data; + } + newamplitude = volume * AmpEnvelope->envout_dB() * 2.0; //Filter - if (GlobalFilterL!=NULL) { - REALTYPE globalfilterpitch=GlobalFilterCenterPitch+GlobalFilterEnvelope->envout(); - REALTYPE filterfreq=globalfilterpitch+ctl->filtercutoff.relfreq+GlobalFilterFreqTracking; - filterfreq=GlobalFilterL->getrealfreq(filterfreq); + if(GlobalFilterL != NULL) { + REALTYPE globalfilterpitch = GlobalFilterCenterPitch + + GlobalFilterEnvelope->envout(); + REALTYPE filterfreq = globalfilterpitch + ctl->filtercutoff.relfreq + + GlobalFilterFreqTracking; + filterfreq = GlobalFilterL->getrealfreq(filterfreq); - GlobalFilterL->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - if (GlobalFilterR!=NULL) GlobalFilterR->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); - }; - -}; + GlobalFilterL->setfreq_and_q(filterfreq, + globalfiltercenterq * ctl->filterq.relq); + if(GlobalFilterR != NULL) + GlobalFilterR->setfreq_and_q( + filterfreq, + globalfiltercenterq + * ctl->filterq.relq); + } +} /* * Note Output */ -int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) +int SUBnote::noteout(REALTYPE *outl, REALTYPE *outr) { int i; - for (i=0;ifilterout(&outl[0]); + if(GlobalFilterL != NULL) + GlobalFilterL->filterout(&outl[0]); //right channel - if (stereo!=0) { - for (i=0;ifilterout(&outr[0]); - } else for (i=0;ifilterout(&outr[0]); + } + else + memcpy(outr, outl, SOUND_BUFFER_SIZE * sizeof(REALTYPE)); - if (firsttick!=0) { - int n=10; - if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; - for (i=0;i SOUND_BUFFER_SIZE) + n = SOUND_BUFFER_SIZE; + for(i = 0; i < n; i++) { + REALTYPE ampfadein = 0.5 - 0.5 * cos( + (REALTYPE) i / (REALTYPE) n * PI); + outl[i] *= ampfadein; + outr[i] *= ampfadein; + } + firsttick = 0; + } - if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude,newamplitude)) { + if(ABOVE_AMPLITUDE_THRESHOLD(oldamplitude, newamplitude)) { // Amplitude interpolation - for (i=0;ifinished()!=0) { - for (i=0;ifinished() != 0) { + for(i = 0; i < SOUND_BUFFER_SIZE; i++) { //fade-out + REALTYPE tmp = 1.0 - (REALTYPE)i / (REALTYPE)SOUND_BUFFER_SIZE; + outl[i] *= tmp; + outr[i] *= tmp; + } KillNote(); - }; - return(1); -}; + } + return 1; +} /* * Relase Key (Note Off) @@ -662,17 +769,22 @@ int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr) void SUBnote::relasekey() { AmpEnvelope->relasekey(); - if (FreqEnvelope!=NULL) FreqEnvelope->relasekey(); - if (BandWidthEnvelope!=NULL) BandWidthEnvelope->relasekey(); - if (GlobalFilterEnvelope!=NULL) GlobalFilterEnvelope->relasekey(); -}; + if(FreqEnvelope != NULL) + FreqEnvelope->relasekey(); + if(BandWidthEnvelope != NULL) + BandWidthEnvelope->relasekey(); + if(GlobalFilterEnvelope != NULL) + GlobalFilterEnvelope->relasekey(); +} /* * Check if the note is finished */ int SUBnote::finished() { - if (NoteEnabled==OFF) return(1); - else return(0); -}; + if(NoteEnabled == OFF) + return 1; + else + return 0; +} diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.h b/plugins/zynaddsubfx/src/Synth/SUBnote.h index 48b55f1ca..e6b875e48 100644 --- a/plugins/zynaddsubfx/src/Synth/SUBnote.h +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.h @@ -31,84 +31,101 @@ class SUBnote { -public: - SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent); - ~SUBnote(); + public: + SUBnote(SUBnoteParameters *parameters, + Controller *ctl_, + REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool besilent); + ~SUBnote(); - void SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + void SUBlegatonote(REALTYPE freq, + REALTYPE velocity, + int portamento_, + int midinote, + bool externcall); - int noteout(REALTYPE *outl,REALTYPE *outr);//note output,return 0 if the note is finished - void relasekey(); - int finished(); + int noteout(REALTYPE *outl, REALTYPE *outr); //note output,return 0 if the note is finished + void relasekey(); + int finished(); - int ready; //if I can get the sampledata + int ready; //if I can get the sampledata -private: + private: - void computecurrentparameters(); - void initparameters(REALTYPE freq); - void KillNote(); + void computecurrentparameters(); + void initparameters(REALTYPE freq); + void KillNote(); - SUBnoteParameters *pars; + SUBnoteParameters *pars; - //parameters - int stereo; - int numstages;//number of stages of filters - int numharmonics;//number of harmonics (after the too higher hamonics are removed) - int firstnumharmonics;//To keep track of the first note's numharmonics value, useful in legato mode. - int start;//how the harmonics start - REALTYPE basefreq; - REALTYPE panning; - Envelope *AmpEnvelope; - Envelope *FreqEnvelope; - Envelope *BandWidthEnvelope; + //parameters + int stereo; + int numstages; //number of stages of filters + int numharmonics; //number of harmonics (after the too higher hamonics are removed) + int firstnumharmonics; //To keep track of the first note's numharmonics value, useful in legato mode. + int start; //how the harmonics start + REALTYPE basefreq; + REALTYPE panning; + Envelope *AmpEnvelope; + Envelope *FreqEnvelope; + Envelope *BandWidthEnvelope; - Filter *GlobalFilterL,*GlobalFilterR; + Filter *GlobalFilterL, *GlobalFilterR; - Envelope *GlobalFilterEnvelope; + Envelope *GlobalFilterEnvelope; - //internal values - ONOFFTYPE NoteEnabled; - int firsttick,portamento; - REALTYPE volume,oldamplitude,newamplitude; + //internal values + ONOFFTYPE NoteEnabled; + int firsttick, portamento; + REALTYPE volume, oldamplitude, newamplitude; - REALTYPE GlobalFilterCenterPitch;//octaves - REALTYPE GlobalFilterFreqTracking; + REALTYPE GlobalFilterCenterPitch; //octaves + REALTYPE GlobalFilterFreqTracking; - struct bpfilter { - REALTYPE freq,bw,amp; //filter parameters - REALTYPE a1,a2,b0,b2;//filter coefs. b1=0 - REALTYPE xn1,xn2,yn1,yn2; //filter internal values - }; + struct bpfilter { + REALTYPE freq, bw, amp; //filter parameters + REALTYPE a1, a2, b0, b2; //filter coefs. b1=0 + REALTYPE xn1, xn2, yn1, yn2; //filter internal values + }; - void initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag); - void computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain); - void filter(bpfilter &filter,REALTYPE *smps); + void initfilter(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE amp, + REALTYPE mag); + void computefiltercoefs(bpfilter &filter, + REALTYPE freq, + REALTYPE bw, + REALTYPE gain); + inline void filter(bpfilter &filter, REALTYPE *smps); - bpfilter *lfilter,*rfilter; + bpfilter *lfilter, *rfilter; - REALTYPE *tmpsmp; - REALTYPE *tmprnd;//this is filled with random numbers + REALTYPE *tmpsmp; + REALTYPE *tmprnd; //this is filled with random numbers - Controller *ctl; - int oldpitchwheel,oldbandwidth; - REALTYPE globalfiltercenterq; + Controller *ctl; + int oldpitchwheel, oldbandwidth; + REALTYPE globalfiltercenterq; - // Legato vars - struct { - bool silent; - REALTYPE lastfreq; - LegatoMsg msg; - int decounter; - struct { // Fade In/Out vars - int length; - REALTYPE m, step; - } fade; - struct { // Note parameters - REALTYPE freq, vel; - int portamento, midinote; - } param; - } Legato; + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; }; diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc index 831a8a533..9d3ca6caf 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc @@ -517,6 +517,56 @@ void ADvoiceUI::cb_Use1(Fl_Choice* o, void* v) { ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Use1_i(o,v); } +void ADvoiceUI::cb_Stereo_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value(); +} +void ADvoiceUI::cb_Stereo(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Stereo_i(o,v); +} + +void ADvoiceUI::cb_Unison_i(Fl_Choice* o, void*) { + pars->set_unison_size_index(nvoice,(int) o->value()); +} +void ADvoiceUI::cb_Unison(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Unison_i(o,v); +} + +void ADvoiceUI::cb_Vibratto_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_vibratto=(int)o->value(); +} +void ADvoiceUI::cb_Vibratto(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Vibratto_i(o,v); +} + +void ADvoiceUI::cb_Invert_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].Unison_invert_phase=(int) o->value(); +} +void ADvoiceUI::cb_Invert(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Invert_i(o,v); +} + +void ADvoiceUI::cb_Frequency_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value(); +unisonspreadoutput->do_callback(); +} +void ADvoiceUI::cb_Frequency(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Frequency_i(o,v); +} + +void ADvoiceUI::cb_unisonspreadoutput_i(Fl_Value_Output* o, void*) { + o->value(pars->getUnisonFrequencySpreadCents(nvoice)); +} +void ADvoiceUI::cb_unisonspreadoutput(Fl_Value_Output* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_unisonspreadoutput_i(o,v); +} + +void ADvoiceUI::cb_Vib_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].Unison_vibratto_speed=(int)o->value(); +} +void ADvoiceUI::cb_Vib(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Vib_i(o,v); +} + void ADvoiceUI::cb_Vol1_i(Fl_Value_Slider* o, void*) { pars->VoicePar[nvoice].PVolume=(int)o->value(); } @@ -645,7 +695,7 @@ void ADvoiceUI::cb_voiceonbutton(Fl_Check_Button* o, void* v) { } Fl_Group* ADvoiceUI::make_window() { - { ADnoteVoiceParameters = new Fl_Group(0, 0, 765, 525, "Voice"); + { ADnoteVoiceParameters = new Fl_Group(0, 0, 765, 575, "Voice"); ADnoteVoiceParameters->box(FL_FLAT_BOX); ADnoteVoiceParameters->color(FL_BACKGROUND_COLOR); ADnoteVoiceParameters->selection_color(FL_BACKGROUND_COLOR); @@ -656,11 +706,11 @@ Fl_Group* ADvoiceUI::make_window() { ADnoteVoiceParameters->user_data((void*)(this)); ADnoteVoiceParameters->align(Fl_Align(FL_ALIGN_TOP)); ADnoteVoiceParameters->when(FL_WHEN_RELEASE); - { Fl_Group* o = voiceparametersgroup = new Fl_Group(0, 0, 765, 525); + { Fl_Group* o = voiceparametersgroup = new Fl_Group(0, 0, 765, 580); voiceparametersgroup->box(FL_THIN_UP_BOX); voiceparametersgroup->color((Fl_Color)48); - { voicemodegroup = new Fl_Group(0, 5, 760, 515); - { Fl_Group* o = voiceFMparametersgroup = new Fl_Group(530, 5, 230, 515, "MODULATOR"); + { voicemodegroup = new Fl_Group(0, 5, 760, 575); + { Fl_Group* o = voiceFMparametersgroup = new Fl_Group(530, 5, 230, 565, "MODULATOR"); voiceFMparametersgroup->box(FL_THIN_UP_FRAME); voiceFMparametersgroup->color((Fl_Color)48); voiceFMparametersgroup->labeltype(FL_EMBOSSED_LABEL); @@ -823,8 +873,8 @@ Fl_Group* ADvoiceUI::make_window() { } // Fl_Value_Slider* o o->end(); } // Fl_Group* o - { modoscil = new Fl_Group(535, 365, 220, 150); - { Fl_Group* o = fmoscil = new Fl_Group(535, 405, 220, 110); + { modoscil = new Fl_Group(535, 365, 220, 200); + { Fl_Group* o = fmoscil = new Fl_Group(535, 425, 220, 140); fmoscil->box(FL_THIN_DOWN_BOX); fmoscil->color(FL_GRAY0); fmoscil->selection_color((Fl_Color)71); @@ -845,7 +895,7 @@ Fl_Group* ADvoiceUI::make_window() { changeFMoscilbutton->callback((Fl_Callback*)cb_changeFMoscilbutton); if (pars->VoicePar[nvoice].PextFMoscil>=0) o->labelcolor(FL_BLUE); } // Fl_Button* changeFMoscilbutton - { Fl_Slider* o = new Fl_Slider(665, 395, 65, 10, "Phase"); + { Fl_Slider* o = new Fl_Slider(665, 400, 65, 10, "Phase"); o->type(5); o->box(FL_FLAT_BOX); o->labelsize(10); @@ -856,7 +906,7 @@ Fl_Group* ADvoiceUI::make_window() { o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); o->value(64-pars->VoicePar[nvoice].PFMoscilphase); } // Fl_Slider* o - { Fl_Choice* o = new Fl_Choice(560, 390, 75, 15, "Use"); + { Fl_Choice* o = new Fl_Choice(560, 395, 75, 15, "Use"); o->down_box(FL_BORDER_BOX); o->labelsize(10); o->textfont(1); @@ -1082,6 +1132,102 @@ cy)"); char tmp[50]; for (int i=0;iadd(tmp);}; o->value(pars->VoicePar[nvoice].Pextoscil+1); } // Fl_Choice* o + { Fl_Group* o = new Fl_Group(5, 525, 515, 45); + o->box(FL_ENGRAVED_BOX); + { WidgetPDial* o = new WidgetPDial(285, 540, 25, 25, "Stereo"); + o->tooltip("Stereo Spread"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Stereo); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_stereo_spread); + } // WidgetPDial* o + { Fl_Choice* o = new Fl_Choice(10, 545, 75, 20, "Unison"); + o->tooltip("Unison size"); + o->down_box(FL_BORDER_BOX); + o->labelfont(1); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Unison); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);}; + o->value(pars->get_unison_size_index(nvoice)); + } // Fl_Choice* o + { WidgetPDial* o = new WidgetPDial(340, 540, 25, 25, "Vibratto"); + o->tooltip("Vibratto"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vibratto); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_vibratto); + } // WidgetPDial* o + { Fl_Choice* o = new Fl_Choice(445, 545, 65, 15, "Invert"); + o->tooltip("Phase Invert"); + o->down_box(FL_BORDER_BOX); + o->labelsize(11); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Invert); + o->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->add("None");o->add("Random");char tmp[100];for (int i=2;i<=5;i++){snprintf(tmp,100,"%d %%",100/i);o->add(tmp);}; + o->value(pars->VoicePar[nvoice].Unison_invert_phase); + } // Fl_Choice* o + { Fl_Slider* o = new Fl_Slider(95, 547, 125, 13, "Frequency Spread"); + o->tooltip("Frequency Spread of the Unison"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(12); + o->maximum(127); + o->step(1); + o->value(64); + o->callback((Fl_Callback*)cb_Frequency); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->value(pars->VoicePar[nvoice].Unison_frequency_spread); + } // Fl_Slider* o + { Fl_Value_Output* o = unisonspreadoutput = new Fl_Value_Output(225, 545, 40, 15, "(cents)"); + unisonspreadoutput->labelsize(10); + unisonspreadoutput->maximum(1000); + unisonspreadoutput->step(0.1); + unisonspreadoutput->textfont(1); + unisonspreadoutput->textsize(10); + unisonspreadoutput->callback((Fl_Callback*)cb_unisonspreadoutput); + unisonspreadoutput->align(Fl_Align(FL_ALIGN_TOP_LEFT)); + o->value(pars->getUnisonFrequencySpreadCents(nvoice)); + } // Fl_Value_Output* unisonspreadoutput + { WidgetPDial* o = new WidgetPDial(390, 540, 25, 25, "Vib.speed"); + o->tooltip("Vibratto Average Speed"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vib); + o->align(Fl_Align(FL_ALIGN_TOP)); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].Unison_vibratto_speed); + } // WidgetPDial* o + o->end(); + } // Fl_Group* o voicemodegroup->end(); } // Fl_Group* voicemodegroup { Fl_Group* o = new Fl_Group(5, 40, 240, 210, "AMPLITUDE"); @@ -1522,7 +1668,7 @@ void ADnoteUI::cb_currentvoicecounter_i(Fl_Counter* o, void*) { advoice->hide(); ADnoteVoice->remove(advoice); delete advoice; -advoice=new ADvoiceUI(0,0,765,525); +advoice=new ADvoiceUI(0,0,765,585); ADnoteVoice->add(advoice); advoice->init(pars,nvoice,master); advoice->show(); @@ -1899,9 +2045,9 @@ Fl_Double_Window* ADnoteUI::make_window() { } // Fl_Button* o ADnoteGlobalParameters->end(); } // Fl_Double_Window* ADnoteGlobalParameters - { ADnoteVoice = new Fl_Double_Window(765, 560, "ADsynth Voice Parameters"); + { ADnoteVoice = new Fl_Double_Window(765, 620, "ADsynth Voice Parameters"); ADnoteVoice->user_data((void*)(this)); - { ADvoiceUI* o = advoice = new ADvoiceUI(0, 0, 760, 525); + { ADvoiceUI* o = advoice = new ADvoiceUI(0, 0, 760, 575); advoice->box(FL_BORDER_BOX); advoice->color(FL_BACKGROUND_COLOR); advoice->selection_color(FL_BACKGROUND_COLOR); @@ -1915,12 +2061,12 @@ Fl_Double_Window* ADnoteUI::make_window() { o->show(); advoice->end(); } // ADvoiceUI* advoice - { Fl_Button* o = new Fl_Button(300, 530, 195, 25, "Close Window"); + { Fl_Button* o = new Fl_Button(300, 585, 195, 25, "Close Window"); o->box(FL_THIN_UP_BOX); o->labelfont(1); o->callback((Fl_Callback*)cb_Close1); } // Fl_Button* o - { Fl_Counter* o = currentvoicecounter = new Fl_Counter(5, 530, 130, 25, "Current Voice"); + { Fl_Counter* o = currentvoicecounter = new Fl_Counter(5, 585, 130, 25, "Current Voice"); currentvoicecounter->type(1); currentvoicecounter->labelfont(1); currentvoicecounter->minimum(0); @@ -1933,7 +2079,7 @@ Fl_Double_Window* ADnoteUI::make_window() { currentvoicecounter->align(Fl_Align(FL_ALIGN_RIGHT)); o->bounds(1,NUM_VOICES); } // Fl_Counter* currentvoicecounter - { Fl_Button* o = new Fl_Button(700, 535, 25, 15, "C"); + { Fl_Button* o = new Fl_Button(700, 590, 25, 15, "C"); o->box(FL_THIN_UP_BOX); o->color((Fl_Color)179); o->labelfont(1); @@ -1941,7 +2087,7 @@ Fl_Double_Window* ADnoteUI::make_window() { o->labelcolor(FL_BACKGROUND2_COLOR); o->callback((Fl_Callback*)cb_C1); } // Fl_Button* o - { Fl_Button* o = new Fl_Button(730, 535, 25, 15, "P"); + { Fl_Button* o = new Fl_Button(730, 590, 25, 15, "P"); o->box(FL_THIN_UP_BOX); o->color((Fl_Color)179); o->labelfont(1); diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl index 4888eaea4..748156c74 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0109 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} @@ -178,19 +178,19 @@ class ADvoiceUI {open : {public Fl_Group} } { Fl_Window ADnoteVoiceParameters { label Voice - xywh {225 174 765 525} type Double hide - class Fl_Group + xywh {69 185 765 575} type Double + class Fl_Group visible } { - Fl_Group voiceparametersgroup { - xywh {0 0 765 525} box THIN_UP_BOX color 48 + Fl_Group voiceparametersgroup {open + xywh {0 0 765 580} box THIN_UP_BOX color 48 code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();} } { - Fl_Group voicemodegroup { - xywh {0 5 760 515} + Fl_Group voicemodegroup {open + xywh {0 5 760 575} } { Fl_Group voiceFMparametersgroup { label MODULATOR - xywh {530 5 230 515} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + xywh {530 5 230 565} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 code0 {if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate();} } { Fl_Group modfrequency { @@ -209,7 +209,7 @@ class ADvoiceUI {open : {public Fl_Group} callback {pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value(); if (o->value()==0) voiceFMfreqenvgroup->deactivate(); else voiceFMfreqenvgroup->activate(); -o->redraw();} selected +o->redraw();} tooltip {Forced Relase} xywh {545 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 code0 {o->value(pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled);} } @@ -298,10 +298,10 @@ o->redraw();} } } Fl_Group modoscil { - xywh {535 365 220 150} + xywh {535 365 220 200} } { Fl_Group fmoscil {open - xywh {535 405 220 110} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + xywh {535 425 220 140} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 code0 {oscFM=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} code1 {int nv=nvoice; if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil;} code2 {oscFM->init(pars->VoicePar[nv].FMSmp,0,pars->VoicePar[nvoice].PFMoscilphase,master);} @@ -326,7 +326,7 @@ oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master);} callback {pars->VoicePar[nvoice].PFMoscilphase=64-(int)o->value(); oscFM->phase=64-(int) o->value(); fmoscil->redraw();} - xywh {665 395 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + xywh {665 400 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 code0 {o->value(64-pars->VoicePar[nvoice].PFMoscilphase);} } Fl_Choice {} { @@ -340,7 +340,7 @@ if ((int) o->value() != 0) { changeFMoscilbutton->labelcolor(FL_BLACK); }; voiceFMparametersgroup->redraw();} open - xywh {560 390 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + xywh {560 395 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 code0 {o->add("Internal");} code1 {char tmp[50]; for (int i=0;iadd(tmp);};} code3 {o->value(pars->VoicePar[nvoice].PextFMoscil+1);} @@ -548,6 +548,58 @@ voiceonbutton->redraw();} open code1 {char tmp[50]; for (int i=0;iadd(tmp);};} code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);} } {} + Fl_Group {} {open + xywh {5 525 515 45} box ENGRAVED_BOX + } { + Fl_Dial {} { + label Stereo + callback {pars->VoicePar[nvoice].Unison_stereo_spread=(int)o->value();} + tooltip {Stereo Spread} xywh {285 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_stereo_spread);} + class WidgetPDial + } + Fl_Choice {} { + label Unison + callback {pars->set_unison_size_index(nvoice,(int) o->value());} open selected + tooltip {Unison size} xywh {10 545 75 20} down_box BORDER_BOX labelfont 1 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");char tmp[100];for (int i=1;ADnote_unison_sizes[i];i++){snprintf(tmp,100,"size %d",ADnote_unison_sizes[i]);o->add(tmp);};} + code1 {o->value(pars->get_unison_size_index(nvoice));} + } {} + Fl_Dial {} { + label Vibratto + callback {pars->VoicePar[nvoice].Unison_vibratto=(int)o->value();} + tooltip Vibratto xywh {340 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto);} + class WidgetPDial + } + Fl_Choice {} { + label Invert + callback {pars->VoicePar[nvoice].Unison_invert_phase=(int) o->value();} open + tooltip {Phase Invert} xywh {445 545 65 15} down_box BORDER_BOX labelsize 11 align 5 textfont 1 textsize 10 + code0 {o->add("None");o->add("Random");char tmp[100];for (int i=2;i<=5;i++){snprintf(tmp,100,"%d %%",100/i);o->add(tmp);};} + code1 {o->value(pars->VoicePar[nvoice].Unison_invert_phase);} + } {} + Fl_Slider {} { + label {Frequency Spread} + callback {pars->VoicePar[nvoice].Unison_frequency_spread=(int)o->value(); +unisonspreadoutput->do_callback();} + tooltip {Frequency Spread of the Unison} xywh {95 547 125 13} type {Horz Knob} box FLAT_BOX labelsize 12 align 1 maximum 127 step 1 value 64 + code0 {o->value(pars->VoicePar[nvoice].Unison_frequency_spread);} + } + Fl_Value_Output unisonspreadoutput { + label {(cents)} + callback {o->value(pars->getUnisonFrequencySpreadCents(nvoice));} + xywh {225 545 40 15} labelsize 10 align 5 maximum 1000 step 0.1 textfont 1 textsize 10 + code0 {o->value(pars->getUnisonFrequencySpreadCents(nvoice));} + } + Fl_Dial {} { + label {Vib.speed} + callback {pars->VoicePar[nvoice].Unison_vibratto_speed=(int)o->value();} + tooltip {Vibratto Average Speed} xywh {390 540 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].Unison_vibratto_speed);} + class WidgetPDial + } + } } Fl_Group {} { label AMPLITUDE @@ -728,7 +780,8 @@ o->redraw();} pars=NULL; oscedit=NULL;} {} } - Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {open + } { code {pars=parameters; nvoice=nvoice_; master=master_; @@ -752,7 +805,7 @@ if (oscedit!=NULL) { decl {Master *master;} {} } -class ADnoteUI {: {public PresetsUI_} +class ADnoteUI {open : {public PresetsUI_} } { Function {make_window()} {open private } { @@ -967,10 +1020,10 @@ resui->resonancewindow->show();} } Fl_Window ADnoteVoice { label {ADsynth Voice Parameters} - xywh {53 58 765 560} type Double hide + xywh {152 271 765 620} type Double visible } { Fl_Group advoice { - xywh {0 0 760 525} box BORDER_BOX + xywh {0 0 760 575} box BORDER_BOX code0 {o->init(pars,nvoice,master);} code1 {o->show();} class ADvoiceUI @@ -978,7 +1031,7 @@ resui->resonancewindow->show();} Fl_Button {} { label {Close Window} callback {ADnoteVoice->hide();} - xywh {300 530 195 25} box THIN_UP_BOX labelfont 1 + xywh {300 585 195 25} box THIN_UP_BOX labelfont 1 } Fl_Counter currentvoicecounter { label {Current Voice} @@ -986,23 +1039,23 @@ resui->resonancewindow->show();} advoice->hide(); ADnoteVoice->remove(advoice); delete advoice; -advoice=new ADvoiceUI(0,0,765,525); +advoice=new ADvoiceUI(0,0,765,585); ADnoteVoice->add(advoice); advoice->init(pars,nvoice,master); advoice->show(); ADnoteVoice->redraw();} - xywh {5 530 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13 + xywh {5 585 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13 code0 {o->bounds(1,NUM_VOICES);} } Fl_Button {} { label C callback {presetsui->copy(pars,nvoice);} - xywh {700 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + xywh {700 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 } Fl_Button {} { label P callback {presetsui->paste(pars,this,nvoice);} - xywh {730 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + xywh {730 590 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 } } Fl_Window ADnoteVoiceList { diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.h b/plugins/zynaddsubfx/src/UI/ADnoteUI.h index 01817c196..a9a573d60 100644 --- a/plugins/zynaddsubfx/src/UI/ADnoteUI.h +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.h @@ -174,6 +174,23 @@ private: static void cb_R(Fl_Check_Button*, void*); void cb_Use1_i(Fl_Choice*, void*); static void cb_Use1(Fl_Choice*, void*); + void cb_Stereo_i(WidgetPDial*, void*); + static void cb_Stereo(WidgetPDial*, void*); + void cb_Unison_i(Fl_Choice*, void*); + static void cb_Unison(Fl_Choice*, void*); + void cb_Vibratto_i(WidgetPDial*, void*); + static void cb_Vibratto(WidgetPDial*, void*); + void cb_Invert_i(Fl_Choice*, void*); + static void cb_Invert(Fl_Choice*, void*); + void cb_Frequency_i(Fl_Slider*, void*); + static void cb_Frequency(Fl_Slider*, void*); +public: + Fl_Value_Output *unisonspreadoutput; +private: + void cb_unisonspreadoutput_i(Fl_Value_Output*, void*); + static void cb_unisonspreadoutput(Fl_Value_Output*, void*); + void cb_Vib_i(WidgetPDial*, void*); + static void cb_Vib(WidgetPDial*, void*); void cb_Vol1_i(Fl_Value_Slider*, void*); static void cb_Vol1(Fl_Value_Slider*, void*); void cb_V1_i(Fl_Value_Slider*, void*); diff --git a/plugins/zynaddsubfx/src/UI/EffUI.cc b/plugins/zynaddsubfx/src/UI/EffUI.cc index 9da1534d9..9c1b141c7 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.cc +++ b/plugins/zynaddsubfx/src/UI/EffUI.cc @@ -154,6 +154,7 @@ void EffUI::cb_revp10(Fl_Choice* o, void* v) { Fl_Menu_Item EffUI::menu_revp10[] = { {"Random", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {"Freeverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, {0,0,0,0,0,0,0,0,0} }; @@ -192,11 +193,11 @@ void EffUI::cb_revp4(WidgetPDial* o, void* v) { ((EffUI*)(o->parent()->user_data()))->cb_revp4_i(o,v); } -void EffUI::cb_revp5_i(WidgetPDial* o, void*) { - eff->seteffectpar(5,(int) o->value()); +void EffUI::cb_revp12_i(WidgetPDial* o, void*) { + eff->seteffectpar(12,(int) o->value()); } -void EffUI::cb_revp5(WidgetPDial* o, void* v) { - ((EffUI*)(o->parent()->user_data()))->cb_revp5_i(o,v); +void EffUI::cb_revp12(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp12_i(o,v); } void EffUI::cb_revp6_i(WidgetPDial* o, void*) { @@ -1022,7 +1023,7 @@ Fl_Group* EffUI::make_reverb_window() { revp->align(Fl_Align(FL_ALIGN_TOP_LEFT)); revp->menu(menu_revp); } // Fl_Choice* revp - { revp10 = new Fl_Choice(110, 15, 75, 15, "Type"); + { revp10 = new Fl_Choice(110, 15, 85, 15, "Type"); revp10->down_box(FL_BORDER_BOX); revp10->color((Fl_Color)14); revp10->labelfont(1); @@ -1103,20 +1104,19 @@ Fl_Group* EffUI::make_reverb_window() { revp4->align(Fl_Align(FL_ALIGN_BOTTOM)); revp4->when(FL_WHEN_CHANGED); } // WidgetPDial* revp4 - { revp5 = new WidgetPDial(200, 40, 30, 30, "R.delay"); - revp5->box(FL_ROUND_UP_BOX); - revp5->color(FL_BACKGROUND_COLOR); - revp5->selection_color(FL_INACTIVE_COLOR); - revp5->labeltype(FL_NORMAL_LABEL); - revp5->labelfont(1); - revp5->labelsize(11); - revp5->labelcolor(FL_FOREGROUND_COLOR); - revp5->maximum(127); - revp5->callback((Fl_Callback*)cb_revp5); - revp5->align(Fl_Align(FL_ALIGN_BOTTOM)); - revp5->when(FL_WHEN_RELEASE); - revp5->deactivate(); - } // WidgetPDial* revp5 + { revp12 = new WidgetPDial(200, 40, 30, 30, "bw"); + revp12->box(FL_ROUND_UP_BOX); + revp12->color(FL_BACKGROUND_COLOR); + revp12->selection_color(FL_INACTIVE_COLOR); + revp12->labeltype(FL_NORMAL_LABEL); + revp12->labelfont(1); + revp12->labelsize(11); + revp12->labelcolor(FL_FOREGROUND_COLOR); + revp12->maximum(127); + revp12->callback((Fl_Callback*)cb_revp12); + revp12->align(Fl_Align(FL_ALIGN_BOTTOM)); + revp12->when(FL_WHEN_RELEASE); + } // WidgetPDial* revp12 { revp6 = new WidgetPDial(235, 40, 30, 30, "E/R"); revp6->box(FL_ROUND_UP_BOX); revp6->color(FL_BACKGROUND_COLOR); @@ -1175,7 +1175,7 @@ Fl_Group* EffUI::make_reverb_window() { revp9->align(Fl_Align(FL_ALIGN_BOTTOM)); revp9->when(FL_WHEN_CHANGED); } // WidgetPDial* revp9 - { revp11 = new WidgetPDial(190, 10, 25, 25, "R.S."); + { revp11 = new WidgetPDial(200, 10, 25, 25, "R.S."); revp11->tooltip("RoomSize"); revp11->box(FL_ROUND_UP_BOX); revp11->color(FL_BACKGROUND_COLOR); @@ -2449,13 +2449,14 @@ switch(eff->geteffect()){ revp2->value(eff->geteffectpar(2)); revp3->value(eff->geteffectpar(3)); revp4->value(eff->geteffectpar(4)); - revp5->value(eff->geteffectpar(5)); + //revp5->value(eff->geteffectpar(5)); revp6->value(eff->geteffectpar(6)); revp7->value(eff->geteffectpar(7)); revp8->value(eff->geteffectpar(8)); revp9->value(eff->geteffectpar(9)); revp10->value(eff->geteffectpar(10)); revp11->value(eff->geteffectpar(11)); + revp12->value(eff->geteffectpar(12)); effreverbwindow->show(); break; @@ -2573,13 +2574,13 @@ void EffUI::refresh() { refresh(eff); } -void SimpleEffUI::cb_revpa_i(Fl_Choice* o, void*) { +void SimpleEffUI::cb_revp5_i(Fl_Choice* o, void*) { eff->changepreset((int)o->value()); refresh(eff); } -void SimpleEffUI::cb_revpa(Fl_Choice* o, void* v) { - ((SimpleEffUI*)(o->parent()->user_data()))->cb_revpa_i(o,v); +void SimpleEffUI::cb_revp5(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp5_i(o,v); } Fl_Menu_Item SimpleEffUI::menu_revp1[] = { @@ -3118,7 +3119,7 @@ Fl_Group* SimpleEffUI::make_reverb_window() { revp->textfont(1); revp->textsize(10); revp->textcolor(FL_BACKGROUND2_COLOR); - revp->callback((Fl_Callback*)cb_revpa); + revp->callback((Fl_Callback*)cb_revp5); revp->align(Fl_Align(FL_ALIGN_TOP_LEFT)); revp->menu(menu_revp1); } // Fl_Choice* revp diff --git a/plugins/zynaddsubfx/src/UI/EffUI.fl b/plugins/zynaddsubfx/src/UI/EffUI.fl index e2712f107..178f3ad04 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.fl +++ b/plugins/zynaddsubfx/src/UI/EffUI.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0107 +version 1.0109 header_name {.h} code_name {.cc} decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} @@ -36,7 +36,7 @@ decl {\#include "../Effects/EffectMgr.h"} {public decl {\#include "PresetsUI.h"} {public } -class EQGraph {selected : {public Fl_Box} +class EQGraph {: {public Fl_Box} } { Function {EQGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { code {eff=NULL; @@ -155,7 +155,7 @@ return(log(freq/20.0)/log(1000.0));} {} decl {int maxdB;} {} } -class EffUI {: {public Fl_Group,public PresetsUI_} +class EffUI {open : {public Fl_Group,public PresetsUI_} } { Function {EffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { code {eff=NULL; @@ -188,10 +188,11 @@ if (filterwindow!=NULL){ } } } - Function {make_reverb_window()} {} { - Fl_Window effreverbwindow { - xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide - class Fl_Group + Function {make_reverb_window()} {open + } { + Fl_Window effreverbwindow {open + xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 + class Fl_Group visible } { Fl_Text_Display {} { label {Reverb } @@ -259,8 +260,8 @@ refresh(eff);} } Fl_Choice revp10 { label Type - callback {eff->seteffectpar(10,(int) o->value());} - xywh {110 15 75 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + callback {eff->seteffectpar(10,(int) o->value());} open + xywh {110 15 85 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 } { MenuItem {} { label Random @@ -270,6 +271,10 @@ refresh(eff);} label Freeverb xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 } + MenuItem {} { + label Bandwidth + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } } Fl_Dial revp0 { label Vol @@ -301,10 +306,10 @@ refresh(eff);} tooltip {Initial Delay Feedback} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 class WidgetPDial } - Fl_Dial revp5 { - label {R.delay} - callback {eff->seteffectpar(5,(int) o->value());} - xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 deactivate + Fl_Dial revp12 { + label bw + callback {eff->seteffectpar(12,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 class WidgetPDial } Fl_Dial revp6 { @@ -337,7 +342,7 @@ refresh(eff);} if (Fl::event_button1()) x=(int)o->value(); else o->value(x); eff->seteffectpar(11,x);} - tooltip RoomSize xywh {190 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1 + tooltip RoomSize xywh {200 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1 class WidgetPDial } } @@ -1263,7 +1268,8 @@ effdynamicfilterwindow->position(px,py); refresh(eff);} {} } - Function {refresh(EffectMgr *eff_)} {} { + Function {refresh(EffectMgr *eff_)} {open + } { code {eff=eff_; this->hide(); @@ -1293,13 +1299,14 @@ switch(eff->geteffect()){ revp2->value(eff->geteffectpar(2)); revp3->value(eff->geteffectpar(3)); revp4->value(eff->geteffectpar(4)); - revp5->value(eff->geteffectpar(5)); + //revp5->value(eff->geteffectpar(5)); revp6->value(eff->geteffectpar(6)); revp7->value(eff->geteffectpar(7)); revp8->value(eff->geteffectpar(8)); revp9->value(eff->geteffectpar(9)); revp10->value(eff->geteffectpar(10)); revp11->value(eff->geteffectpar(11)); + revp12->value(eff->geteffectpar(12)); effreverbwindow->show(); break; @@ -1410,7 +1417,8 @@ switch(eff->geteffect()){ break; }; -this->show();} {} +this->show();} {selected + } } Function {refresh()} {} { code {refresh(eff);} {} diff --git a/plugins/zynaddsubfx/src/UI/EffUI.h b/plugins/zynaddsubfx/src/UI/EffUI.h index 3fddc2920..9f8721b51 100644 --- a/plugins/zynaddsubfx/src/UI/EffUI.h +++ b/plugins/zynaddsubfx/src/UI/EffUI.h @@ -84,10 +84,10 @@ private: void cb_revp4_i(WidgetPDial*, void*); static void cb_revp4(WidgetPDial*, void*); public: - WidgetPDial *revp5; + WidgetPDial *revp12; private: - void cb_revp5_i(WidgetPDial*, void*); - static void cb_revp5(WidgetPDial*, void*); + void cb_revp12_i(WidgetPDial*, void*); + static void cb_revp12(WidgetPDial*, void*); public: WidgetPDial *revp6; private: @@ -545,8 +545,8 @@ public: Fl_Group *effreverbwindow; Fl_Choice *revp; private: - void cb_revpa_i(Fl_Choice*, void*); - static void cb_revpa(Fl_Choice*, void*); + void cb_revp5_i(Fl_Choice*, void*); + static void cb_revp5(Fl_Choice*, void*); static Fl_Menu_Item menu_revp1[]; public: WidgetPDial *revp0; diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.cc b/plugins/zynaddsubfx/src/UI/MasterUI.cc index 2b91bd54e..bd8545239 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.cc +++ b/plugins/zynaddsubfx/src/UI/MasterUI.cc @@ -214,7 +214,8 @@ labelsize(10); align(FL_ALIGN_TOP); value(master->Psysefxsend[neff1][neff2]); -char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp)); +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1); +this->copy_label(tmp); } SysEffSend::~SysEffSend() { @@ -380,7 +381,7 @@ Fl_Group* Panellistitem::make_window() { partenabled->labelsize(13); partenabled->callback((Fl_Callback*)cb_partenabled); partenabled->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); - char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp); o->value(master->part[npart]->Penabled); } // Fl_Check_Button* partenabled panellistitem->end(); @@ -1986,7 +1987,7 @@ General Public License for details."); partenabled->labelsize(13); partenabled->callback((Fl_Callback*)cb_partenabled1); partenabled->align(Fl_Align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE)); - //char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + //char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp); o->value(master->part[npart]->Penabled); } // Fl_Check_Button* partenabled { VirKeys* o = virkeys = new VirKeys(5, 215, 590, 80, "Keyboard"); @@ -2338,19 +2339,23 @@ simplerefresh(); MasterUI::~MasterUI() { masterwindow->hide(); -delete (masterwindow); +delete masterwindow; +simplemasterwindow->hide(); +delete simplemasterwindow; aboutwindow->hide(); -delete (aboutwindow); +delete aboutwindow; syseffsendwindow->hide(); -delete(syseffsendwindow); +delete syseffsendwindow; -delete (virkeyboard); -delete (microtonalui); -delete (bankui); -delete (configui); -delete (sequi); +delete virkeyboard; +delete microtonalui; +delete bankui; +delete configui; +delete sequi; -delete(presetsui); +delete presetsui; +delete panelwindow; +delete selectuiwindow; } void MasterUI::showUI() { diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.fl b/plugins/zynaddsubfx/src/UI/MasterUI.fl index b0c77d790..a844def6c 100644 --- a/plugins/zynaddsubfx/src/UI/MasterUI.fl +++ b/plugins/zynaddsubfx/src/UI/MasterUI.fl @@ -1,9 +1,8 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0109 +version 1.0107 header_name {.h} code_name {.cc} -decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {selected -} +decl {//Copyright (c) 2002-2009 Nasca Octavian Paul} {} decl {//License: GNU GPL version 2 or later} {} @@ -275,7 +274,8 @@ labelsize(10); align(FL_ALIGN_TOP); value(master->Psysefxsend[neff1][neff2]); -char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp));} {} +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1); +this->copy_label(tmp);} {} } Function {~SysEffSend()} {} { code {hide();} {} @@ -344,7 +344,7 @@ bankui->show();} xywh {15 235 40 20} box PLASTIC_UP_BOX labelsize 10 } Fl_Choice partrcv { - callback {master->part[npart]->Prcvchn=(int) o->value();} open + callback {master->part[npart]->Prcvchn=(int) o->value();} tooltip {receive from Midi channel} xywh {10 213 50 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");};} code1 {o->value(master->part[npart]->Prcvchn);} @@ -367,7 +367,7 @@ if ((int) o->value()==0) panellistitemgroup->deactivate(); o->redraw();} private xywh {5 0 45 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 - code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);} code1 {o->value(master->part[npart]->Penabled);} } } @@ -386,8 +386,7 @@ make_window(); panellistitem->show(); end();} {} } - Function {refresh()} {open - } { + Function {refresh()} {} { code {partenabled->value(master->part[npart]->Penabled); if (master->part[npart]->Penabled!=0) panellistitemgroup->activate(); else panellistitemgroup->deactivate(); @@ -415,7 +414,8 @@ panellistitemgroup->redraw();} {} } class MasterUI {} { - Function {make_window()} {} { + Function {make_window()} {selected + } { Fl_Window masterwindow { label zynaddsubfx callback {\#ifdef VSTAUDIOOUT @@ -426,7 +426,7 @@ if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { *exitprogram=1; }; \#endif} - xywh {31 206 390 465} type Double xclass zynaddsubfx visible + xywh {31 206 390 465} type Double hide xclass zynaddsubfx } { Fl_Menu_Bar mastermenu { xywh {-5 0 690 25} @@ -1043,18 +1043,18 @@ GNU General Public License for details.} label {ZynAddSubFX Panel} xywh {89 59 630 635} type Double hide } { - Fl_Scroll {} {open + Fl_Scroll {} { xywh {0 5 570 310} type HORIZONTAL box THIN_UP_BOX } { - Fl_Pack {} {open + Fl_Pack {} { xywh {5 10 560 285} type HORIZONTAL code0 {for (int i=0;iinit(master,i,bankui);}} } {} } - Fl_Scroll {} {open + Fl_Scroll {} { xywh {0 320 570 310} type HORIZONTAL box THIN_UP_BOX } { - Fl_Pack {} {open + Fl_Pack {} { xywh {5 325 560 285} type HORIZONTAL code0 {for (int i=NUM_MIDI_PARTS/2;iinit(master,i,bankui);}} } {} @@ -1288,7 +1288,7 @@ if ((int) o->value()==0) simplelistitemgroup->deactivate(); o->redraw();} private xywh {250 40 85 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 - code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->copy_label(tmp);} code1 {o->value(master->part[npart]->Penabled);} } Fl_Box virkeys { @@ -1643,19 +1643,23 @@ simplerefresh();} {} } Function {~MasterUI()} {} { code {masterwindow->hide(); -delete (masterwindow); +delete masterwindow; +simplemasterwindow->hide(); +delete simplemasterwindow; aboutwindow->hide(); -delete (aboutwindow); +delete aboutwindow; syseffsendwindow->hide(); -delete(syseffsendwindow); +delete syseffsendwindow; -delete (virkeyboard); -delete (microtonalui); -delete (bankui); -delete (configui); -delete (sequi); +delete virkeyboard; +delete microtonalui; +delete bankui; +delete configui; +delete sequi; -delete(presetsui);} {} +delete presetsui; +delete panelwindow; +delete selectuiwindow;} {} } Function {showUI()} {} { code {switch (config.cfg.UserInterfaceMode){ diff --git a/plugins/zynaddsubfx/src/UI/PartUI.cc b/plugins/zynaddsubfx/src/UI/PartUI.cc index 986b11995..f25571165 100644 --- a/plugins/zynaddsubfx/src/UI/PartUI.cc +++ b/plugins/zynaddsubfx/src/UI/PartUI.cc @@ -38,7 +38,7 @@ Fl_Group* PartSysEffSend::make_window() { o->when(FL_WHEN_CHANGED); o->size(25,25); o->value(master->Psysefxvol[neff][npart]); - char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp)); + char tmp[10];snprintf(tmp,10,"%d",neff+1);o->copy_label(tmp); } // WidgetPDial* o syseffsend->end(); } // Fl_Group* syseffsend @@ -333,7 +333,7 @@ Fl_Group* PartKitItem::make_window() { enabledcheck->labelsize(13); enabledcheck->callback((Fl_Callback*)cb_enabledcheck); enabledcheck->align(Fl_Align(FL_ALIGN_LEFT)); - snprintf(label,10,"%d",n+1);o->label(strdup(label)); + snprintf(label,10,"%d",n+1);o->label(label); o->value(part->kit[n].Penabled); if (n==0) o->deactivate(); } // Fl_Check_Button* enabledcheck diff --git a/plugins/zynaddsubfx/src/UI/PartUI.fl b/plugins/zynaddsubfx/src/UI/PartUI.fl index 05fe5151a..fcf15f0e4 100644 --- a/plugins/zynaddsubfx/src/UI/PartUI.fl +++ b/plugins/zynaddsubfx/src/UI/PartUI.fl @@ -56,7 +56,7 @@ class PartSysEffSend {: {public Fl_Group} xywh {0 0 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 130 maximum 127 step 1 code0 {o->size(25,25);} code1 {o->value(master->Psysefxvol[neff][npart]);} - code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp));} + code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->copy_label(tmp);} class WidgetPDial } } @@ -212,7 +212,7 @@ o->redraw(); partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 } else o->value(1);} private xywh {30 0 20 15} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 4 - code0 {snprintf(label,10,"%d",n+1);o->label(strdup(label));} + code0 {snprintf(label,10,"%d",n+1);o->label(label);} code1 {o->value(part->kit[n].Penabled);} code2 {if (n==0) o->deactivate();} } @@ -590,7 +590,7 @@ part->ctl.portamento.updowntimestretch=x;} } Fl_Dial proptb { label {Prp.Dpth} - callback {part->ctl.portamento.propDepth=(int) o->value();} selected + callback {part->ctl.portamento.propDepth=(int) o->value();} tooltip {The difference from nonproportinal portamento} xywh {405 60 25 25} labelsize 9 maximum 127 step 1 code0 {o->value(part->ctl.portamento.propDepth);} class WidgetPDial @@ -841,7 +841,7 @@ if (part->Pkitmode==0) { } } Fl_Window instrumenteditwindow { - label {Instrument Edit} + label {Instrument Edit} selected xywh {182 214 395 360} type Double hide } { Fl_Group {} { diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc index 49491ff62..25df926ad 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc @@ -486,6 +486,10 @@ midictl=75; make_window(); } +VirKeyboard::~VirKeyboard() { + delete virkeyboardwindow; +} + void VirKeyboard::show() { virkeyboardwindow->show(); } diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl index 0b83b5b56..37fe43e5c 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl @@ -41,9 +41,9 @@ decl {const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u decl {const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0};} {} -decl {const int keysoct1az[]={'a',233,'z','\\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0};} {} +decl {const int keysoct1az[]={'a',233,'z','\\"','e','r','(','t','-','y',232,'u','i',231,'o',224,'p',65106,'=','$',0};} {} -decl {const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0};} {} +decl {const int keysoct2az[]={'w','s','x','d','c','v','g','b','h','n','j',',',';','l',':','m','!',0};} {} class VirKeys {: {public Fl_Box} } { @@ -184,8 +184,7 @@ if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ return(1);} {} } - Function {presskey(int nk,int exclusive,int type)} {selected - } { + Function {presskey(int nk,int exclusive,int type)} {} { code {//Exclusive means that multiple keys can be pressed at once //when the user uses the shift key if (nk>=N_OCT*12) return; @@ -410,6 +409,10 @@ virkeys->take_focus();} open midictl=75; make_window();} {} } + Function {~VirKeyboard()} {} { + code {delete virkeyboardwindow;} {selected + } + } Function {show()} {} { code {virkeyboardwindow->show();} {} } diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.h b/plugins/zynaddsubfx/src/UI/VirKeyboard.h index bfcec5b53..7d7e7b95e 100644 --- a/plugins/zynaddsubfx/src/UI/VirKeyboard.h +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.h @@ -80,6 +80,7 @@ private: static void cb_partrcv(Fl_Choice*, void*); public: VirKeyboard(Master *master_); + ~VirKeyboard(); void show(); void relaseallkeys(); private: diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.cc b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc index bd1d43653..dde9e8854 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.cc +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc @@ -33,7 +33,8 @@ textmode=false; } void TipWin::setText(const char * c) { - strcpy(text,c); + strncpy(text, c, max_tooltip_len-1); +text[max_tooltip_len-1] = 0; textmode=true; // Recalc size of window fl_font(labelfont(), labelsize()); diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.fl b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl index 0fed5b571..f68a96ec3 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.fl +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0109 +version 1.0107 header_name {.h} code_name {.cc} decl {//Copyright (c) 2003-2005 Nasca Octavian Paul} {} @@ -61,7 +61,8 @@ textmode=false; } Function {setText(const char * c)} {return_type void } { - code {strcpy(text,c); + code {strncpy(text, c, max_tooltip_len-1); +text[max_tooltip_len-1] = 0; textmode=true; // Recalc size of window fl_font(labelfont(), labelsize()); @@ -84,7 +85,9 @@ textmode=true; } decl {char tip[40];} {} decl {bool textmode;} {} - decl {char text[400];//bad stuff will happen if too much is put in this (perhaps dynamically allocate?)} {} + decl {enum { max_tooltip_len = 400 };} {selected + } + decl {char text[max_tooltip_len];} {} } class WidgetPDial {: {public Fl_Dial} @@ -153,8 +156,7 @@ case FL_RELEASE: return(1); break; }; -return(0);} {selected - } +return(0);} {} } Function {drawgradient(int cx,int cy,int sx,double m1,double m2)} {return_type void } { diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.h b/plugins/zynaddsubfx/src/UI/WidgetPDial.h index 7f9759c1e..e81f17e18 100644 --- a/plugins/zynaddsubfx/src/UI/WidgetPDial.h +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.h @@ -22,7 +22,8 @@ public: private: char tip[40]; bool textmode; - char text[400]; //bad stuff will happen if too much is put in this (perhaps dynamically allocate?) + enum { max_tooltip_len = 400 }; + char text[max_tooltip_len]; }; class WidgetPDial : public Fl_Dial { diff --git a/plugins/zynaddsubfx/src/globals.h b/plugins/zynaddsubfx/src/globals.h index f13da7d95..7c0717168 100644 --- a/plugins/zynaddsubfx/src/globals.h +++ b/plugins/zynaddsubfx/src/globals.h @@ -29,10 +29,10 @@ #define REALTYPE float struct FFTFREQS { - REALTYPE *s,*c;//sine and cosine components + REALTYPE *s, *c; //sine and cosine components }; -extern void newFFTFREQS(FFTFREQS *f,int size); +extern void newFFTFREQS(FFTFREQS *f, int size); extern void deleteFFTFREQS(FFTFREQS *f); /**Sampling rate*/ @@ -131,7 +131,7 @@ extern int OSCIL_SIZE; * The maximum number of bands of the equaliser */ #define MAX_EQ_BANDS 8 -#if (MAX_EQ_BANDS>=20) +#if (MAX_EQ_BANDS >= 20) #error "Too many EQ bands in globals.h" #endif @@ -162,46 +162,67 @@ extern int OSCIL_SIZE; /* * How the amplitude threshold is computed */ -#define ABOVE_AMPLITUDE_THRESHOLD(a,b) ( ( 2.0*fabs( (b) - (a) ) / \ - ( fabs( (b) + (a) + 0.0000000001) ) ) > AMPLITUDE_INTERPOLATION_THRESHOLD ) +#define ABOVE_AMPLITUDE_THRESHOLD(a, b) ((2.0 * fabs((b) - (a)) \ + / (fabs((b) + (a) + 0.0000000001))) > \ + AMPLITUDE_INTERPOLATION_THRESHOLD) /* * Interpolate Amplitude */ -#define INTERPOLATE_AMPLITUDE(a,b,x,size) ( (a) + \ - ( (b) - (a) ) * (REALTYPE)(x) / (REALTYPE) (size) ) +#define INTERPOLATE_AMPLITUDE(a, b, x, size) ((a) \ + + ((b) \ + - (a)) * (REALTYPE)(x) \ + / (REALTYPE) (size)) /* * dB */ -#define dB2rap(dB) ((exp((dB)*LOG_10/20.0))) -#define rap2dB(rap) ((20*log(rap)/LOG_10)) +#define dB2rap(dB) ((exp((dB) * LOG_10 / 20.0))) +#define rap2dB(rap) ((20 * log(rap) / LOG_10)) /* * The random generator (0.0..1.0) */ -#define RND (rand()/(RAND_MAX+1.0)) +#define RND (rand() / (RAND_MAX + 1.0)) -#define ZERO(data,size) {char *data_=(char *) data;for (int i=0;i0) ? ( (int)(f) ) :( (int)(f-1.0) )); +#define F2I(f, i) (i) = ((f > 0) ? ((int)(f)) : ((int)(f - 1.0))); #endif diff --git a/src/core/LocalResourceProvider.cpp b/src/core/LocalResourceProvider.cpp index 447ccbb4d..f017f2be6 100644 --- a/src/core/LocalResourceProvider.cpp +++ b/src/core/LocalResourceProvider.cpp @@ -22,7 +22,7 @@ * */ - +#include #include #include "LocalResourceProvider.h" @@ -45,6 +45,8 @@ LocalResourceProvider::LocalResourceProvider( connect( database(), SIGNAL( directoryItemRemoved( const QString & ) ), this, SLOT( removeDirectory( const QString & ) ) ); + m_watcher.addPath( ResourceItem::getBaseDirectory( m_baseDir ) + m_dir ); + database()->init(); } @@ -120,23 +122,30 @@ void LocalResourceProvider::reloadDirectory( const QString & _path ) p += QDir::separator(); } - foreach( ResourceItem * it, database()->items() ) + if( p == ResourceItem::getBaseDirectory( m_baseDir ) + m_dir ) { - if( it->type() == ResourceItem::TypeDirectory && - it->fullName() == p ) - { - dirRelation = it->relation(); - } + updateDatabase(); } - - if( dirRelation ) + else { - ResourceItem * dirItem = dirRelation->item(); - if( dirItem ) + foreach( ResourceItem * it, database()->items() ) { - m_scannedFolders.clear(); - readDir( dirItem->fullRelativeName(), - dirRelation->parent() ); + if( it->type() == ResourceItem::TypeDirectory && + it->fullName() == p ) + { + dirRelation = it->relation(); + } + } + + if( dirRelation ) + { + ResourceItem * dirItem = dirRelation->item(); + if( dirItem ) + { + m_scannedFolders.clear(); + readDir( dirItem->fullRelativeName(), + dirRelation->parent() ); + } } } @@ -165,7 +174,7 @@ void LocalResourceProvider::readDir( const QString & _dir, ResourceItem::Relation * curParent = _parent->findChild( d.dirName() + QDir::separator(), m_baseDir ); -printf("read dir: %s\n", d.canonicalPath().toUtf8().constData() ); +qDebug() << "read dir" << d.canonicalPath(); if( curParent ) { parentItem = curParent->item(); @@ -202,6 +211,7 @@ printf("read dir: %s\n", d.canonicalPath().toUtf8().constData() ); { if( f.isSymLink() ) { + qDebug() << "following symlink" << f.canonicalFilePath() << "to" << f.symLinkTarget(); f = QFileInfo( f.symLinkTarget() ); } @@ -268,7 +278,7 @@ printf("read dir: %s\n", d.canonicalPath().toUtf8().constData() ); { ResourceItem::Relation * item = *it; it = curParent->children().erase( it ); - database()->recursiveRemoveItems( item ); + database()->removeItemsRecursively( item ); } else { diff --git a/src/core/ResourceAction.cpp b/src/core/ResourceAction.cpp index 9d747c421..428234e25 100644 --- a/src/core/ResourceAction.cpp +++ b/src/core/ResourceAction.cpp @@ -98,6 +98,21 @@ bool ResourceAction::importProject( trackContainer * _target ) +bool ResourceAction::defaultTrigger() +{ + switch( m_action ) + { + case LoadProject: + return loadProject(); + case ImportFile: + return importProject( engine::getSong() ); + default: + break; + } + return false; +} + + #include "moc_ResourceAction.cxx" diff --git a/src/core/ResourceDB.cpp b/src/core/ResourceDB.cpp index 5d9d285e7..3d91f7897 100644 --- a/src/core/ResourceDB.cpp +++ b/src/core/ResourceDB.cpp @@ -98,7 +98,7 @@ void ResourceDB::init() void ResourceDB::load( const QString & _file ) { - recursiveRemoveItems( topLevelNode(), false ); + removeItemsRecursively( topLevelNode(), false ); multimediaProject m( _file ); @@ -283,7 +283,7 @@ void ResourceDB::addItem( ResourceItem * newItem ) ResourceItem::Relation * oldRelation = oldItem->relation(); if( oldRelation ) { - recursiveRemoveItems( oldRelation, false ); + removeItemsRecursively( oldRelation, false ); delete oldRelation; } if( oldItem->type() == ResourceItem::TypeDirectory ) @@ -299,8 +299,8 @@ void ResourceDB::addItem( ResourceItem * newItem ) -void ResourceDB::recursiveRemoveItems( ResourceItem::Relation * parent, - bool removeTopLevelParent ) +void ResourceDB::removeItemsRecursively( ResourceItem::Relation * parent, + bool removeParent ) { if( !parent ) { @@ -309,10 +309,10 @@ void ResourceDB::recursiveRemoveItems( ResourceItem::Relation * parent, while( !parent->children().isEmpty() ) { - recursiveRemoveItems( parent->children().front() ); + removeItemsRecursively( parent->children().front() ); } - if( removeTopLevelParent && parent->item() ) + if( removeParent && parent->item() ) { if( parent->item()->type() == ResourceItem::TypeDirectory ) { diff --git a/src/core/audio/AudioPulseAudio.cpp b/src/core/audio/AudioPulseAudio.cpp index 03edd6612..539b1fba5 100644 --- a/src/core/audio/AudioPulseAudio.cpp +++ b/src/core/audio/AudioPulseAudio.cpp @@ -35,6 +35,7 @@ #include "gui_templates.h" #include "templates.h" #include "Cpu.h" +#include "engine.h" static void stream_write_callback(pa_stream *s, size_t length, void *userdata) @@ -51,6 +52,7 @@ AudioPulseAudio::AudioPulseAudio( bool & _success_ful, mixer * _mixer ) : DEFAULT_CHANNELS, SURROUND_CHANNELS ), _mixer ), m_s( NULL ), + m_quit( false ), m_convertEndian( false ) { _success_ful = false; @@ -68,11 +70,6 @@ AudioPulseAudio::AudioPulseAudio( bool & _success_ful, mixer * _mixer ) : AudioPulseAudio::~AudioPulseAudio() { stopProcessing(); - - if( m_s != NULL ) - { - pa_stream_unref( m_s ); - } } @@ -173,11 +170,29 @@ static void context_state_callback(pa_context *c, void *userdata) _this->m_s = pa_stream_new( c, "lmms", &_this->m_sampleSpec, NULL); pa_stream_set_state_callback( _this->m_s, stream_state_callback, _this ); pa_stream_set_write_callback( _this->m_s, stream_write_callback, _this ); - pa_stream_connect_playback( _this->m_s, NULL, NULL, - (pa_stream_flags) 0, - pa_cvolume_set( &cv, _this->m_sampleSpec.channels, - PA_VOLUME_NORM ), - NULL ); + + pa_buffer_attr buffer_attr; + + buffer_attr.maxlength = (uint32_t)(-1); + + // play silence in case of buffer underun instead of using default rewind + buffer_attr.prebuf = 0; + + buffer_attr.minreq = (uint32_t)(-1); + buffer_attr.fragsize = (uint32_t)(-1); + + double latency = (double)( engine::getMixer()->framesPerPeriod() ) / + (double)_this->sampleRate(); + + // ask PulseAudio for the desired latency (which might not be approved) + buffer_attr.tlength = pa_usec_to_bytes( latency * PA_USEC_PER_MSEC, + &_this->m_sampleSpec ); + + pa_stream_connect_playback( _this->m_s, NULL, &buffer_attr, + PA_STREAM_ADJUST_LATENCY, + pa_cvolume_set( &cv, _this->m_sampleSpec.channels, + PA_VOLUME_NORM ), + NULL ); break; } @@ -195,51 +210,59 @@ static void context_state_callback(pa_context *c, void *userdata) void AudioPulseAudio::run() { - pa_mainloop * m = NULL; - - - if (!(m = pa_mainloop_new())) { + pa_mainloop * mainLoop = pa_mainloop_new(); + if( !mainLoop ) + { qCritical( "pa_mainloop_new() failed.\n" ); return; } - pa_mainloop_api * mainloop_api = pa_mainloop_get_api(m); + pa_mainloop_api * mainloop_api = pa_mainloop_get_api( mainLoop ); - pa_context *context = pa_context_new(mainloop_api, "lmms"); + pa_context *context = pa_context_new( mainloop_api, "lmms" ); if ( context == NULL ) { - qCritical( "pa_context_new() failed." ); + qCritical( "pa_context_new() failed." ); return; } - pa_context_set_state_callback(context, context_state_callback, this ); - /* Connect the context */ - pa_context_connect(context, NULL, (pa_context_flags) 0, NULL); + pa_context_set_state_callback( context, context_state_callback, this ); + // connect the context + pa_context_connect( context, NULL, (pa_context_flags) 0, NULL ); - int ret; - /* Run the main loop */ - if (pa_mainloop_run(m, &ret) < 0) + // run the main loop + int ret = 0; + m_quit = false; + while( m_quit == false && pa_mainloop_iterate( mainLoop, 1, &ret ) >= 0 ) { - qCritical( "pa_mainloop_run() failed.\n" ); } + + pa_stream_disconnect( m_s ); + pa_stream_unref( m_s ); + + pa_context_disconnect( context ); + pa_context_unref( context ); + + pa_mainloop_free( mainLoop ); } -void AudioPulseAudio::streamWriteCallback(pa_stream *s, size_t length) +void AudioPulseAudio::streamWriteCallback( pa_stream *s, size_t length ) { const fpp_t fpp = getMixer()->framesPerPeriod(); sampleFrameA * temp = CPU::allocFrames( fpp ); - Sint16 * pcmbuf = (Sint16*)pa_xmalloc( fpp * channels() * + Sint16 * pcmbuf = (Sint16*)CPU::memAlloc( fpp * channels() * sizeof(Sint16) ); size_t fd = 0; - while( fd < length/4 ) + while( fd < length/4 && m_quit == false ) { const fpp_t frames = getNextBuffer( temp ); if( !frames ) { - return; + m_quit = true; + break; } int bytes = CPU::convertToS16( temp, (intSampleFrameA *) pcmbuf, @@ -254,7 +277,7 @@ void AudioPulseAudio::streamWriteCallback(pa_stream *s, size_t length) fd += frames; } - pa_xfree( pcmbuf ); + CPU::memFree( pcmbuf ); CPU::freeFrames( temp ); } diff --git a/src/core/main.cpp b/src/core/main.cpp index b91c15653..41227025f 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -458,6 +458,9 @@ int main( int argc, char * * argv ) engine::mainWindow()->showMaximized(); } engine::getSong()->loadProject( file_to_load ); + + // don't show welcome screen + engine::mainWindow()->showWelcomeScreen( false ); } else if( !file_to_import.isEmpty() ) { @@ -472,6 +475,9 @@ int main( int argc, char * * argv ) { engine::mainWindow()->showMaximized(); } + + // don't show welcome screen + engine::mainWindow()->showWelcomeScreen( false ); } else { @@ -484,6 +490,9 @@ int main( int argc, char * * argv ) { engine::mainWindow()->showMaximized(); } + + // show welcome screen + engine::mainWindow()->showWelcomeScreen(); } } else @@ -519,9 +528,7 @@ int main( int argc, char * * argv ) } } - const int ret = app->exec(); - delete app; - return( ret ); + return app->exec(); } diff --git a/src/gui/DirectorySelectDialog.cpp b/src/gui/DirectorySelectDialog.cpp new file mode 100644 index 000000000..d304555fa --- /dev/null +++ b/src/gui/DirectorySelectDialog.cpp @@ -0,0 +1,50 @@ +/* + * DirectorySelectDialog.cpp - implementation of DirectorySelectDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "DirectorySelectDialog.h" + +#include "ui_DirectorySelectDialog.h" + + +DirectorySelectDialog::DirectorySelectDialog( QWidget * _parent, + DatabaseScope _databaseScope ) : + ResourceSelectDialog( _parent, ResourceSelectDialog::TreeModel, + _databaseScope ), + ui( new Ui::DirectorySelectDialog ) +{ + // setup form + ui->setupUi( this ); + + // setup ResourceSelectDialog + setupUi(); +} + + + + +DirectorySelectDialog::~DirectorySelectDialog() +{ +} + + diff --git a/src/gui/Forms/DirectorySelectDialog.ui b/src/gui/Forms/DirectorySelectDialog.ui new file mode 100644 index 000000000..23975f7b5 --- /dev/null +++ b/src/gui/Forms/DirectorySelectDialog.ui @@ -0,0 +1,89 @@ + + + DirectorySelectDialog + + + + 0 + 0 + 465 + 546 + + + + Select directory + + + + + + + + + QAbstractItemView::ScrollPerPixel + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + ResourceTreeView + QTreeView +

ResourceTreeView.h
+ + + + filterEdit + resourceTreeView + buttonBox + + + + + buttonBox + accepted() + DirectorySelectDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + DirectorySelectDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/gui/Forms/PreferencesDialog.ui b/src/gui/Forms/PreferencesDialog.ui new file mode 100644 index 000000000..f9df36a99 --- /dev/null +++ b/src/gui/Forms/PreferencesDialog.ui @@ -0,0 +1,776 @@ + + + PreferencesDialog + + + + 0 + 0 + 577 + 478 + + + + Preferences + + + + + + + + + + 0 + 0 + + + + + 101 + 470 + + + + + 101 + 16777215 + + + + ::item { width:87; } + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + 64 + 64 + + + + 4 + + + QListView::IconMode + + + -1 + + + + General + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Directories + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Audio + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + MIDI + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Plugins + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + + + + 0 + + + + + 16 + + + + + + 14 + 75 + true + + + + General settings + + + + + + + User interface + + + + + + Enable tooltips + + + + + + + Show volume as dbV + + + + + + + Show welcome screen + + + + + + + + + + Online resources + + + + 10 + + + + + Enable online resources + + + + + + + Enable uploads + + + + + + + Username + + + + + + + false + + + + + + + Password + + + + + + + false + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 16 + + + + + + 14 + 75 + true + + + + Audio settings + + + + + + + General + + + + 10 + + + 10 + + + + + Buffer size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Sample rate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 44100 Hz + + + + + 48000 Hz + + + + + 88200 Hz + + + + + 96000 Hz + + + + + + + + + 0 + 0 + + + + 3 + + + + 32 + + + + + 64 + + + + + 128 + + + + + 256 (default) + + + + + 512 + + + + + 1024 + + + + + 2048 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Audio engine + + + + 10 + + + 10 + + + + + Audio engine + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + Device + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + 16 + + + + + + 14 + 75 + true + + + + MIDI settings + + + + + + + MIDI engine + + + + 10 + + + 10 + + + + + MIDI engine + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + Device + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + + 0 + 100 + + + + MIDI remote control + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 16 + + + + + + 14 + 75 + true + + + + Plugins settings + + + + + + + + 24 + 24 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + PreferencesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + PreferencesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + enableUploadsCheckBox + toggled(bool) + usernameEdit + setEnabled(bool) + + + 299 + 253 + + + 336 + 283 + + + + + enableUploadsCheckBox + toggled(bool) + passwordEdit + setEnabled(bool) + + + 299 + 253 + + + 336 + 317 + + + + + enableOnlineResourcesCheckBox + toggled(bool) + enableUploadsCheckBox + setEnabled(bool) + + + 299 + 226 + + + 299 + 253 + + + + + configPageSelector + currentRowChanged(int) + configPages + setCurrentIndex(int) + + + 54 + 238 + + + 340 + 224 + + + + + diff --git a/src/gui/Forms/WelcomeScreen.ui b/src/gui/Forms/WelcomeScreen.ui index ad366c872..64e51378d 100644 --- a/src/gui/Forms/WelcomeScreen.ui +++ b/src/gui/Forms/WelcomeScreen.ui @@ -356,6 +356,9 @@ p, li { white-space: pre-wrap; } Qt::ScrollBarAlwaysOff + + Qt::ScrollBarAlwaysOff + 16 @@ -375,6 +378,9 @@ p, li { white-space: pre-wrap; } Qt::ScrollBarAlwaysOff + + Qt::ScrollBarAlwaysOff + 16 diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index a12e0eded..453193dbd 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -51,9 +51,10 @@ #include "engine.h" #include "FxMixerView.h" #include "AboutDialog.h" +#include "PreferencesDialog.h" #include "ControllerRackView.h" #include "plugin_browser.h" -#include "side_bar.h" +#include "SideBar.h" #include "config_mgr.h" #include "mixer.h" #include "project_notes.h" @@ -92,26 +93,22 @@ MainWindow::MainWindow() : vbox->setSpacing( 0 ); vbox->setMargin( 0 ); - QWidget * w = new QWidget( m_mainWidget ); QHBoxLayout * hbox = new QHBoxLayout( w ); hbox->setSpacing( 0 ); hbox->setMargin( 0 ); - sideBar * side_bar = new sideBar( sideBar::Vertical, w ); - side_bar->setStyle( sideBar::VSNET/*KDEV3ICON*/ ); - side_bar->setPosition( sideBar::Left ); + SideBar * sideBar = new SideBar( Qt::Vertical, w ); QSplitter * splitter = new QSplitter( Qt::Horizontal, w ); splitter->setChildrenCollapsible( false ); - int id = 0; QString wdir = configManager::inst()->workingDir(); - side_bar->appendTab( new pluginBrowser( splitter ), ++id ); + sideBar->appendTab( new pluginBrowser( splitter ) ); // add a resource browser to sidebar m_resourceBrowser = new ResourceBrowser( splitter ); - side_bar->appendTab( m_resourceBrowser, ++id ); + sideBar->appendTab( m_resourceBrowser ); m_workspace = new QMdiArea( splitter ); @@ -136,7 +133,7 @@ MainWindow::MainWindow() : m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); - hbox->addWidget( side_bar ); + hbox->addWidget( sideBar ); hbox->addWidget( splitter ); @@ -155,17 +152,14 @@ MainWindow::MainWindow() : vbox->addWidget( m_toolBar ); vbox->addWidget( w ); + m_updateTimer.start( 1000 / 20, this ); // 20 fps m_welcomeScreen = new WelcomeScreen( this ); - - setCentralWidget( m_welcomeScreen ); - - m_updateTimer.start( 1000 / 20, this ); // 20 fps + m_welcomeScreen->setVisible( false ); } - MainWindow::~MainWindow() { for( QList::Iterator it = m_tools.begin(); @@ -185,15 +179,14 @@ MainWindow::~MainWindow() - -void MainWindow::setMainWidgetVisible( bool _visible ) +void MainWindow::showWelcomeScreen(bool _visible) { - setCentralWidget( _visible ? m_mainWidget : m_welcomeScreen ); + m_welcomeScreen->setVisible( _visible ); + setCentralWidget( _visible ? m_welcomeScreen : m_mainWidget ); } - void MainWindow::finalize() { resetWindowTitle(); @@ -265,6 +258,10 @@ void MainWindow::finalize() edit_menu->addAction( embed::getIconPixmap( "setup_general" ), tr( "Settings" ), this, SLOT( showSettingsDialog() ) ); + edit_menu->addSeparator(); + edit_menu->addAction( embed::getIconPixmap( "setup_general" ), + tr( "Preferences (premature dialog)" ), + this, SLOT( showPreferencesDialog() ) ); m_toolsMenu = new QMenu( this ); @@ -315,8 +312,7 @@ void MainWindow::finalize() // create the grid layout for the first buttons area QWidget * gridButtons_w = new QWidget( m_toolBar ); - QGridLayout * gridButtons_layout = new QGridLayout( gridButtons_w/*, 2, 1*/ ); - + QGridLayout * gridButtons_layout = new QGridLayout( gridButtons_w ); // create tool-buttons toolButton * project_new = new toolButton( @@ -1059,6 +1055,14 @@ void MainWindow::showSettingsDialog() +void MainWindow::showPreferencesDialog() +{ + PreferencesDialog().exec(); +} + + + + void MainWindow::aboutLMMS() { AboutDialog().exec(); @@ -1200,6 +1204,12 @@ void MainWindow::closeEvent( QCloseEvent * _ce ) } +void MainWindow::showEvent( QShowEvent * _se ) +{ + //showWelcomeScreen( false ); // must explicitly ask for welcome screen + _se->accept(); +} + void MainWindow::focusOutEvent( QFocusEvent * _fe ) diff --git a/src/gui/PreferencesDialog.cpp b/src/gui/PreferencesDialog.cpp new file mode 100644 index 000000000..6214051f8 --- /dev/null +++ b/src/gui/PreferencesDialog.cpp @@ -0,0 +1,55 @@ +/* + * PreferencesDialog.cpp - implementation of PreferencesDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "PreferencesDialog.h" +#include "embed.h" +#include "engine.h" +#include "MainWindow.h" +#include "ui_PreferencesDialog.h" + + +PreferencesDialog::PreferencesDialog() : + QDialog( engine::mainWindow() ), + ui( new Ui::PreferencesDialog ) +{ + ui->setupUi( this ); + + // set up icons in page selector view on the left side + static const char * icons[] = { + "preferences-system", + "folder-64", + "preferences-desktop-sound", + "setup-midi", + "setup-plugins" + } ; + for( int i = 0; i < qMin( sizeof( icons ), + ui->configPageSelector->count() ); ++i ) + { + ui->configPageSelector->item( i )->setIcon( + embed::getIconPixmap( icons[i] ) ); + } +} + + + diff --git a/src/gui/QuickLoadDialog.cpp b/src/gui/QuickLoadDialog.cpp index aab67def6..7e64d6641 100644 --- a/src/gui/QuickLoadDialog.cpp +++ b/src/gui/QuickLoadDialog.cpp @@ -23,21 +23,23 @@ */ #include "QuickLoadDialog.h" -#include "ResourceListModel.h" -#include "engine.h" #include "ui_QuickLoadDialog.h" - QuickLoadDialog::QuickLoadDialog( QWidget * _parent, - ResourceItem::Type _typeFilter ) : - QDialog( _parent ), - ui( new Ui::QuickLoadDialog ), - m_listModel( new ResourceListModel( engine::mergedResourceDB(), this ) ) + ResourceItem::Type _typeFilter, + DatabaseScope _databaseScope ) : + ResourceSelectDialog( _parent, ResourceSelectDialog::ListModel, + _databaseScope ), + ui( new Ui::QuickLoadDialog ) { + // setup form ui->setupUi( this ); + // setup ResourceSelectDialog + setupUi(); + // setup type combobox + type filtering for( int i = ResourceItem::TypeUnknown+1; i < ResourceItem::NumTypes; ++i ) { @@ -53,16 +55,6 @@ QuickLoadDialog::QuickLoadDialog( QWidget * _parent, { ui->resourceTypeComboBox->setCurrentIndex( _typeFilter ); } - - // setup list view to display our model - ui->resourceListView->setModel( m_listModel ); - ui->resourceListView->selectionModel()->select( - m_listModel->index( 0, 0 ), - QItemSelectionModel::SelectCurrent ); - - // connect filter edit with model - connect( ui->filterEdit, SIGNAL( textChanged( const QString & ) ), - m_listModel, SLOT( setKeywordFilter( const QString & ) ) ); } @@ -70,18 +62,6 @@ QuickLoadDialog::QuickLoadDialog( QWidget * _parent, QuickLoadDialog::~QuickLoadDialog() { - delete m_listModel; } - - -void QuickLoadDialog::setTypeFilter( int _type ) -{ - m_listModel->setTypeFilter( static_cast( _type ) ); -} - - - -#include "moc_QuickLoadDialog.cxx" - diff --git a/src/gui/ResourceBrowser.cpp b/src/gui/ResourceBrowser.cpp index 2be9e848b..c53f50a44 100644 --- a/src/gui/ResourceBrowser.cpp +++ b/src/gui/ResourceBrowser.cpp @@ -43,30 +43,30 @@ struct ActionDesc { - ResourceBrowser::Actions action; + ResourceAction::Action action; const char * pixmap; const char * text; } ; static ActionDesc resourceBrowserActions[] = { - { ResourceBrowser::EditProperties, "edit_draw", + { ResourceAction::EditProperties, "edit_draw", QT_TRANSLATE_NOOP( "ResourceBrowser", "Show/edit properties" ) }, - { ResourceBrowser::LoadProject, "project_open", + { ResourceAction::LoadProject, "project_open", QT_TRANSLATE_NOOP( "ResourceBrowser", "Load project" ) }, - { ResourceBrowser::LoadInNewTrackSongEditor, "songeditor", + { ResourceAction::LoadInNewTrackSongEditor, "songeditor", QT_TRANSLATE_NOOP( "ResourceBrowser", "Load in new track in Song Editor" ) }, - { ResourceBrowser::LoadInNewTrackBBEditor, "bb_track", + { ResourceAction::LoadInNewTrackBBEditor, "bb_track", QT_TRANSLATE_NOOP( "ResourceBrowser", "Load in new track in B+B Editor" ) }, - { ResourceBrowser::LoadInActiveInstrumentTrack, "instrument_track", + { ResourceAction::LoadInActiveInstrumentTrack, "instrument_track", QT_TRANSLATE_NOOP( "ResourceBrowser", "Load into active instrument track" ) }, - { ResourceBrowser::DownloadIntoCollection, "mimetypes/folder-downloads", + { ResourceAction::DownloadIntoCollection, "mimetypes/folder-downloads", QT_TRANSLATE_NOOP( "ResourceBrowser", "Download into collection" ) }, - { ResourceBrowser::UploadToWWW, "mimetypes/network-workgroup", + { ResourceAction::UploadToWWW, "mimetypes/network-workgroup", QT_TRANSLATE_NOOP( "ResourceBrowser", "Upload to WWW" ) }, - { ResourceBrowser::DeleteLocalResource, "edit-delete", + { ResourceAction::DeleteLocalResource, "edit-delete", QT_TRANSLATE_NOOP( "ResourceBrowser", "Delete resource" ) }, - { ResourceBrowser::ImportFile, "project_import", + { ResourceAction::ImportFile, "project_import", QT_TRANSLATE_NOOP( "ResourceBrowser", "Import file" ) } } ; @@ -74,7 +74,7 @@ static ActionDesc resourceBrowserActions[] = ResourceBrowser::ResourceBrowser( QWidget * _parent ) : - sideBarWidget( tr( "Resource Browser" ), + SideBarWidget( tr( "Resource Browser" ), embed::getIconPixmap( "resource_browser" ), _parent ), m_previewer(), @@ -98,7 +98,7 @@ ResourceBrowser::ResourceBrowser( QWidget * _parent ) : filterLayout->addWidget( m_filterStatusLabel ); // create an according tree-view for our tree-model - m_treeView = new ResourceTreeView( &m_treeModel, contentParent() ); + m_treeView = new ResourceTreeView( contentParent(), &m_treeModel ); // set up context menu handling m_treeView->setContextMenuPolicy( Qt::CustomContextMenu ); @@ -167,7 +167,7 @@ ResourceBrowser::ResourceBrowser( QWidget * _parent ) : for( int i = 0; i < (int) ( sizeof( resourceBrowserActions ) / sizeof( ActionDesc ) ); ++i ) { - Actions a = resourceBrowserActions[i].action; + ResourceAction::Action a = resourceBrowserActions[i].action; m_actions[a] = new QAction( embed::getIconPixmap( resourceBrowserActions[i].pixmap ), @@ -211,16 +211,16 @@ void ResourceBrowser::showContextMenu( const QPoint & _pos ) case ResourceItem::TypePreset: case ResourceItem::TypePluginSpecificResource: case ResourceItem::TypePlugin: - m.addAction( m_actions[LoadInNewTrackSongEditor] ); - m.addAction( m_actions[LoadInNewTrackBBEditor] ); - m.addAction( m_actions[LoadInActiveInstrumentTrack] ); + m.addAction( m_actions[ResourceAction::LoadInNewTrackSongEditor] ); + m.addAction( m_actions[ResourceAction::LoadInNewTrackBBEditor] ); + m.addAction( m_actions[ResourceAction::LoadInActiveInstrumentTrack] ); break; case ResourceItem::TypeProject: - m.addAction( m_actions[LoadProject] ); + m.addAction( m_actions[ResourceAction::LoadProject] ); break; case ResourceItem::TypeForeignProject: case ResourceItem::TypeMidiFile: - m.addAction( m_actions[ImportFile] ); + m.addAction( m_actions[ResourceAction::ImportFile] ); break; case ResourceItem::TypeImage: case ResourceItem::TypeDirectory: @@ -234,25 +234,25 @@ void ResourceBrowser::showContextMenu( const QPoint & _pos ) m.addSeparator(); if( item->isLocalResource() ) { - m.addAction( m_actions[DeleteLocalResource] ); - m.addAction( m_actions[UploadToWWW] ); + m.addAction( m_actions[ResourceAction::DeleteLocalResource] ); + m.addAction( m_actions[ResourceAction::UploadToWWW] ); } else { - m.addAction( m_actions[DownloadIntoCollection] ); + m.addAction( m_actions[ResourceAction::DownloadIntoCollection] ); } } m.addSeparator(); - m.addAction( m_actions[EditProperties] ); + m.addAction( m_actions[ResourceAction::EditProperties] ); // show and exec menu QAction * a = m.exec( m_treeView->mapToGlobal( _pos ) ); if( a ) { // trigger action if one has been selected - triggerAction( static_cast( a->data().toInt() ), - item ); + triggerAction( static_cast( a->data().toInt() ), + item ); } } @@ -269,12 +269,14 @@ void ResourceBrowser::startItemPreview( const QModelIndex & _idx ) } + + void ResourceBrowser::setFocusAndPreview( const QModelIndex & _idx ) { // transfor focus to the treeview. for some reason you have to // setFocus to the line edit above it first. - m_filterEdit->setFocus(Qt::MouseFocusReason); - m_treeView->setFocus(Qt::MouseFocusReason); + m_filterEdit->setFocus( Qt::MouseFocusReason ); + m_treeView->setFocus( Qt::MouseFocusReason ); startItemPreview( _idx ); } @@ -291,7 +293,7 @@ void ResourceBrowser::stopItemPreview( const QModelIndex & ) void ResourceBrowser::currentChanged( const QModelIndex & current, - const QModelIndex & previous ) + const QModelIndex & previous ) { // stop previous previews @@ -299,12 +301,11 @@ void ResourceBrowser::currentChanged( const QModelIndex & current, // start previewing the sound we just changed to startItemPreview( current ); - - } + void ResourceBrowser::stopPreview() { m_previewer.stopPreview(); @@ -316,28 +317,28 @@ void ResourceBrowser::stopPreview() void ResourceBrowser::triggerDefaultAction( const QModelIndex & _idx ) { ResourceItem * item = m_treeModel.item( _idx ); - Actions action = NumActions; + ResourceAction::Action action = ResourceAction::NumActions; switch( item->type() ) { case ResourceItem::TypeSample: - action = LoadInNewTrackBBEditor; + action = ResourceAction::LoadInNewTrackBBEditor; break; case ResourceItem::TypePreset: case ResourceItem::TypePluginSpecificResource: case ResourceItem::TypePlugin: - action = LoadInNewTrackSongEditor; + action = ResourceAction::LoadInNewTrackSongEditor; break; case ResourceItem::TypeProject: - action = LoadProject; + action = ResourceAction::LoadProject; break; case ResourceItem::TypeForeignProject: case ResourceItem::TypeMidiFile: - action = ImportFile; + action = ResourceAction::ImportFile; break; default: break; } - if( action != NumActions ) + if( action != ResourceAction::NumActions ) { triggerAction( action, item ); } @@ -363,26 +364,14 @@ void ResourceBrowser::manageDirectories() -void ResourceBrowser::triggerAction( Actions _action, ResourceItem * _item ) +void ResourceBrowser::triggerAction( ResourceAction::Action _action, + ResourceItem * _item ) { + ResourceAction action( _item, _action ); switch( _action ) { - case LoadProject: - if( engine::mainWindow()->mayChangeProject() ) - { - ResourceFileMapper mapper( _item ); - if( _item->isLocalResource() ) - { - engine::getSong()->loadProject( - mapper.fileName() ); - } - else - { - engine::getSong()-> - createNewProjectFromTemplate( - mapper.fileName() ); - } - } + default: + action.defaultTrigger(); break; } } diff --git a/src/gui/ResourceSelectDialog.cpp b/src/gui/ResourceSelectDialog.cpp new file mode 100644 index 000000000..aacd1a598 --- /dev/null +++ b/src/gui/ResourceSelectDialog.cpp @@ -0,0 +1,128 @@ +/* + * ResourceSelectDialog.cpp - implementation of ResourceSelectDialog + * + * Copyright (c) 2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include + +#include "ResourceSelectDialog.h" +#include "ResourceListModel.h" +#include "ResourceTreeModel.h" +#include "engine.h" + + + +ResourceSelectDialog::ResourceSelectDialog( QWidget * _parent, + ModelTypes _modelType, + DatabaseScope _databaseScope ) : + QDialog( _parent ), + m_model( NULL ) +{ + ResourceDB * db = NULL; + switch( _databaseScope ) + { + case WorkingDirResources: + db = engine::workingDirResourceDB(); + break; + case WebResources: + db = engine::webResourceDB(); + break; + case AllResources: + default: + db = engine::mergedResourceDB(); + break; + } + + switch( _modelType ) + { + case ListModel: + m_model = new ResourceListModel( db, this ); + break; + case TreeModel: + m_model = new ResourceTreeModel( db, this ); + break; + } +} + + + + +ResourceSelectDialog::~ResourceSelectDialog() +{ + delete m_model; +} + + + + +ResourceItem * ResourceSelectDialog::selectedItem() +{ + if( result() != QDialog::Accepted ) + { + return NULL; + } + + QAbstractItemView * resourceView = findChild(); + if( !resourceView ) + { + return NULL; + } + + return m_model->item( resourceView->currentIndex() ); +} + + + + +void ResourceSelectDialog::setupUi( ) +{ + QAbstractItemView * resourceView = findChild(); + if( resourceView ) + { + // setup view to display our model + resourceView->setModel( m_model ); + resourceView->selectionModel()->select( m_model->index( 0, 0 ), + QItemSelectionModel::SelectCurrent ); + } + + QLineEdit * filterEdit = findChild(); + if( filterEdit ) + { + // connect filter edit with model + connect( filterEdit, SIGNAL( textChanged( const QString & ) ), + m_model, SLOT( setKeywordFilter( const QString & ) ) ); + } +} + + + + +void ResourceSelectDialog::setTypeFilter( int _type ) +{ + m_model->setTypeFilter( static_cast( _type ) ); +} + + + +#include "moc_ResourceSelectDialog.cxx" + diff --git a/src/gui/ResourceTreeView.cpp b/src/gui/ResourceTreeView.cpp index 91dbe9577..4844754c7 100644 --- a/src/gui/ResourceTreeView.cpp +++ b/src/gui/ResourceTreeView.cpp @@ -26,17 +26,39 @@ #include "ResourceTreeModel.h" -ResourceTreeView::ResourceTreeView( ResourceTreeModel * _tm, - QWidget * _parent ) : +ResourceTreeView::ResourceTreeView( QWidget * _parent, + ResourceTreeModel * _tm ) : QTreeView( _parent ), - m_tm( _tm ) + m_treeModel( NULL ) { setHeaderHidden( true ); setDragEnabled( true ); - setModel( m_tm ); - connect( m_tm, SIGNAL( itemsChanged() ), - this, SLOT( updateFilter() ) ); + setModel( _tm ); +} + + + + +ResourceTreeView::~ResourceTreeView() +{ +} + + + + +void ResourceTreeView::setModel( QAbstractItemModel * _model ) +{ + if( _model ) + { + m_treeModel = dynamic_cast( _model ); + if( m_treeModel ) + { + QTreeView::setModel( m_treeModel ); + connect( m_treeModel, SIGNAL( itemsChanged() ), + this, SLOT( updateFilter() ) ); + } + } } @@ -48,11 +70,11 @@ void ResourceTreeView::setFilter( const QString & _s ) if( _s.isEmpty() ) { collapseAll(); - m_tm->setKeywordFilter( _s ); + m_treeModel->setKeywordFilter( _s ); } else { - m_tm->setKeywordFilter( _s ); + m_treeModel->setKeywordFilter( _s ); expandToDepth( _s.size() ); } setUpdatesEnabled( true ); diff --git a/src/gui/WelcomeScreen.cpp b/src/gui/WelcomeScreen.cpp index 964988aeb..3b33ed976 100644 --- a/src/gui/WelcomeScreen.cpp +++ b/src/gui/WelcomeScreen.cpp @@ -112,7 +112,7 @@ WelcomeScreen::~WelcomeScreen() void WelcomeScreen::createNewProject() { - switchView(); + hideWelcomeScreen(); } @@ -141,7 +141,7 @@ void WelcomeScreen::instantMidiAction() void WelcomeScreen::openRecentProject( const QModelIndex & _idx ) { - switchView(); + hideWelcomeScreen(); ResourceAction( m_recentProjectsModel->item( _idx ) ).loadProject(); } @@ -156,7 +156,7 @@ void WelcomeScreen::openCommunityResource( const QModelIndex & _idx ) switch( item->type() ) { case ResourceItem::TypeProject: - switchView(); + hideWelcomeScreen(); action.loadProject(); break; default: @@ -177,9 +177,9 @@ void WelcomeScreen::openOnlineResource( QListWidgetItem * _item ) -void WelcomeScreen::switchView() +void WelcomeScreen::hideWelcomeScreen() { - engine::mainWindow()->setMainWidgetVisible( true ); + engine::mainWindow()->showWelcomeScreen( false ); } diff --git a/src/gui/embed.cpp b/src/gui/embed.cpp index 9c7795039..5f6c1008c 100644 --- a/src/gui/embed.cpp +++ b/src/gui/embed.cpp @@ -93,18 +93,18 @@ QPixmap getIconPixmap( const char * _name, int _w, int _h ) // Save to cache and return s_pixmapCache.insert( _name, p ); - return( p ); + return p; } - return( getIconPixmap( _name ).scaled( _w, _h, Qt::IgnoreAspectRatio, - Qt::SmoothTransformation ) ); + return getIconPixmap( _name ). + scaled( _w, _h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); } QString getText( const char * _name ) { const embed::descriptor & e = findEmbeddedData( _name ); - return( QString::fromLatin1( (const char *) e.data, e.size ) ); + return QString::fromUtf8( (const char *) e.data, e.size ); } diff --git a/src/gui/plugin_browser.cpp b/src/gui/plugin_browser.cpp index 035266357..43194d78f 100644 --- a/src/gui/plugin_browser.cpp +++ b/src/gui/plugin_browser.cpp @@ -37,7 +37,7 @@ pluginBrowser::pluginBrowser( QWidget * _parent ) : - sideBarWidget( tr( "Instrument plugins" ), + SideBarWidget( tr( "Instrument plugins" ), embed::getIconPixmap( "plugins" ), _parent ) { setWindowTitle( tr( "Instrument browser" ) ); diff --git a/src/gui/widgets/SideBar.cpp b/src/gui/widgets/SideBar.cpp new file mode 100644 index 000000000..e99e0ee08 --- /dev/null +++ b/src/gui/widgets/SideBar.cpp @@ -0,0 +1,160 @@ +/* + * SideBar.cpp - side-bar in LMMS' MainWindow + * + * Copyright (c) 2004-2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include +#include +#include + +#include "SideBar.h" +#include "SideBarWidget.h" + + +// internal helper class allowing to create QToolButtons with +// vertical orientation +class SideBarButton : public QToolButton +{ +public: + SideBarButton( Qt::Orientation _orientation, QWidget * _parent ) : + QToolButton( _parent ), + m_orientation( _orientation ) + { + } + virtual ~SideBarButton() + { + } + + Qt::Orientation orientation() const + { + return m_orientation; + } + + virtual QSize sizeHint() const + { + QSize s = QToolButton::sizeHint(); + s.setWidth( s.width() + 8 ); + if( orientation() == Qt::Horizontal ) + { + return s; + } + return QSize( s.height(), s.width() ); + } + + +protected: + virtual void paintEvent( QPaintEvent * ) + { + QStylePainter p( this ); + QStyleOptionToolButton opt; + initStyleOption( &opt ); + if( orientation() == Qt::Vertical ) + { + const QSize s = sizeHint(); + p.rotate( 270 ); + p.translate( -s.height(), 0 ); + opt.rect = QRect( 0, 0, s.height(), s.width() ); + } + p.drawComplexControl( QStyle::CC_ToolButton, opt ); + } + + +private: + Qt::Orientation m_orientation; + +} ; + + +SideBar::SideBar( Qt::Orientation _orientation, QWidget * _parent ) : + QToolBar( _parent ), + m_btnGroup( this ) +{ + setOrientation( _orientation ); + setIconSize( QSize( 16, 16 ) ); + + m_btnGroup.setExclusive( false ); + connect( &m_btnGroup, SIGNAL( buttonClicked( QAbstractButton * ) ), + this, SLOT( toggleButton( QAbstractButton * ) ) ); +} + + + + +SideBar::~SideBar() +{ +} + + + + +void SideBar::appendTab( SideBarWidget * _sbw ) +{ + SideBarButton * btn = new SideBarButton( orientation(), this ); + btn->setText( _sbw->title() ); + btn->setIcon( _sbw->icon() ); + btn->setCheckable( true ); + m_widgets[btn] = _sbw; + m_btnGroup.addButton( btn ); + addWidget( btn ); + + _sbw->hide(); + _sbw->setMinimumWidth( 200 ); +} + + + + +void SideBar::toggleButton( QAbstractButton * _btn ) +{ + QToolButton * toolButton = NULL; + QWidget * activeWidget = NULL; + for( ButtonMap::Iterator it = m_widgets.begin(); + it != m_widgets.end(); ++it ) + { + QToolButton * curBtn = it.key(); + if( curBtn != _btn ) + { + curBtn->setChecked( false ); + curBtn->setToolButtonStyle( Qt::ToolButtonIconOnly ); + } + else + { + toolButton = it.key(); + activeWidget = it.value(); + } + if( it.value() ) + { + it.value()->hide(); + } + } + + if( toolButton && activeWidget ) + { + activeWidget->setVisible( _btn->isChecked() ); + toolButton->setToolButtonStyle( _btn->isChecked() ? + Qt::ToolButtonTextBesideIcon : Qt::ToolButtonIconOnly ); + } +} + + +#include "moc_SideBar.cxx" + diff --git a/src/gui/widgets/side_bar_widget.cpp b/src/gui/widgets/SideBarWidget.cpp similarity index 80% rename from src/gui/widgets/side_bar_widget.cpp rename to src/gui/widgets/SideBarWidget.cpp index 73ecc1097..d9cf21b60 100644 --- a/src/gui/widgets/side_bar_widget.cpp +++ b/src/gui/widgets/SideBarWidget.cpp @@ -1,8 +1,8 @@ /* - * side_bar_widget.cpp - implementation of base-widget for side-bar + * SideBarWidget.cpp - implementation of base-widget for side-bar + * + * Copyright (c) 2004-2009 Tobias Doerffel * - * Copyright (c) 2004-2008 Tobias Doerffel - * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -22,17 +22,16 @@ * */ - #include #include #include -#include "side_bar_widget.h" +#include "SideBarWidget.h" #include "gui_templates.h" -sideBarWidget::sideBarWidget( const QString & _title, const QPixmap & _icon, +SideBarWidget::SideBarWidget( const QString & _title, const QPixmap & _icon, QWidget * _parent ) : QWidget( _parent ), m_title( _title ), @@ -47,14 +46,14 @@ sideBarWidget::sideBarWidget( const QString & _title, const QPixmap & _icon, -sideBarWidget::~sideBarWidget() +SideBarWidget::~SideBarWidget() { } -void sideBarWidget::paintEvent( QPaintEvent * ) +void SideBarWidget::paintEvent( QPaintEvent * ) { const int TITLE_FONT_HEIGHT = 13; @@ -77,7 +76,7 @@ void sideBarWidget::paintEvent( QPaintEvent * ) -void sideBarWidget::resizeEvent( QResizeEvent * ) +void SideBarWidget::resizeEvent( QResizeEvent * ) { const int MARGIN = 6; m_contents->setGeometry( MARGIN, 40 + MARGIN, width() - MARGIN * 2, @@ -86,6 +85,5 @@ void sideBarWidget::resizeEvent( QResizeEvent * ) -#include "moc_side_bar.cxx" -#include "moc_side_bar_widget.cxx" +#include "moc_SideBarWidget.cxx" diff --git a/src/gui/widgets/kmultitabbar.cpp b/src/gui/widgets/kmultitabbar.cpp deleted file mode 100644 index 750065a1c..000000000 --- a/src/gui/widgets/kmultitabbar.cpp +++ /dev/null @@ -1,917 +0,0 @@ -/* - * kmultitabbar.cpp - widget for horizontal and vertical tabs - * - * Copyright (c) 2001-2003 Joseph Wenninger - * Copyright (c) 2004-2007 Tobias Doerffel - * - * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program (see COPYING); if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - */ - - -#include "kmultitabbar.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "templates.h" -#include "tooltip.h" - -#define NEARBYINT(i) ((int(float(i) + 0.5))) - -class KMultiTabBarTabPrivate { -public: - QPixmap pix; -}; - - -KMultiTabBarInternal::KMultiTabBarInternal(QWidget *parent, KMultiTabBar::KMultiTabBarMode bm):QWidget(parent) -{ - m_expandedTabSize=-1; - m_showActiveTabTexts=false; - m_barMode=bm; - if (bm==KMultiTabBar::Vertical) - { - box=new QWidget(this); - mainLayout=new QVBoxLayout(box); - box->setFixedWidth(24); - setFixedWidth(24); - } - else - { - box=new QWidget(this); - mainLayout=new QHBoxLayout(box); - box->setFixedHeight(24); - setFixedHeight(24); - } - mainLayout->setMargin(0); - mainLayout->setSpacing(0); -} - -void KMultiTabBarInternal::setStyle(enum KMultiTabBar::KMultiTabBarStyle style) -{ - m_style=style; - for (int i=0;isetStyle(m_style); - - if ( (m_style==KMultiTabBar::KDEV3) || - (m_style==KMultiTabBar::KDEV3ICON ) ) { - delete mainLayout; - mainLayout=0; - resizeEvent(0); - } else if (mainLayout==0) { - if (m_barMode==KMultiTabBar::Vertical) - { - box=new QWidget(this); - mainLayout=new QVBoxLayout(box); - box->setFixedWidth(24); - setFixedWidth(24); - } - else - { - box=new QWidget(this); - mainLayout=new QHBoxLayout(box); - box->setFixedHeight(24); - setFixedHeight(24); - } - for (int i=0;iaddWidget(m_tabs.at(i)); - - } - update(); -} - - - -#define CALCDIFF(m_tabs,diff,i) if (m_lines>(int)lines) {\ - int ulen=0;\ - diff=0; \ - for (int i2=i;i2neededSize();\ - if ((ulen+l1)>(int)space){\ - if (ulen==0) diff=0;\ - else diff=((float)(space-ulen))/(i2-i);\ - break;\ - }\ - ulen+=l1;\ - }\ - } else {diff=0; } - - -void KMultiTabBarInternal::resizeEvent(QResizeEvent *ev) { - if (ev) QWidget::resizeEvent(ev); - - if ( (m_style==KMultiTabBar::KDEV3) || - (m_style==KMultiTabBar::KDEV3ICON) ){ - box->setGeometry(0,0,width(),height()); - int lines=1; - uint space; - float tmp=0; - if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) - space=width(); - else - space=height(); - - int cnt=0; -//CALCULATE LINES - const int tabCount=m_tabs.count(); - for (int i=0;ineededSize(); - if (tmp>space) { - if (cnt>1)i--; - else if (i==(tabCount-1)) break; - cnt=0; - tmp=0; - lines++; - } - } -//SET SIZE & PLACE - float diff=0; - cnt=0; - - if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) { - - setFixedHeight(lines*24); - box->setFixedHeight(lines*24); - m_lines=height()/24-1; - lines=0; - CALCDIFF(m_tabs,diff,0) - tmp=-diff; - - for (int i=0;ineededSize()+diff; - if (tmp>space) { - if (cnt>1) { - CALCDIFF(m_tabs,diff,i) - i--; - } - else { - tab->removeEventFilter(this); - tab->move(NEARBYINT(tmp-tab->neededSize()),lines*24); - tab->setFixedWidth(NEARBYINT(tmp+diff)-tab->x());; - tab->installEventFilter(this); - CALCDIFF(m_tabs,diff,(i+1)) - - } - tmp=-diff; - cnt=0; - lines++; - - } else { - tab->removeEventFilter(this); - tab->move(NEARBYINT(tmp-tab->neededSize()),lines*24); - tab->setFixedWidth(NEARBYINT(tmp+diff)-tab->x());; - - tab->installEventFilter(this); - - } - } - } - else { - setFixedWidth(lines*24); - box->setFixedWidth(lines*24); - m_lines=lines=width()/24; - lines=0; - CALCDIFF(m_tabs,diff,0) - tmp=-diff; - - for (int i=0;ineededSize()+diff; - if (tmp>space) { - if (cnt>1) { - CALCDIFF(m_tabs,diff,i); - tmp=-diff; - i--; - } - else { - tab->removeEventFilter(this); - tab->move(lines*24,NEARBYINT(tmp-tab->neededSize())); - tab->setFixedHeight(NEARBYINT(tmp+diff)-tab->y());; - tab->installEventFilter(this); - } - cnt=0; - tmp=-diff; - lines++; - } else { - tab->removeEventFilter(this); - tab->move(lines*24,NEARBYINT(tmp-tab->neededSize())); - tab->setFixedHeight(NEARBYINT(tmp+diff)-tab->y());; - tab->installEventFilter(this); - } - } - } - - - } else { - int size=0; /*move the calculation into another function and call it only on add tab and tab click events*/ - for (int i=0;i<(int)m_tabs.count();i++) - size+=(m_barMode==KMultiTabBar::Vertical?m_tabs.at(i)->height():m_tabs.at(i)->width()); - if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) - box->setGeometry(0,0,size,height()); - else box->setGeometry(0,0,width(),size); - - } -} - - -void KMultiTabBarInternal::showActiveTabTexts(bool show) -{ - m_showActiveTabTexts=show; -} - - -KMultiTabBarTab* KMultiTabBarInternal::tab(int id) const -{ - for (QListIterator it(m_tabs);it.hasNext();it.next()){ - if (it.peekNext()->id()==id) return it.peekNext(); - } - return 0; -} - -bool KMultiTabBarInternal::eventFilter(QObject *, QEvent *e) { - if (e->type()==QEvent::Resize) resizeEvent(0); - return false; -} - -int KMultiTabBarInternal::appendTab(const QPixmap &pic ,int id,const QString& text) -{ - KMultiTabBarTab *tab; - m_tabs.append(tab= new KMultiTabBarTab(pic,text,id,box,m_position,m_style)); - mainLayout->addWidget( tab ); - tab->installEventFilter(this); - tab->showActiveTabText(m_showActiveTabTexts); - - if (m_style==KMultiTabBar::KONQSBC) - { - if (m_expandedTabSizeneededSize()) { - m_expandedTabSize=tab->neededSize(); - for (int i=0;isetSize(m_expandedTabSize); - - } else tab->setSize(m_expandedTabSize); - } else tab->updateState(); - tab->show(); - resizeEvent(0); - return 0; -} - -void KMultiTabBarInternal::removeTab(int id) -{ - for (int pos=0;posid()==id) - { - delete m_tabs.at(pos); - m_tabs.removeAt(pos); - resizeEvent(0); - break; - } - } -} - -void KMultiTabBarInternal::setPosition(enum KMultiTabBar::KMultiTabBarPosition pos) -{ - m_position=pos; - for (int i=0;isetTabsPosition(m_position); - update(); -} - -KMultiTabBarButton::KMultiTabBarButton(const QPixmap& pic,const QString& text, QMenu *popup, - int id,QWidget *parent,KMultiTabBar::KMultiTabBarPosition pos,KMultiTabBar::KMultiTabBarStyle style) - :QPushButton(QIcon(),text,parent),m_style(style) -{ - setIcon(pic); - setText(text); - m_position=pos; - if (popup) setMenu(popup); - setFlat(true); - setFixedHeight(24); - setFixedWidth(24); - m_id=id; - setToolTip(text); - connect(this,SIGNAL(clicked()),this,SLOT(slotClicked())); -} - -KMultiTabBarButton::KMultiTabBarButton(const QString& text, QMenu *popup, - int id,QWidget *parent,KMultiTabBar::KMultiTabBarPosition pos,KMultiTabBar::KMultiTabBarStyle style) - :QPushButton(QIcon(),text,parent),m_style(style) -{ - setText(text); - m_position=pos; - if (popup) setMenu(popup); - setFlat(true); - setFixedHeight(24); - setFixedWidth(24); - m_id=id; - setToolTip(text); - connect(this,SIGNAL(clicked()),this,SLOT(slotClicked())); -} - -KMultiTabBarButton::~KMultiTabBarButton() { -} - -int KMultiTabBarButton::id() const{ - return m_id; -} - -void KMultiTabBarButton::setText(const QString& text) -{ - QPushButton::setText(text); - m_text=text; - setToolTip(text); -} - -void KMultiTabBarButton::slotClicked() -{ - emit clicked(m_id); -} - -void KMultiTabBarButton::setPosition(KMultiTabBar::KMultiTabBarPosition pos) -{ - m_position=pos; - update(); -} - -void KMultiTabBarButton::setStyle(KMultiTabBar::KMultiTabBarStyle style) -{ - m_style=style; - update(); -} - -void KMultiTabBarButton::hideEvent( QHideEvent* he) { - QPushButton::hideEvent(he); - KMultiTabBar *tb=dynamic_cast(parentWidget()); - if (tb) tb->updateSeparator(); -} - -void KMultiTabBarButton::showEvent( QShowEvent* he) { - QPushButton::showEvent(he); - KMultiTabBar *tb=dynamic_cast(parentWidget()); - if (tb) tb->updateSeparator(); -} - - -QSize KMultiTabBarButton::sizeHint() const -{ - //constPolish(); - - int w = 0, h = 0; - - // calculate contents size... - int iw = 0, ih = 0; - if ( !icon().isNull() ) { - iw = 20; - ih = 16; - w += iw; - h = qMax( h, ih ); - } - QStyleOptionButton sob; - if ( menu() != 0 ) - w += style()->pixelMetric(QStyle::PM_MenuButtonIndicator, &sob, this); - - QString s( text() ); - bool empty = s.isEmpty(); - if ( empty ) - s = QLatin1String("XXXX"); - QFontMetrics fm = fontMetrics(); - QSize sz = fm.size( Qt::TextShowMnemonic, s ); - if(!empty || !w) - w += sz.width(); - if(!empty || !h) - h = qMax(h, sz.height()); - - - QStyleOptionToolButton opt; - opt.init(this); - opt.rect = QRect(0, 0, w, h); - opt.subControls = QStyle::SC_All; - opt.activeSubControls = 0; - opt.text = text(); - opt.font = font(); - opt.icon = icon(); - opt.iconSize = QSize(iw, ih); - return (style()->sizeFromContents(QStyle::CT_ToolButton, &opt, QSize(w, h), this). - expandedTo(QApplication::globalStrut())); -} - - -KMultiTabBarTab::KMultiTabBarTab(const QPixmap& pic, const QString& text, - int id,QWidget *parent,KMultiTabBar::KMultiTabBarPosition pos, - KMultiTabBar::KMultiTabBarStyle style) - :KMultiTabBarButton(text,0,id,parent,pos,style), - m_showActiveTabText(false) -{ - d=new KMultiTabBarTabPrivate(); - setIcon(pic); - m_expandedSize=24; - setCheckable(true); - setAttribute( Qt::WA_OpaquePaintEvent, true ); -} - -KMultiTabBarTab::~KMultiTabBarTab() { - delete d; -} - - -void KMultiTabBarTab::setTabsPosition(KMultiTabBar::KMultiTabBarPosition pos) -{ - if ((pos!=m_position) && ((pos==KMultiTabBar::Left) || (pos==KMultiTabBar::Right))) { - if (!d->pix.isNull()) { - QMatrix temp;// (1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F); - temp.rotate(180); - d->pix=d->pix.transformed(temp); - setIcon(d->pix); - } - } - setPosition(pos); -} - -void KMultiTabBarTab::setIcon(const QString& icon) -{ - QPixmap pic(icon); - setIcon(pic); -} - -void KMultiTabBarTab::setIcon(const QPixmap& icon) -{ - - if (m_style!=KMultiTabBar::KDEV3) { - if ((m_position==KMultiTabBar::Left) || (m_position==KMultiTabBar::Right)) { - QMatrix rotateMatrix; -/* if (m_position==KMultiTabBar::Left) - rotateMatrix.rotate(-270); - else*/ - rotateMatrix.rotate(90); - d->pix=icon.transformed(rotateMatrix); //TODO FIX THIS, THIS SHOWS WINDOW - KMultiTabBarButton::setIcon(d->pix); - } else KMultiTabBarButton::setIcon(icon); - } -} - -void KMultiTabBarTab::slotClicked() -{ - updateState(); - KMultiTabBarButton::slotClicked(); -} - -void KMultiTabBarTab::setState(bool b) -{ - setChecked(b); - updateState(); -} - -void KMultiTabBarTab::updateState() -{ - - if (m_style!=KMultiTabBar::KONQSBC) { - if ((m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) || (isChecked())) { - QPushButton::setText(m_text); - } else { - QPushButton::setText(QString()); - } - - if ((m_position==KMultiTabBar::Right || m_position==KMultiTabBar::Left)) { - setFixedWidth(24); - if ((m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) || (isChecked())) { - setFixedHeight(KMultiTabBarButton::sizeHint().width()); - } else setFixedHeight(36); - } else { - setFixedHeight(24); - if ((m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) || (isChecked())) { - setFixedWidth(KMultiTabBarButton::sizeHint().width()); - } else setFixedWidth(36); - } - } else { - if ((!isChecked()) || (!m_showActiveTabText)) - { - setFixedWidth(24); - setFixedHeight(24); - return; - } - if ((m_position==KMultiTabBar::Right || m_position==KMultiTabBar::Left)) - setFixedHeight(m_expandedSize); - else - setFixedWidth(m_expandedSize); - } -} - -int KMultiTabBarTab::neededSize() -{ - return (((m_style!=KMultiTabBar::KDEV3)?24:0)+QFontMetrics(QFont()).width(m_text)+6); -} - -void KMultiTabBarTab::setSize(int size) -{ - m_expandedSize=size; - updateState(); -} - -void KMultiTabBarTab::showActiveTabText(bool show) -{ - m_showActiveTabText=show; -} - -void KMultiTabBarTab::paintEvent(QPaintEvent *) { - QPainter painter(this); - drawButton(&painter); -} - -void KMultiTabBarTab::drawButtonLabel(QPainter *p) { - drawButton(p); -} -void KMultiTabBarTab::drawButton(QPainter *paint) -{ - if (m_style!=KMultiTabBar::KONQSBC) drawButtonStyled(paint); - else drawButtonClassic(paint); -} - -void KMultiTabBarTab::drawButtonStyled(QPainter *paint) { - - QSize sh; - const int width = 36; // rotated - const int height = 24; - if ((m_style==KMultiTabBar::KDEV3) || (m_style==KMultiTabBar::KDEV3ICON) || (isChecked())) { - if ((m_position==KMultiTabBar::Left) || (m_position==KMultiTabBar::Right)) - sh=QSize(this->height(),this->width());//KMultiTabBarButton::sizeHint(); - else sh=QSize(this->width(),this->height()); - } - else - sh=QSize(width,height); - - QPixmap pixmap( sh.width(),height); ///,sh.height()); - pixmap.fill(backgroundRole()); - QPainter painter(&pixmap); - - - QStyle::State st=QStyle::State_None; - - st|=QStyle::State_Enabled; - - if (isChecked()) st|=QStyle::State_On; - - QStyleOptionButton options; - options.init(this); - options.state = st; - options.rect = QRect(0,0,pixmap.width(),pixmap.height()); - options.palette = palette(); - options.text = text(); - options.icon = icon(); - options.iconSize = iconSize(); - - style()->drawControl(QStyle::CE_PushButton, &options, &painter, this); - - switch (m_position) { - case KMultiTabBar::Left: - paint->rotate(-90); - paint->drawPixmap(1-pixmap.width(),0,pixmap); - break; - case KMultiTabBar::Right: - paint->rotate(90); - paint->drawPixmap(0,1-pixmap.height(),pixmap); - break; - - default: - paint->drawPixmap(0,0,pixmap); - break; - } - -} - -void KMultiTabBarTab::drawButtonClassic(QPainter *paint) -{ - QPixmap pixmap; - if( !icon().isNull() ) - pixmap = icon().pixmap( 16, 16 ); - paint->fillRect(0, 0, 24, 24, palette().background().color()); - - if (!isChecked()) - { - - if (m_position==KMultiTabBar::Right) - { - paint->fillRect(0,0,21,21,QBrush(palette().background().color())); - - paint->setPen(palette().background().color().dark(150)); - paint->drawLine(0,22,23,22); - - paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); - - paint->setPen(palette().shadow().color()); - paint->drawLine(0,0,0,23); - paint->setPen(palette().background().color().dark(120)); - paint->drawLine(1,0,1,23); - - } - else - if ((m_position==KMultiTabBar::Bottom) || (m_position==KMultiTabBar::Top)) - { - paint->fillRect(0,1,23,22,QBrush(palette().background().color())); - - paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); - - paint->setPen(palette().background().color().dark(120)); - paint->drawLine(23,0,23,23); - - - paint->setPen(palette().light().color()); - paint->drawLine(0,22,23,22); - paint->drawLine(0,23,23,23); - paint->setPen(palette().shadow().color()); - paint->drawLine(0,0,23,0); - paint->setPen(palette().background().color().dark(120)); - paint->drawLine(0,1,23,1); - - } - else - { - paint->setPen(palette().background().color().dark(120)); - paint->drawLine(0,23,23,23); - paint->fillRect(0,0,23,21,QBrush(palette().background())); - paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); - - paint->setPen(palette().light().color()); - paint->drawLine(23,0,23,23); - paint->drawLine(22,0,22,23); - - paint->setPen(palette().shadow().color()); - paint->drawLine(0,0,0,23); - - } - - - } - else - { - if (m_position==KMultiTabBar::Right) - { - paint->setPen(palette().shadow().color()); - paint->drawLine(0,height()-1,23,height()-1); - paint->drawLine(0,height()-2,23,height()-2); - paint->drawLine(23,0,23,height()-1); - paint->drawLine(22,0,22,height()-1); - paint->fillRect(0,0,21,height()-3,QBrush(palette().light().color())); - paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); - - if (m_showActiveTabText) - { - if (height()<25+4) return; - - QPixmap tpixmap(height()-25-3, width()-2); - QPainter painter(&tpixmap); - - painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),QBrush(palette().light().color())); - - painter.setPen(palette().text().color()); - painter.drawText(0,+width()/2+QFontMetrics(QFont()).height()/2,m_text); - - paint->rotate(90); - paint->drawPixmap(25,-tpixmap.height()+1,tpixmap); - } - - } - else - if (m_position==KMultiTabBar::Top) - { - paint->fillRect(0,0,width()-1,23,QBrush(palette().light().color())); - paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); - if (m_showActiveTabText) - { - paint->setPen(palette().text().color()); - paint->drawText(25,height()/2+QFontMetrics(QFont()).height()/2,m_text); - } - } - else - if (m_position==KMultiTabBar::Bottom) - { - paint->setPen(palette().shadow().color()); - paint->drawLine(0,23,width()-1,23); - paint->drawLine(0,22,width()-1,22); - paint->fillRect(0,0,width()-1,21,QBrush(palette().light().color())); - paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); - if (m_showActiveTabText) - { - paint->setPen(palette().text().color()); - paint->drawText(25,height()/2+QFontMetrics(QFont()).height()/2,m_text); - } - - } - else - { - - - paint->setPen(palette().shadow().color()); - paint->drawLine(0,height()-1,23,height()-1); - paint->drawLine(0,height()-2,23,height()-2); - paint->fillRect(0,0,23,height()-3,QBrush(palette().light().color())); - paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); - if (m_showActiveTabText) - { - - if (height()<25+4) return; - - QPixmap tpixmap(height()-25-3, width()-2); - QPainter painter(&tpixmap); - - painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),QBrush(palette().light().color())); - - painter.setPen(palette().text().color()); - painter.drawText(tpixmap.width()-QFontMetrics(QFont()).width(m_text),+width()/2+QFontMetrics(QFont()).height()/2,m_text); - - paint->rotate(-90); - - paint->drawPixmap(-24-tpixmap.width(),2,tpixmap); - - } - - } - - } -} - -KMultiTabBar::KMultiTabBar(KMultiTabBarMode bm, QWidget *parent) - : QWidget(parent) -{ - if (bm==Vertical) - { - m_l=new QVBoxLayout(this); - setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding)); - } - else - { - m_l=new QHBoxLayout(this); - setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - } - m_l->setMargin(0); - - m_internal=new KMultiTabBarInternal(this,bm); - setPosition((bm==KMultiTabBar::Vertical)?KMultiTabBar::Right:KMultiTabBar::Bottom); - setStyle(VSNET); - m_l->insertWidget(0,m_internal); - m_l->insertWidget(0,m_btnTabSep=new QFrame(this)); - m_btnTabSep->setFixedHeight(4); - m_btnTabSep->setFrameStyle(QFrame::Panel | QFrame::Sunken); - m_btnTabSep->setLineWidth(2); - m_btnTabSep->hide(); - - updateGeometry(); -} - -KMultiTabBar::~KMultiTabBar() { -} - -int KMultiTabBar::appendButton(const QPixmap &pic ,int id,QMenu *popup,const QString&) -{ - KMultiTabBarButton *btn; - m_buttons.append(btn= new KMultiTabBarButton(pic,QString(), - popup,id,this,m_position,m_internal->m_style)); - m_l->insertWidget(0,btn); - btn->show(); - m_btnTabSep->show(); - return 0; -} - -void KMultiTabBar::updateSeparator() { - bool hideSep=true; - for (QListIterator it(m_buttons);it.hasNext();){ - if (it.next()->isVisibleTo(this)) { - hideSep=false; - break; - } - } - if (hideSep) m_btnTabSep->hide(); - else m_btnTabSep->show(); - -} - -int KMultiTabBar::appendTab(const QPixmap &pic ,int id ,const QString& text) -{ - m_internal->appendTab(pic,id,text); - return 0; -} - -KMultiTabBarButton* KMultiTabBar::button(int id) const -{ - for (QListIterator it(m_buttons);it.hasNext();it.next()){ - if (it.peekNext()->id()==id) return it.peekNext(); - } - return 0; -} - -KMultiTabBarTab* KMultiTabBar::tab(int id) const -{ - return m_internal->tab(id); -} - - - -void KMultiTabBar::removeButton(int id) -{ - for (int pos=0;posid()==id) - { - m_buttons.at(pos)->deleteLater(); - m_buttons.removeAt(pos); - break; - } - } - if (m_buttons.count()==0) m_btnTabSep->hide(); -} - -void KMultiTabBar::removeTab(int id) -{ - m_internal->removeTab(id); -} - -void KMultiTabBar::setTab(int id,bool state) -{ - KMultiTabBarTab *ttab=tab(id); - if (ttab) - { - ttab->setState(state); - } -} - -bool KMultiTabBar::isTabRaised(int id) const -{ - KMultiTabBarTab *ttab=tab(id); - if (ttab) - { - return ttab->isChecked(); - } - - return false; -} - - -void KMultiTabBar::showActiveTabTexts(bool show) -{ - m_internal->showActiveTabTexts(show); -} - -void KMultiTabBar::setStyle(KMultiTabBarStyle style) -{ - m_internal->setStyle(style); -} - -KMultiTabBar::KMultiTabBarStyle KMultiTabBar::tabStyle() const -{ - return m_internal->m_style; -} - -void KMultiTabBar::setPosition(KMultiTabBarPosition pos) -{ - m_position=pos; - m_internal->setPosition(pos); - for (int i=0;isetPosition(pos); -} - -KMultiTabBar::KMultiTabBarPosition KMultiTabBar::position() const -{ - return m_position; -} -void KMultiTabBar::fontChange(const QFont& /* oldFont */) -{ - for (int i=0;icount();i++) - tabs()->at(i)->resize(); - update(); -} - -QList* KMultiTabBar::tabs() {return m_internal->tabs();} -QList* KMultiTabBar::buttons() {return &m_buttons;} - - -#include "moc_kmultitabbar.cxx" - - -