summaryrefslogtreecommitdiff
path: root/muse2/doc
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/doc')
-rw-r--r--muse2/doc/CMakeLists.txt75
-rwxr-xr-xmuse2/doc/build_docs.sh129
-rw-r--r--muse2/doc/developer_docs.tex702
-rw-r--r--muse2/doc/documentation.tex587
-rw-r--r--muse2/doc/pdf/developer_docs.pdfbin0 -> 226142 bytes
-rw-r--r--muse2/doc/pdf/documentation.pdf (renamed from muse2/doc/documentation.pdf)bin1488360 -> 1429504 bytes
6 files changed, 928 insertions, 565 deletions
diff --git a/muse2/doc/CMakeLists.txt b/muse2/doc/CMakeLists.txt
new file mode 100644
index 00000000..de90563e
--- /dev/null
+++ b/muse2/doc/CMakeLists.txt
@@ -0,0 +1,75 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 1999-2013 by Werner Schweer and others
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#=============================================================================
+
+install( FILES pdf/documentation.pdf pdf/developer_docs.pdf
+ DESTINATION ${MusE_DOC_DIR}/muse_pdf
+ )
+
+file (GLOB single_documentation_html_files
+ html/single/documentation/*.css
+ html/single/documentation/*.html
+ # html/single/documentation/*.jpg
+ html/single/documentation/*.png
+ # html/single/documentation/toc_.txt
+ )
+
+file (GLOB single_developer_docs_html_files
+ html/single/developer_docs/*.css
+ html/single/developer_docs/*.html
+ # html/single/developer_docs/*.jpg
+ html/single/developer_docs/*.png
+ # html/single/developer_docs/toc_.txt
+ )
+
+file (GLOB split_documentation_html_files
+ html/split/documentation/*.css
+ html/split/documentation/*.html
+ # html/split/documentation/*.jpg
+ html/split/documentation/*.png
+ # html/split/documentation/toc_.txt
+ )
+
+file (GLOB split_developer_docs_html_files
+ html/split/developer_docs/*.css
+ html/split/developer_docs/*.html
+ # html/split/developer_docs/*.jpg
+ html/split/developer_docs/*.png
+ # html/split/developer_docs/toc_.txt
+ )
+
+install( FILES ${single_documentation_html_files}
+ DESTINATION ${MusE_DOC_DIR}/muse_html/single/documentation
+ )
+
+install( FILES ${single_developer_docs_html_files}
+ DESTINATION ${MusE_DOC_DIR}/muse_html/single/developer_docs
+ )
+
+install( FILES ${split_documentation_html_files}
+ DESTINATION ${MusE_DOC_DIR}/muse_html/split/documentation
+ )
+
+install( FILES ${split_developer_docs_html_files}
+ DESTINATION ${MusE_DOC_DIR}/muse_html/split/developer_docs
+ )
+ \ No newline at end of file
diff --git a/muse2/doc/build_docs.sh b/muse2/doc/build_docs.sh
new file mode 100755
index 00000000..fe9fe231
--- /dev/null
+++ b/muse2/doc/build_docs.sh
@@ -0,0 +1,129 @@
+#!/bin/bash
+#=============================================================================
+# MusE
+# Linux Music Editor
+# Copyright (C) 1999-2013 by Werner Schweer and others
+#
+# build_docs.sh Copyright (C) 2013 Tim E. Real <terminator356 at users dot sourceforge dot net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#=============================================================================
+
+#=============================================================
+#
+# Run this script to re-create the PDF and HTML documentation.
+# Usage: build_docs.sh [--help] [--no_post_clean]
+#
+#=============================================================
+
+if [ "$1" == "--help" ]; then
+ echo "Usage: build_docs.sh [--no_post_clean (don't clean up after build)]"
+ exit 1
+fi
+
+#
+# Pre clean
+#
+rm -rf pdf/*.*
+rm -rf html/single/documentation/*.*
+rm -rf html/single/developer_docs/*.*
+rm -rf html/split/documentation/*.*
+rm -rf html/split/developer_docs/*.*
+rm -rf tmp
+
+mkdir -p tmp/pdf/documentation
+mkdir -p tmp/pdf/developer_docs
+
+mkdir -p tmp/html/single/documentation
+mkdir -p tmp/html/single/developer_docs
+mkdir -p tmp/html/split/documentation
+mkdir -p tmp/html/split/developer_docs
+
+#
+# Run the PDF conversions first to get the *.aux files required for proper HTML links displaying
+# Run each conversion at least three times to resolve all references
+#
+# pdflatex -output-directory=pdf documentation.tex
+# pdflatex -output-directory=pdf documentation.tex
+# pdflatex -output-directory=pdf documentation.tex
+#
+# pdflatex -output-directory=pdf developer_docs.tex
+# pdflatex -output-directory=pdf developer_docs.tex
+# pdflatex -output-directory=pdf developer_docs.tex
+
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/documentation documentation.tex
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/documentation documentation.tex
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/documentation documentation.tex
+
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/developer_docs developer_docs.tex
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/developer_docs developer_docs.tex
+pdflatex -interaction=batchmode -halt-on-error -file-line-error -output-directory=tmp/pdf/developer_docs developer_docs.tex
+
+#
+# Now run the HTML conversions
+#
+# latex2html -nonavigation -noaddress -noinfo -split 0 -external_file pdf/documentation -dir html/single/documentation documentation.tex
+# latex2html -nonavigation -noaddress -noinfo -split 0 -external_file pdf/developer_docs -dir html/single/developer_docs developer_docs.tex
+# latex2html -noaddress -noinfo -split 4 -external_file pdf/documentation -dir html/split/documentation documentation.tex
+# latex2html -noaddress -noinfo -split 4 -external_file pdf/developer_docs -dir html/split/developer_docs developer_docs.tex
+
+latex2html -nonavigation -noaddress -noinfo -split 0 -external_file tmp/pdf/documentation/documentation -mkdir -dir tmp/html/single/documentation documentation.tex
+latex2html -nonavigation -noaddress -noinfo -split 0 -external_file tmp/pdf/developer_docs/developer_docs -mkdir -dir tmp/html/single/developer_docs developer_docs.tex
+
+latex2html -noaddress -noinfo -split 4 -external_file tmp/pdf/documentation/documentation -mkdir -dir tmp/html/split/documentation documentation.tex
+latex2html -noaddress -noinfo -split 4 -external_file tmp/pdf/developer_docs/developer_docs -mkdir -dir tmp/html/split/developer_docs developer_docs.tex
+
+#
+# Move the files
+#
+mv -f tmp/pdf/documentation/*.pdf pdf
+mv -f tmp/pdf/developer_docs/*.pdf pdf
+
+mv -f tmp/html/single/documentation/*.css html/single/documentation
+mv -f tmp/html/single/documentation/*.html html/single/documentation
+# mv -f tmp/html/single/documentation/*.jpg html/single/documentation
+mv -f tmp/html/single/documentation/*.png html/single/documentation
+# mv -f tmp/html/single/documentation/toc_.txt html/single/documentation
+
+mv -f tmp/html/single/developer_docs/*.css html/single/developer_docs
+mv -f tmp/html/single/developer_docs/*.html html/single/developer_docs
+# mv -f tmp/html/single/developer_docs/*.jpg html/single/developer_docs
+mv -f tmp/html/single/developer_docs/*.png html/single/developer_docs
+# mv -f tmp/html/single/developer_docs/toc_.txt html/single/developer_docs
+
+mv -f tmp/html/split/documentation/*.css html/split/documentation
+mv -f tmp/html/split/documentation/*.html html/split/documentation
+# mv -f tmp/html/split/documentation/*.jpg html/split/documentation
+mv -f tmp/html/split/documentation/*.png html/split/documentation
+# mv -f tmp/html/split/documentation/toc_.txt html/split/documentation
+
+mv -f tmp/html/split/developer_docs/*.css html/split/developer_docs
+mv -f tmp/html/split/developer_docs/*.html html/split/developer_docs
+# mv -f tmp/html/split/developer_docs/*.jpg html/split/developer_docs
+mv -f tmp/html/split/developer_docs/*.png html/split/developer_docs
+# mv -f tmp/html/split/developer_docs/toc_.txt html/split/developer_docs
+
+#
+# Post clean
+#
+if [ "$1" != "--no_post_clean" ]; then
+# rm -f pdf/*.aux pdf/*.log pdf/*.out pdf/*.toc
+# rm -f html/single/documentation/*.aux html/single/documentation/*.log html/single/documentation/*.out html/single/documentation/*.pl html/single/documentation/*.tex html/single/documentation/WARNINGS
+# rm -f html/single/developer_docs/*.aux html/single/developer_docs/*.log html/single/developer_docs/*.out html/single/developer_docs/*.pl html/single/developer_docs/*.tex html/single/developer_docs/WARNINGS
+# rm -f html/split/documentation/*.aux html/split/documentation/*.log html/split/documentation/*.out html/split/documentation/*.pl html/split/documentation/*.tex html/split/documentation/WARNINGS
+# rm -f html/split/developer_docs/*.aux html/split/developer_docs/*.log html/split/developer_docs/*.out html/split/developer_docs/*.pl html/split/developer_docs/*.tex html/split/developer_docs/WARNINGS
+rm -rf tmp
+fi
diff --git a/muse2/doc/developer_docs.tex b/muse2/doc/developer_docs.tex
new file mode 100644
index 00000000..bc3cdc86
--- /dev/null
+++ b/muse2/doc/developer_docs.tex
@@ -0,0 +1,702 @@
+%% (c) 2012 florian jung
+%% (c) 2012 Robert Jonsson
+%% we should consider putting this under a proper license. GPL, or
+%% some GPL-like documentation license??
+
+%% rules for editing documentation: (READ THIS FIRST)
+%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+%%
+%% please try to let newly written lines be shorter than 72 characters.
+%% minor exceptions are okay, but please not more than 80 chars.
+%% comments shall start after character #80 of the line (that is,
+%% they shall be "on the right margin")
+%%
+%% DON'T MIX up changes and reformatting in one commit. when changing
+%% stuff, please don't touch the lines before and after your change
+%% (that is, do not re-wrap them), even if it will look a bit patchy.
+%% this is for being able to easily use diff.
+%% when you want to reformat this file, then do it. but don't change
+%% anything, as this would be hard to find in a diff. and clearly
+%% state in the commit log that you "only" rearranged things.
+%%
+%% please adhere to the "User's manual" / "Internals" / "Design"
+%% partitioning (genereally, don't change the chapters until there
+%% is a really good reason for doing so (adding a chapter like
+%% "feature requests" as flo did in r1497 IS one).
+%% Below that, feel free to change the logical arrangement
+%% (making paragraphs to subsections and similar) if you deem it
+%% neccessary.
+%%
+%% Whenever referring to code symbols, constants or source/header
+%% files, please use \sym{someClass::someSymbol}, \usym{UPPERCASE_THING}
+%% or \f{file.cpp}.
+%% Only specify file paths or namespaces where it would be ambiguous
+%% otherwise. Specify 'someClass::' until it would disturb the reader
+%% and it is obvious. you have to replace '_' by {\_} (with the {}!).
+%% These macros do automatic hyphenation on Camel-Case, under_-score
+%% and scope::-operator boundaries. If you need to insert additional
+%% hyphenation points, use {\-}.
+%% Example: \sym{someClass::someAb{\-}nor{\-}mal{\-}lyLongName} will
+%% hyphenate: some-Class::-some-Ab-nor-mal-ly-Long-Name
+%%
+%% Whenever referring to URLs, please wrap them in \url{blah}. Key
+%% combinations shall look like \key{CTRL+C}. Menu items shall look
+%% like \menu{Menu > Submenu > Menu Item}.
+%%
+%% Where possible, reference other parts of this documents with
+%% \label and \ref. Avoid duplicate information under "Internals" by
+%% referring to the appropriate section in "User's manual".
+%%
+%% Please do no time-stamping of sections. if you need time-stamps,
+%% use "svn blame documentation.tex"
+%%
+%% If you contribute something, feel free to add yourself to \author.
+%%
+%% If you don't speak LaTeX fluently, a few tips:
+%% * \section, \subsection, \subsubsection, \paragraph, \subparagraph
+%% let you create sections etc. just copy-and-paste if unsure.
+%% * you must prefix special characters like the underscore with \
+%% (backslash)
+%% * \emph{some text} emphasizes the text, printing it italic.
+%% * \texttt{some text} displays the text in a typewriter font
+%% * \label{someName} creates a label at this position. this doesn't
+%% show up in the pdf. with \ref{someName}, you can reference to this
+%% label. (LaTeX will insert the section number instead of \ref)
+%% For this to work, you might need to recompile the .tex twice.
+%%
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% Dependencies:
+%% To produce pdf output from this document the following packages are
+%% needed (atleast under Ubuntu derivatives)
+%% latex???-base
+%% texlive-latex-recommended
+%% texlive-latex-extra
+%%
+%% To produce a pdf version of this manual type:
+%% pdflatex documentation.tex <enter>
+%% A file documentation.pdf should be generated.
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\documentclass[a4paper]{report}
+\usepackage[a4paper, left=2.5cm, right=2.5cm, top=2.5cm, bottom=2.5cm]{geometry}
+\usepackage[T1]{fontenc}
+\usepackage[utf8]{inputenc}
+\usepackage{lmodern}
+\usepackage[english]{babel}
+\usepackage{graphicx}
+\usepackage{hyphenat}
+\usepackage{wrapfig}
+\usepackage{fancyhdr}
+\usepackage{hyperref}
+\usepackage{xcolor}
+\hypersetup{
+ linkcolor=blue,
+ urlcolor=blue,
+ colorlinks=true, % hyperlinks will be blue
+ linkbordercolor=blue, % hyperlink borders will be blue
+ %pdfborderstyle={/S/U/W 1} % border style will be underline of width 1pt
+}
+\pagestyle{fancy}
+ \lhead{\scriptsize{\slshape\leftmark}}
+ \chead{}
+ \rhead{\thepage}
+ \lfoot{}
+ \cfoot{}
+ \rfoot{}
+ \renewcommand{\headrulewidth}{0.4pt}
+\usepackage{ifthen}
+
+%% Borrowed from Lyx output. "Because html converters don't know
+%% tabularnewline". Is required? Maybe replace with \\ ?
+\providecommand{\tabularnewline}{\\}
+
+% Hyphenate symbols before each uppercase letter, after each underscore
+% (without a "-") and after each ':' (without a "-")
+% TODO for any latex crack: also do automatic hyphenation, that is,
+% instead of some-Automation-Expression, do some-Au-to-ma-tion-Ex-press-ion
+\makeatletter
+\newcommand{\camelhyph}[1]{\@fterfirst\c@amelhyph#1\relax }
+\newcommand{\underscorehyph}[1]{\@fterfirst\u@nderscorehyph#1\relax }
+\def\@fterfirst #1#2{#2#1}
+\def\c@amelhyph #1{%
+\ifthenelse{\equal{#1}\relax}{}{% Do nothing if the end has been reached
+ \ifnum`#1=95 \_\hspace{0pt}\else % Check whether #1 is "_", then print _[thin space]
+ \ifnum`#1=58 :\hspace{0pt}\else
+ \ifnum`#1>64
+ \ifnum`#1<91 \-#1\else#1\fi% Check whether #1 is an uppercase letter,
+ \else#1\fi
+ \fi
+ \fi
+ % if so, print \-#1, otherwise #1
+ \expandafter\c@amelhyph% % insert \c@amelhyph again.
+}}
+\def\u@nderscorehyph #1{%
+\ifthenelse{\equal{#1}\relax}{}{% Do nothing if the end has been reached
+ \ifnum`#1=95 \_\hspace{0pt}\else % Check whether #1 is "_", then print _\-
+ \ifnum`#1=58 :\hspace{0pt}\else#1\fi\fi
+ \expandafter\u@nderscorehyph% % insert \u@nderscorehyph again.
+}}
+\makeatother
+
+
+
+\author{Florian Jung, Robert Jonsson, Tim Donnelly}
+\title{MusE Documentation}
+
+% Orcan: not needed since the hyperref package takes care of all
+%\newcommand{\url}[1]{\texttt{#1}}
+\newcommand{\key}[1]{\textbf{#1}}
+\newcommand{\shell}[1]{\texttt{\textbf{#1}}}
+\newcommand{\menu}[1]{\textbf{#1}}
+\newcommand{\sym}[1]{\texttt{\camelhyph{#1}}}
+\newcommand{\listing}[1]{\texttt{\camelhyph{#1}}}
+\newcommand{\usym}[1]{\texttt{\underscorehyph{#1}}}
+\newcommand{\file}[1]{\texttt{\camelhyph{#1}}}
+\newcommand{\screenshotwidth}[0]{0.8\textwidth}
+
+\begin{document}
+\tableofcontents
+\chapter{Internals -- how it works}
+This chapter explains how MusE is built internally, and is meant
+to be an aid for developers wanting to quickly start up with MusE.
+For details on \emph{why} stuff is done please refer to the following
+chapter.
+
+\section{User interface programming}
+We use the QT Toolkit for GUI- and other programming. The \emph{QT-Assistant}
+is an important tool for getting help. Almost everything can be looked
+up there.
+
+GUIs can be either be hardcoded (see \file{arranger.cpp} for an example)
+or can be created using \emph{QT-Designer} (see the dialogs under
+\file{widgets/function_dialogs/} for mostly cleanly-written examples).
+Don't forget to add your \file{cpp}, \file{h} and \file{ui} files to the
+corresponding sections in the \file{CMakeLists.txt}!
+
+Additionally, MusE offers some custom widgets, like menu title items etc.
+Following, there will be a small, unordered list about custom widgets:
+\begin{itemize}
+\item \sym{MusEGui::MenuTitleItem}: Provides a title-bar in a \sym{QMenu}. \\
+ Usage: \listing{someMenu->addAction(new\ MusEGui::MenuTitleItem(tr("fnord"),\ someMenu));} \\
+ Defined in \file{widgets/menutitleitem.h}.
+\item \sym{MusEGui::PopupMenu}: Provides a \sym{QMenu}-like menu which
+ can stay open after the user checks a checkable action.\\
+ Usage: just create a \listing{new\ PopupMenu(\ true|false\ )} instead of
+ a \listing{new\ QMenu()}. (\listing{true} means 'stay open')\\
+ Defined in \file{widgets/popupmenu.h}.
+\end{itemize}
+
+
+\section{Configuration} \label{portconfig_sucks}
+Configuration is a bit pesky in MusE in its current state. If you get
+confused by reading this chapter, that's a sign of a sane mind.
+
+There are three kinds of configuration items:
+\begin{itemize}
+\item (1) Global configuration, like coloring schemes, plugin categories, MDI-ness settings
+\item (2) Per-Song configuration, like whether to show or hide certain track types in the arranger
+\item (3) Something in between, like MIDI port settings etc. They obviously actually are
+ global configuration issues (or ought to be), but also obviously must be stored
+ in the song file for portability. (This problem could possibly be solved by
+ the feature proposal in \ref{symbolic_ports}.
+\end{itemize}
+
+\paragraph{Reading configuration}
+\sym{void\ MusECore::readConfiguration(Xml\&,\ bool,\ bool)} in
+\file{conf.cpp} is the central point
+of reading configuration. It is called when MusE is started first
+(by \sym{bool\ MusECore::readConfiguration()}), and also when a
+song is loaded. \\ %TODO: call paths!
+It can be instructed whether to read MIDI ports (3), global configuration
+and MIDI ports (1+3). Per-Song configuration is always read (2).
+
+When adding new configuration items and thus altering \sym{readConfiguration()},
+you must take care to place your item into the correct section. The code is
+divided into the following sections:
+\begin{itemize}
+\item Global and/or per-song configuration (3)
+\item Global configuration (1)
+\item Code for skipping obsolete entries
+\end{itemize}
+
+The sections are divided by comments (they contain \texttt{----}, so just
+search for them). Please do not just remove code for reading obsolete entries,
+but always add an appropriate entry to the 'skipping' section in order to
+prevent error messages when reading old configs.
+
+\paragraph{Writing configuration}
+Global configuration is written using the
+\sym{MusEGui::MusE::writeGlobalConfiguration()} functions, while
+per-song-config is written by \sym{MusEGui::MusE::writeConfiguration()}
+(notice the missing \sym{Global}; both implemented in \file{conf.cpp}).
+
+\sym{writeConfiguration} is actually just a subset of the code in
+\sym{writeGlobalConfiguration}. \textbf{Duplicate code!} % TODO fix that in the sourcecode.
+
+\paragraph{Song state}
+Additionally to per-song configuration, there is the song's state.
+This contains "the song", that is all tracks, parts and note events,
+together with information about the currently opened windows, their
+position, size, settings and so on. Adding new items here is actually
+pretty painless: Configuration is read and written using
+\sym{MusECore::Song::read} and \sym{::write}, both implemented in
+\file{songfile.cpp}. There are no caveats.
+
+\paragraph{How to add new items}
+When adding global configuration items, then add them into the second
+block ("global configuration") in \sym{readConfiguration} and into
+\sym{writeGlobalConfiguration}.
+
+When adding just-per-song items, better don't bother to touch the
+"configuration" code and just add it to the song's state (there might
+be rare exceptions).
+
+When adding global configuration items, make sure you add them into the
+correct section of \sym{readConfiguration}, and into \sym{writeGlobalConfiguration}.
+
+
+%TODO: how to write config,
+%TODO: song/global stuff
+%TODO: config lesen und schreiben fuer plugingroups
+
+
+\section{User controls and automation}
+\subsection{Handling user input}
+\subsubsection{Plugins and synthesizers}
+\paragraph{Overview}
+When the user launches a plugin's GUI, either a MusE-window with
+the relevant controls is shown, or the native GUI is launched. MusE
+will communicate with this native GUI through OSC (Open Sound Control).
+The relevant classes are \sym{PluginGui}, \sym{PluginIBase}
+(in \file{plugin.h}) and \sym{OscIF} (in \sym{osc.h}).
+
+If the user changes a GUI element, first the corresponding control is
+disabled, making MusE not steadily update it through automation
+while the user operates it. Then MusE will update the plugin's parameter
+value, and also record the new value. When appropriate, the controller
+is enabled again.
+
+\paragraph{Processing the input, recording}
+Upon operating a slider, \sym{PluginIBase::setParam} is called,
+which usually writes the control change into the ringbuffer
+\sym{PluginI::{\_}controlFifo}. (\sym{PluginI::apply()},
+\sym{DssiSynthIF::getData()} will read this ringbuffer and
+do the processing accordingly). Furthermore, \sym{AudioTrack::recordAutomation}
+is called, which either directly modifies the controller lists or writes
+the change into a "to be recorded"-list (\sym{AudioTrack::{\_}recEvents})
+(depending on whether the song is stopped or played).
+
+The \sym{AudioTrack::{\_}recEvents} list consists of \sym{CtrlRecVal}
+items (see \file{ctrl.h}), which hold the following data:
+\begin{itemize}
+\item the frame where the change occurred
+\item the value
+\item the type, which can be \usym{ARVT{\_}START}, \usym{ARVT{\_}VAL} or \usym{ARVT{\_}STOP}.
+ \usym{ARVT{\_}VAL} are written by every \usym{AudioTrack::recordAutomation}
+ call, \usym{ARVT{\_}START} and \usym{ARVT{\_}STOP} are generated by
+ \sym{AudioTrack::startAutoRecord} and \sym{stopAutoRecord}, respectively.
+\item and the id of the controller which is affected
+\end{itemize}
+It is processed when the song is stopped. The call path for this is:
+\sym{Song::stopRolling} calls \sym{Song::processAutomationEvents}
+calls \sym{AudioTrack::processAutomationEvents}.
+This function removes the old events from the track's controller list
+and replaces them with the new events from \sym{{\_}recEvents}. In
+\usym{AUTO{\_}WRITE} mode, just all controller events within the recorded
+range are erased; in \usym{AUTO{\_}TOUCH} mode, the \usym{ARVT{\_}START}
+and \usym{ARVT{\_}STOP} types of the \sym{CtrlRecVal} events are used
+to determine the range(s) which should be wiped.
+
+\paragraph{How it's stored}
+Automation data is kept % this is copied from
+in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList}, % "design decisions" -> "automation"
+that is, a list of \sym{CtrlList}s, that is, a list of lists of
+controller-objects which hold the control points of the automation graph.
+The \sym{CtrlList} also stores whether the list is meant discrete
+(a new control point results in a value-jump) or continuous (a new control
+point results in the value slowly sloping to the new value).
+Furthermore, it stores a \sym{{\_}curVal} (accessed by \sym{curVal()}),
+which holds the currently active value, which can be different from the
+actually stored value because of user interaction. This value is also
+used when there is no stored automation data.
+
+\sym{AudioTrack::addController} and \sym{removeController} are used % TODO: swapControllerIDX??
+to add/remove whole controller types; the most important functions which
+access \sym{{\_}controller} are:
+\begin{itemize}
+\item \sym{processAutomationEvents}, \sym{recordAutomation},
+ \sym{startAutoRecord}, \sym{stopAutoRecord}: see above.
+\item \sym{seekPrevACEvent}, \sym{seekNextACEvent}, \sym{eraseACEvent},
+ \sym{eraseRangeACEvents}, \sym{addACEvent}, \sym{changeACEvent},
+ which do the obvious
+\item \sym{pluginCtrlVal}, \sym{setPluginCtrlVal}: the first
+ returns the current value according to the \sym{{\_}controller}
+ list, the second only sets the \sym{curVal}, but does not
+ insert any events.
+\end{itemize}
+
+Whenever a \sym{CtrlList} has been manipulated,
+\sym{MusEGlobal::song->controllerChange(Track{*})} shall be called,
+which emits the \sym{MusEGlobal::song->controllerChanged(Track{*})}
+signal in order to inform any parts of MusE about the change (currently,
+only the arranger's part canvas utilizes this).
+
+\paragraph{Enabling and disabling controllers}
+Disabling the controller is both dependent from the current automation
+mode and from whether the GUI is native or not.
+In \usym{AUTO{\_}WRITE} mode, once a slider is touched (for MusE-GUIs) or
+once a OSC control change is received (for native GUIs), the control
+is disabled until the song is stopped or seeked.
+
+In \usym{AUTO{\_}TOUCH} (and currently (r1492) \usym{AUTO{\_}READ}, but
+that's to be fixed) mode, once a MusE-GUI's slider is pressed down, the
+corresponding control is disabled. Once the slider is released, the
+control is re-enabled again. Checkboxes remain in "disabled" mode,
+however they only affect the recorded automation until the last toggle
+of the checkbox. (Example: start the song, toggle the checkbox, toggle
+it again, wait 10 seconds, stop the song. This will NOT overwrite the
+last 10 seconds of automation data, but everything between the first
+and the last toggle.). For native GUIs, this is a bit tricky, because
+we don't have direct access to the GUI widgets. That is, we have no
+way to find out whether the user doesn't touch a control at all, or
+whether he has it held down, but just doesn't operate it. The current
+behaviour for native GUIs is to behave like in \usym{AUTO{\_}WRITE} mode.
+
+The responsible functions are: \sym{PluginI::oscControl} and
+\sym{DssiSynthIF::oscControl} for handling native GUIs,
+\sym{PluginI::ctrlPressed} and \sym{ctrlReleased} for MusE
+default GUIs and \sym{PluginI::guiParamPressed},
+\sym{guiParamReleased}, \sym{guiSliderPressed} and
+\sym{guiSliderReleased} for MusE GUIs read from a UI file;
+\sym{guiSlider{*}} obviously handle sliders, while \sym{guiParam{*}}
+handle everything else which is not a slider. They call
+\sym{PluginI::enableController} to enable/disable it.
+
+Furthermore, on every song stop or seek, \sym{PluginI::enableAllControllers}
+is called, which re-enables all controllers again. The call paths for
+this are:
+\begin{itemize}
+\item For stop: \sym{Song::stopRolling} calls
+ \sym{Song::processAutomationEvents} calls
+ \sym{Song::clearRecAu{\-}to{\-}ma{\-}tion} calls
+ \sym{Track::clearRecAutomation} calls
+ \sym{PluginI::enableAllControllers}
+\item For seek: \sym{Audio::seek} sends a message ("\sym{G}") to
+ \sym{Song::seqSignal} which calls
+ \sym{Song::clearRecAutomation} which calls
+ \sym{PluginI::enableAllControllers}
+\end{itemize}
+
+
+
+
+\chapter{Design decisions}
+\section{Automation}
+As of revision 1490, automation is handled in two ways: User-generated
+(live) automation data (generated by the user moving sliders while playing)
+is fed into \sym{PluginI::{\_}controlFifo}. Automation data is kept
+in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList},
+that is, a list of \sym{CtrlList}s, that is, a list of lists of
+controller-objects which hold the control points of the automation graph.
+The \sym{CtrlList} also stores whether the list is meant discrete
+(a new control point results in a value-jump) or continous (a new control
+point results in the value slowly sloping to the new value).
+
+While \sym{PluginI::{\_}controlFifo} can be queried very quickly and
+thus is processed with a very high resolution (only limited by the
+minimum control period setting), the automation value are expensive to
+query, and are only processed once in an audio \emph{driver} period.
+This might lead to noticeable jumps in value.
+
+This could possibly be solved in two ways:
+\paragraph{Maintaining a slave control list}
+This approach would maintain a fully redundant slave control list,
+similar to \sym{PluginI::{\_}controlFifo}. This list must be updated
+every time any automation-related thing is changed, and shall contain
+every controller change as a tuple of controller number and value.
+This could be processed in the same loop as \sym{PluginI::{\_}controlFifo},
+making it comfortable to implement; furthermore, it allows to cleanly
+offer automation-settings at other places in future (such as storing
+automation data in parts or similar).
+
+\paragraph{Holding iterators}
+We also could hold a list of iterators of the single \sym{CtrlList}s.
+This would also cause low CPU usage, because usually, the iterators only
+need to be incremented once. However, it is pretty complex to implement,
+because the iterators may become totally wrong (because of a seek in the
+song), and we must iterate through a whole list of iterators.
+
+\paragraph{Just use the current data access functions}
+By just using the current functions for accessing automation data,
+we might get a quick-and-dirty solution, which however wastes way too
+much CPU ressources. This is because on \emph{every single frame}, we
+need to do a binary search on multiple controller lists.
+
+
+\chapter{Feature requests}
+\section{Per-Part automation and more on automation} % by flo
+Automation shall be undo-able. Automation shall reside in parts which
+are exchangeable, clonable etc (like the MIDI- and Wave-Parts).
+Global per-synth/per-audiotrack automation shall also be available, but
+this can also be implemented as special case of part automation (one
+long part).
+
+\section{Pre-Rendering tracks}
+\subsection{The feature}
+All tracks shall be able to be "pre-renderable". Pre-rendering shall
+be "layered". Pre-rendering shall act like a transparent audio cache:
+Audio data is (redundantly) stored, wasting memory in order to save CPU.
+
+That is: Each track owns one or more wave-recordings of the length of
+the song. If the user calls "pre-render" on a track, then this track
+is played quasi-solo (see below), and the raw audio data is recorded
+and stored in the "layer 0" wave recording. If the user has any effects
+set up to be applied, then each effect is applied on a different layer
+(creating layer 1, layer 2 etc).
+
+This means, that also MIDI and drum tracks can have effects (which
+usually only operate on audio, but we HAVE audio data because of this
+prerendering).
+
+Furthermore, MusE by default does not send MIDI events to the synthesizers
+but instead just plays back the last layer of the prerecording (for
+MIDI tracks), or does not pipe the audio data through the whole plugin
+chain (causing cpu usage), but instead just plays back the last layer.
+The hearable result shall be the same.
+
+Once the user changes any parameter (automation data or plugins for
+wave tracks, MIDI events or effect plugin stuff for MIDI tracks),
+then MusE shall generate the sound for this particular track in the
+"old" way (send MIDI data to synthes, or pipe audio data through plugins).
+(So that the user will not even notice that MusE actually pre-renderered
+stuff.) Either MusE automatically records this while playback (if possible)
+or prompts the user to accordingly set up his cabling and then record
+it. Or (temporarily) disables prerecording for this track, falling back
+to the plain old way of generating sound.
+
+\emph{Quasi-solo} means: For wave tracks, just solo the track. For MIDI
+tracks, mute all tracks which are not on the same synth (channel?),
+and mute all \emph{note} events which are not on the quasi-soloed track.
+This causes MusE to still play any controller events from different
+tracks, because they might have effects on the quasi-soloed track. (You
+can have notes on channel 1 on one track and controller stuff on channel
+1 on another track; then you would need quasi-solo to get proper results.)
+
+\subsection{Use cases}
+\paragraph{Saving CPU}
+On slow systems, this is neccessary for songs with lots of, or demanding
+(or both) soft synthes / plugins. Even if the synth or plugin is so
+demanding that your system is not able to produce sound in real-time,
+then with this feature you'll be able to use the synth (this will make
+editing pretty laggish, because for a change you need to re-render at
+least a part before you can listen to it, but better than being unable
+to use the synth at all!)
+
+\paragraph{Exporting as audio project}
+Using pre-rendering on all tracks, you easily can export your project
+as multi-track audio file (for use with Ardour or similar DAWs).
+Just take the last layer of each track, and write the raw audio data
+into the file, and you're done. (Maybe we are even able to write down
+the raw-raw layer0 audio data plus information about used plugins and
+settings etc..?)
+
+\paragraph{Mobile audio workstations}
+You might want to work a bit on your audio projects on your notebook
+while you're not at home, not having access to your hardware synthesizers.
+Using this feature, you could have pre-recorded the stuff in your studio
+before, and now can at least fiddle around with the non-hw-synth-dependent
+parts of your song, while still having your \emph{full} song with you.
+
+\paragraph{Applying effects on MIDI tracks}
+If you have many physical audio inputs, you might already be able to
+apply effect chains on MIDI tracks, by wiring the synthes' audio
+outputs to your soundcard's inputs, and applying the effects on
+dedicated input tracks you have to create. This requires you to have
+expensive hardware, and is pretty complicated, because you need one
+additional track per MIDI synth.
+
+This feature allows you to apply effects on single MIDI tracks, and not
+only on full MIDI synthes, and doesn't require you to be have that
+many physical audio inputs (you need to manually replug your synthes,
+however).
+
+\subsection{Possible scenarios}
+\paragraph{Setting it up}
+Create a wave track, MusE will allow you to set or unset prerendering
+for every plugin in the plugin rack (recording the actual track is
+useless because it would be a plain copy).
+Create a MIDI track, MusE will ask you on which physical audio input
+your synth is connected. Setting up multiple synthes on one physical
+audio in is allowed, see below.
+
+\paragraph{Pre-rendering stuff}
+When the user presses the "pre-render" button, all tracks which have
+been changed since their last pre-rendering will be re-rendered.
+If you have multiple hardware synthes set up as they were connected
+to one physical audio input port, MusE will prompt you to first plug
+the proper cable in.
+
+\paragraph{Making changes}
+Change a note in a MIDI part, move or delete a part or change automation
+parameters. MusE will temporarily disable the pre-rendered information
+and instead generate the sound via sending out MIDI events, piping stuff
+through effect chains or similar. If you play back the whole song, or
+if you manually trigger a re-rendering of a track via the context menu,
+MusE will play back the stuff, record it again and re-enable the
+pre-rendered information.
+
+
+\subsection{Extensions}
+\paragraph{Automatic discovery of physical audio connections}
+The user plugs all (or only some) synthes' audio outs into the available
+audio inputs, then runs automatic discovery. This will send MIDI events
+to each synthesizer, and look on which audio in there's activity. Then
+it will assume that the synthesizer is connected to that particular
+audio in. Audio ins which show activity before any MIDI events were
+sent are not considered, as they're probably connected to microphones
+or other noise-generating non-synthes.
+
+\paragraph{Audio export}
+As described in the Use cases, MusE can allow you to export your song
+in some multitrack audio format.
+
+\paragraph{Cheap/Faked changes}
+For expensive or unavailable synthes, changing the Volume midi controller,
+the Pan controller or similar "easy" controllers will not trigger a
+complete re-rendering, but instead "fake" the change, by changing
+the volume data directly on the recorded wave. This might require some
+learning and might even get pretty complicated.
+
+\paragraph{Intelligent re-recording}
+For tiny changes, MusE shall only re-render the relevant part. If you
+change some MIDI notes, then begin re-recording shortly before the
+changes, and end re-recording as soon as the recorded stuff doesn't
+differ to much from the stuff coming from the synth. Then properly
+blend the old recording with the updated part.
+
+
+
+\section{Slotted editors}
+Currently, MusE has the pianoroll editor, drum editor, score editor,
+then the controller editor which is inside the pianoroll/drum editor.
+All these editors have a very similar concept: the "time axis" is
+vertical and (almost) linear, they handle parts, and events are
+manipulated similarly.
+
+A unified editor shall be created which allows you to combine different
+kinds of editors in one window, properly aligned against each other.
+These "different kinds of editors" shall be handled as "slots"; one
+unified editor window consists of:
+\begin{itemize}
+\item A menu bar, containing stuff suitable for the complete window,
+ which might include window name, MDI-ness etc.
+\item A toolbar which contains controls suitable for every single slot.
+\item A container with one or more slots; the slots can be scrolled in
+ y-direction if there are multipe slots.
+\item A time-scrollbar with zoom
+\end{itemize}
+
+Each slot contains the following:
+\begin{itemize}
+\item A menu button, button box or control panel for setting up this
+ particular slot. This could contain "note head colors", "show
+ a transposing instrument" etc for score edit slots, "event
+ rectangle color", "grid size" and "snap to grid" for pianoroll/
+ drum editors.
+\item The actual canvas
+\item A y-direction scroll bar, possibly with zoom control (for
+ pianoroll editor)
+\end{itemize}
+
+The main window does not show its scroll bar if there is only one slot,
+because the slot's scrollbar is sufficient then.
+
+Slots can be added, destroyed, moved around, maybe even merged (if the
+slot types allow it); basically, you can compare them with the staves
+in the score editor.
+
+The slots shall align against each other, that is, if a score editor
+slot displays a key change with lots of accidentials, then all other
+slots shall either also display the key change (if they're score slots)
+or display a gap. Events which happen at the same time shall be at the
+same x-coordinate, regardless which slot they are.
+
+\section{Controller master values}
+All controllers (MIDI-controllers and also automation controllers)
+shall have one set of "master values" which allow you to set a gain and
+a bias. Instead of the actual set value, $\textrm{value} * \textrm{bias}
++ textrm{bias}$ shall be sent to the MIDI device / the plugin. For
+controllers like "pan", the unbiased values shall be transformed, that
+is, a pan of 64, with $\textrm{bias}=2$ and $\textrm{gain}=0.5$, shall
+be transformed to 66 (because 64 is actually 0, while 0 is actually -64).
+These values shall be set in the arranger and whereever the actual
+controller/automation values can be edited.
+
+\section{Enabled-indicator while recording}
+The MusE-plugin-GUIs shall display a small LED displaying whether a
+controller is currently enabled or disabled. By clicking this LED, the
+enabled state shall be switched.
+
+Furthermore, there shall be a dedicated window which only lets you switch
+enabled/disabled states. This will be useful when using external GUIs
+or the MIDI-controller-to-automation feature, to re-enable a controller
+when in \usym{AUTO{\_}TOUCH} mode.
+
+
+
+\section{Linear automation editing}
+While holding some modifier key (like shift), operating the MusE-native-
+GUI sliders shall only generate control points when clicking and when
+releasing the slider. This will result in linear graphs for continous
+controllers, and in large steps for discrete controllers (which is in
+particular useful for stuff like "which low/high-pass filter type to use").
+
+Maybe make this behaviour default for discrete controllers?
+
+\section{Symbolic names for MIDI ports} \label{symbolic_ports}
+MIDI ports shall have a user-defined symbolic name (like "Korg" or "Yamaha DX 7").
+The mapping between these symbolic names and the hardware port (like
+"ALSA midi out port") is stored in the global configuration.
+
+Song files only specify the symbolic names as the ports associated with
+their tracks. No information about physical devices/port names, but only
+symbolic names are stored in the song file.
+
+This resolves the issues mentioned in \ref{portconfig_sucks}, and also
+allows the user to share his pieces with other people: They would only
+have to set up that symbolic-to-hardware mapping once (collisions are
+unlikely, because an equal symbolic name should usually mean the same
+device) and are happy, instead of having to re-map \emph{every} port
+for \emph{every} song.
+
+\end{document}
+
+% TODO: song type etc? kill it!
+% song len box: same
+
+% TODO: unified automation and midi ctrls:
+% both shall be editable through the same editors
+% four modes: 1. discrete
+% 2. continous (plus a global and per-port setting for the max rate)
+% 3. switch (not necessarily ON/OFF; signals with color plus text annotation)
+% 4. raw (no graph, instead a box with the value sent out (for "all voices off")
+% they shall be copy-and-pastable, at least between compatible modes
+% they shall be slotted, like pianoroll
+% maybe also "overlapping", like arranger (?)
+% midi recording tries to make out straight lines (like non-ended automation streams)
+%
+
+
+% new song (in general: load as template) plus "overwrite port config"
+% should re-create the default jack devices and autoconnect them.
+
+% what's audio aux for?
+
+% bug in arranger/pcanvas/automation: if a controlpoint is directly on
+% a line of another ctrl graph, you can't click it
+
diff --git a/muse2/doc/documentation.tex b/muse2/doc/documentation.tex
index 37dbafc5..a6fe929b 100644
--- a/muse2/doc/documentation.tex
+++ b/muse2/doc/documentation.tex
@@ -111,10 +111,6 @@
\renewcommand{\headrulewidth}{0.4pt}
\usepackage{ifthen}
-%% Borrowed from Lyx output. "Because html converters don't know
-%% tabularnewline". Is required? Maybe replace with \\ ?
-\providecommand{\tabularnewline}{\\}
-
% Hyphenate symbols before each uppercase letter, after each underscore
% (without a "-") and after each ':' (without a "-")
% TODO for any latex crack: also do automatic hyphenation, that is,
@@ -1058,29 +1054,29 @@ output, MusE uses the first input or output and ignores the rest.
For stereo tracks:
\begin{tabular}{|c|c|c|c|c|}
-\hline
+\hline
plugin inputs & outputs & copies & track in route channels &
-track out route channels\tabularnewline
-\hline
-\hline
-0 & 0 & 1 & 0 & 0\tabularnewline
-\hline
-0 & 1 & 2 & 0 & 2\tabularnewline
-\hline
-0 & >=2 & 1 & 0 & 2\tabularnewline
-\hline
-1 & 0 & 2 & 2 & 0\tabularnewline
-\hline
-1 & 1 & 2 & 2 & 2\tabularnewline
-\hline
-1 & >=2 & 1 & 1 (L only) & 2\tabularnewline
-\hline
->=2 & 0 & 1 & 2 & 0\tabularnewline
-\hline
->=2 & 1 & 2 & 2 & 2\tabularnewline
-\hline
->=2 & >=2 & 1 & 2 & 2\tabularnewline
-\hline
+track out route channels\\
+\hline
+\hline
+0 & 0 & 1 & 0 & 0\\
+\hline
+0 & 1 & 2 & 0 & 2\\
+\hline
+0 & >=2 & 1 & 0 & 2\\
+\hline
+1 & 0 & 2 & 2 & 0\\
+\hline
+1 & 1 & 2 & 2 & 2\\
+\hline
+1 & >=2 & 1 & 1 (L only) & 2\\
+\hline
+>=2 & 0 & 1 & 2 & 0\\
+\hline
+>=2 & 1 & 2 & 2 & 2\\
+\hline
+>=2 & >=2 & 1 & 2 & 2\\
+\hline
\end{tabular}
Notice that on a stereo track with a plugin having one audio input and
@@ -1125,544 +1121,5 @@ For example, for a plugin having one audio input and one audio output,
feeding a plugin having one audio input and two audio outputs,
the extra copy of the first plugin is redundant and not required,
but currently it is created anyway.
-
-
-\chapter{Internals -- how it works}
-This chapter explains how MusE is built internally, and is meant
-to be an aid for developers wanting to quickly start up with MusE.
-For details on \emph{why} stuff is done please refer to the following
-chapter.
-
-\section{User interface programming}
-We use the QT Toolkit for GUI- and other programming. The \emph{QT-Assistant}
-is an important tool for getting help. Almost everything can be looked
-up there.
-
-GUIs can be either be hardcoded (see \file{arranger.cpp} for an example)
-or can be created using \emph{QT-Designer} (see the dialogs under
-\file{widgets/function_dialogs/} for mostly cleanly-written examples).
-Don't forget to add your \file{cpp}, \file{h} and \file{ui} files to the
-corresponding sections in the \file{CMakeLists.txt}!
-
-Additionally, MusE offers some custom widgets, like menu title items etc.
-Following, there will be a small, unordered list about custom widgets:
-\begin{itemize}
-\item \sym{MusEGui::MenuTitleItem}: Provides a title-bar in a \sym{QMenu}. \\
- Usage: \listing{someMenu->addAction(new\ MusEGui::MenuTitleItem(tr("fnord"),\ someMenu));} \\
- Defined in \file{widgets/menutitleitem.h}.
-\item \sym{MusEGui::PopupMenu}: Provides a \sym{QMenu}-like menu which
- can stay open after the user checks a checkable action.\\
- Usage: just create a \listing{new\ PopupMenu(\ true|false\ )} instead of
- a \listing{new\ QMenu()}. (\listing{true} means 'stay open')\\
- Defined in \file{widgets/popupmenu.h}.
-\end{itemize}
-
-
-\section{Configuration} \label{portconfig_sucks}
-Configuration is a bit pesky in MusE in its current state. If you get
-confused by reading this chapter, that's a sign of a sane mind.
-
-There are three kinds of configuration items:
-\begin{itemize}
-\item (1) Global configuration, like coloring schemes, plugin categories, MDI-ness settings
-\item (2) Per-Song configuration, like whether to show or hide certain track types in the arranger
-\item (3) Something in between, like MIDI port settings etc. They obviously actually are
- global configuration issues (or ought to be), but also obviously must be stored
- in the song file for portability. (This problem could possibly be solved by
- the feature proposal in \ref{symbolic_ports}.
-\end{itemize}
-
-\paragraph{Reading configuration}
-\sym{void\ MusECore::readConfiguration(Xml\&,\ bool,\ bool)} in
-\file{conf.cpp} is the central point
-of reading configuration. It is called when MusE is started first
-(by \sym{bool\ MusECore::readConfiguration()}), and also when a
-song is loaded. \\ %TODO: call paths!
-It can be instructed whether to read MIDI ports (3), global configuration
-and MIDI ports (1+3). Per-Song configuration is always read (2).
-
-When adding new configuration items and thus altering \sym{readConfiguration()},
-you must take care to place your item into the correct section. The code is
-divided into the following sections:
-\begin{itemize}
-\item Global and/or per-song configuration (3)
-\item Global configuration (1)
-\item Code for skipping obsolete entries
-\end{itemize}
-
-The sections are divided by comments (they contain \texttt{----}, so just
-search for them). Please do not just remove code for reading obsolete entries,
-but always add an appropriate entry to the 'skipping' section in order to
-prevent error messages when reading old configs.
-
-\paragraph{Writing configuration}
-Global configuration is written using the
-\sym{MusEGui::MusE::writeGlobalConfiguration()} functions, while
-per-song-config is written by \sym{MusEGui::MusE::writeConfiguration()}
-(notice the missing \sym{Global}; both implemented in \file{conf.cpp}).
-
-\sym{writeConfiguration} is actually just a subset of the code in
-\sym{writeGlobalConfiguration}. \textbf{Duplicate code!} % TODO fix that in the sourcecode.
-
-\paragraph{Song state}
-Additionally to per-song configuration, there is the song's state.
-This contains "the song", that is all tracks, parts and note events,
-together with information about the currently opened windows, their
-position, size, settings and so on. Adding new items here is actually
-pretty painless: Configuration is read and written using
-\sym{MusECore::Song::read} and \sym{::write}, both implemented in
-\file{songfile.cpp}. There are no caveats.
-
-\paragraph{How to add new items}
-When adding global configuration items, then add them into the second
-block ("global configuration") in \sym{readConfiguration} and into
-\sym{writeGlobalConfiguration}.
-
-When adding just-per-song items, better don't bother to touch the
-"configuration" code and just add it to the song's state (there might
-be rare exceptions).
-
-When adding global configuration items, make sure you add them into the
-correct section of \sym{readConfiguration}, and into \sym{writeGlobalConfiguration}.
-
-
-%TODO: how to write config,
-%TODO: song/global stuff
-%TODO: config lesen und schreiben fuer plugingroups
-
-
-\section{User controls and automation}
-\subsection{Handling user input}
-\subsubsection{Plugins and synthesizers}
-\paragraph{Overview}
-When the user launches a plugin's GUI, either a MusE-window with
-the relevant controls is shown, or the native GUI is launched. MusE
-will communicate with this native GUI through OSC (Open Sound Control).
-The relevant classes are \sym{PluginGui}, \sym{PluginIBase}
-(in \file{plugin.h}) and \sym{OscIF} (in \sym{osc.h}).
-
-If the user changes a GUI element, first the corresponding control is
-disabled, making MusE not steadily update it through automation
-while the user operates it. Then MusE will update the plugin's parameter
-value, and also record the new value. When appropriate, the controller
-is enabled again.
-
-\paragraph{Processing the input, recording}
-Upon operating a slider, \sym{PluginIBase::setParam} is called,
-which usually writes the control change into the ringbuffer
-\sym{PluginI::{\_}controlFifo}. (\sym{PluginI::apply()},
-\sym{DssiSynthIF::getData()} will read this ringbuffer and
-do the processing accordingly). Furthermore, \sym{AudioTrack::recordAutomation}
-is called, which either directly modifies the controller lists or writes
-the change into a "to be recorded"-list (\sym{AudioTrack::{\_}recEvents})
-(depending on whether the song is stopped or played).
-
-The \sym{AudioTrack::{\_}recEvents} list consists of \sym{CtrlRecVal}
-items (see \file{ctrl.h}), which hold the following data:
-\begin{itemize}
-\item the frame where the change occurred
-\item the value
-\item the type, which can be \usym{ARVT{\_}START}, \usym{ARVT{\_}VAL} or \usym{ARVT{\_}STOP}.
- \usym{ARVT{\_}VAL} are written by every \usym{AudioTrack::recordAutomation}
- call, \usym{ARVT{\_}START} and \usym{ARVT{\_}STOP} are generated by
- \sym{AudioTrack::startAutoRecord} and \sym{stopAutoRecord}, respectively.
-\item and the id of the controller which is affected
-\end{itemize}
-It is processed when the song is stopped. The call path for this is:
-\sym{Song::stopRolling} calls \sym{Song::processAutomationEvents}
-calls \sym{AudioTrack::processAutomationEvents}.
-This function removes the old events from the track's controller list
-and replaces them with the new events from \sym{{\_}recEvents}. In
-\usym{AUTO{\_}WRITE} mode, just all controller events within the recorded
-range are erased; in \usym{AUTO{\_}TOUCH} mode, the \usym{ARVT{\_}START}
-and \usym{ARVT{\_}STOP} types of the \sym{CtrlRecVal} events are used
-to determine the range(s) which should be wiped.
-
-\paragraph{How it's stored}
-Automation data is kept % this is copied from
-in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList}, % "design decisions" -> "automation"
-that is, a list of \sym{CtrlList}s, that is, a list of lists of
-controller-objects which hold the control points of the automation graph.
-The \sym{CtrlList} also stores whether the list is meant discrete
-(a new control point results in a value-jump) or continuous (a new control
-point results in the value slowly sloping to the new value).
-Furthermore, it stores a \sym{{\_}curVal} (accessed by \sym{curVal()}),
-which holds the currently active value, which can be different from the
-actually stored value because of user interaction. This value is also
-used when there is no stored automation data.
-
-\sym{AudioTrack::addController} and \sym{removeController} are used % TODO: swapControllerIDX??
-to add/remove whole controller types; the most important functions which
-access \sym{{\_}controller} are:
-\begin{itemize}
-\item \sym{processAutomationEvents}, \sym{recordAutomation},
- \sym{startAutoRecord}, \sym{stopAutoRecord}: see above.
-\item \sym{seekPrevACEvent}, \sym{seekNextACEvent}, \sym{eraseACEvent},
- \sym{eraseRangeACEvents}, \sym{addACEvent}, \sym{changeACEvent},
- which do the obvious
-\item \sym{pluginCtrlVal}, \sym{setPluginCtrlVal}: the first
- returns the current value according to the \sym{{\_}controller}
- list, the second only sets the \sym{curVal}, but does not
- insert any events.
-\end{itemize}
-
-Whenever a \sym{CtrlList} has been manipulated,
-\sym{MusEGlobal::song->controllerChange(Track{*})} shall be called,
-which emits the \sym{MusEGlobal::song->controllerChanged(Track{*})}
-signal in order to inform any parts of MusE about the change (currently,
-only the arranger's part canvas utilizes this).
-
-\paragraph{Enabling and disabling controllers}
-Disabling the controller is both dependent from the current automation
-mode and from whether the GUI is native or not.
-In \usym{AUTO{\_}WRITE} mode, once a slider is touched (for MusE-GUIs) or
-once a OSC control change is received (for native GUIs), the control
-is disabled until the song is stopped or seeked.
-
-In \usym{AUTO{\_}TOUCH} (and currently (r1492) \usym{AUTO{\_}READ}, but
-that's to be fixed) mode, once a MusE-GUI's slider is pressed down, the
-corresponding control is disabled. Once the slider is released, the
-control is re-enabled again. Checkboxes remain in "disabled" mode,
-however they only affect the recorded automation until the last toggle
-of the checkbox. (Example: start the song, toggle the checkbox, toggle
-it again, wait 10 seconds, stop the song. This will NOT overwrite the
-last 10 seconds of automation data, but everything between the first
-and the last toggle.). For native GUIs, this is a bit tricky, because
-we don't have direct access to the GUI widgets. That is, we have no
-way to find out whether the user doesn't touch a control at all, or
-whether he has it held down, but just doesn't operate it. The current
-behaviour for native GUIs is to behave like in \usym{AUTO{\_}WRITE} mode.
-
-The responsible functions are: \sym{PluginI::oscControl} and
-\sym{DssiSynthIF::oscControl} for handling native GUIs,
-\sym{PluginI::ctrlPressed} and \sym{ctrlReleased} for MusE
-default GUIs and \sym{PluginI::guiParamPressed},
-\sym{guiParamReleased}, \sym{guiSliderPressed} and
-\sym{guiSliderReleased} for MusE GUIs read from a UI file;
-\sym{guiSlider{*}} obviously handle sliders, while \sym{guiParam{*}}
-handle everything else which is not a slider. They call
-\sym{PluginI::enableController} to enable/disable it.
-
-Furthermore, on every song stop or seek, \sym{PluginI::enableAllControllers}
-is called, which re-enables all controllers again. The call paths for
-this are:
-\begin{itemize}
-\item For stop: \sym{Song::stopRolling} calls
- \sym{Song::processAutomationEvents} calls
- \sym{Song::clearRecAu{\-}to{\-}ma{\-}tion} calls
- \sym{Track::clearRecAutomation} calls
- \sym{PluginI::enableAllControllers}
-\item For seek: \sym{Audio::seek} sends a message ("\sym{G}") to
- \sym{Song::seqSignal} which calls
- \sym{Song::clearRecAutomation} which calls
- \sym{PluginI::enableAllControllers}
-\end{itemize}
-
-
-
-
-\chapter{Design decisions}
-\section{Automation}
-As of revision 1490, automation is handled in two ways: User-generated
-(live) automation data (generated by the user moving sliders while playing)
-is fed into \sym{PluginI::{\_}controlFifo}. Automation data is kept
-in \sym{AudioTrack::{\_}controller}, which is a \sym{CtrlListList},
-that is, a list of \sym{CtrlList}s, that is, a list of lists of
-controller-objects which hold the control points of the automation graph.
-The \sym{CtrlList} also stores whether the list is meant discrete
-(a new control point results in a value-jump) or continous (a new control
-point results in the value slowly sloping to the new value).
-
-While \sym{PluginI::{\_}controlFifo} can be queried very quickly and
-thus is processed with a very high resolution (only limited by the
-minimum control period setting), the automation value are expensive to
-query, and are only processed once in an audio \emph{driver} period.
-This might lead to noticeable jumps in value.
-
-This could possibly be solved in two ways:
-\paragraph{Maintaining a slave control list}
-This approach would maintain a fully redundant slave control list,
-similar to \sym{PluginI::{\_}controlFifo}. This list must be updated
-every time any automation-related thing is changed, and shall contain
-every controller change as a tuple of controller number and value.
-This could be processed in the same loop as \sym{PluginI::{\_}controlFifo},
-making it comfortable to implement; furthermore, it allows to cleanly
-offer automation-settings at other places in future (such as storing
-automation data in parts or similar).
-
-\paragraph{Holding iterators}
-We also could hold a list of iterators of the single \sym{CtrlList}s.
-This would also cause low CPU usage, because usually, the iterators only
-need to be incremented once. However, it is pretty complex to implement,
-because the iterators may become totally wrong (because of a seek in the
-song), and we must iterate through a whole list of iterators.
-
-\paragraph{Just use the current data access functions}
-By just using the current functions for accessing automation data,
-we might get a quick-and-dirty solution, which however wastes way too
-much CPU ressources. This is because on \emph{every single frame}, we
-need to do a binary search on multiple controller lists.
-
-
-\chapter{Feature requests}
-\section{Per-Part automation and more on automation} % by flo
-Automation shall be undo-able. Automation shall reside in parts which
-are exchangeable, clonable etc (like the MIDI- and Wave-Parts).
-Global per-synth/per-audiotrack automation shall also be available, but
-this can also be implemented as special case of part automation (one
-long part).
-
-\section{Pre-Rendering tracks}
-\subsection{The feature}
-All tracks shall be able to be "pre-renderable". Pre-rendering shall
-be "layered". Pre-rendering shall act like a transparent audio cache:
-Audio data is (redundantly) stored, wasting memory in order to save CPU.
-
-That is: Each track owns one or more wave-recordings of the length of
-the song. If the user calls "pre-render" on a track, then this track
-is played quasi-solo (see below), and the raw audio data is recorded
-and stored in the "layer 0" wave recording. If the user has any effects
-set up to be applied, then each effect is applied on a different layer
-(creating layer 1, layer 2 etc).
-
-This means, that also MIDI and drum tracks can have effects (which
-usually only operate on audio, but we HAVE audio data because of this
-prerendering).
-
-Furthermore, MusE by default does not send MIDI events to the synthesizers
-but instead just plays back the last layer of the prerecording (for
-MIDI tracks), or does not pipe the audio data through the whole plugin
-chain (causing cpu usage), but instead just plays back the last layer.
-The hearable result shall be the same.
-
-Once the user changes any parameter (automation data or plugins for
-wave tracks, MIDI events or effect plugin stuff for MIDI tracks),
-then MusE shall generate the sound for this particular track in the
-"old" way (send MIDI data to synthes, or pipe audio data through plugins).
-(So that the user will not even notice that MusE actually pre-renderered
-stuff.) Either MusE automatically records this while playback (if possible)
-or prompts the user to accordingly set up his cabling and then record
-it. Or (temporarily) disables prerecording for this track, falling back
-to the plain old way of generating sound.
-
-\emph{Quasi-solo} means: For wave tracks, just solo the track. For MIDI
-tracks, mute all tracks which are not on the same synth (channel?),
-and mute all \emph{note} events which are not on the quasi-soloed track.
-This causes MusE to still play any controller events from different
-tracks, because they might have effects on the quasi-soloed track. (You
-can have notes on channel 1 on one track and controller stuff on channel
-1 on another track; then you would need quasi-solo to get proper results.)
-
-\subsection{Use cases}
-\paragraph{Saving CPU}
-On slow systems, this is neccessary for songs with lots of, or demanding
-(or both) soft synthes / plugins. Even if the synth or plugin is so
-demanding that your system is not able to produce sound in real-time,
-then with this feature you'll be able to use the synth (this will make
-editing pretty laggish, because for a change you need to re-render at
-least a part before you can listen to it, but better than being unable
-to use the synth at all!)
-
-\paragraph{Exporting as audio project}
-Using pre-rendering on all tracks, you easily can export your project
-as multi-track audio file (for use with Ardour or similar DAWs).
-Just take the last layer of each track, and write the raw audio data
-into the file, and you're done. (Maybe we are even able to write down
-the raw-raw layer0 audio data plus information about used plugins and
-settings etc..?)
-
-\paragraph{Mobile audio workstations}
-You might want to work a bit on your audio projects on your notebook
-while you're not at home, not having access to your hardware synthesizers.
-Using this feature, you could have pre-recorded the stuff in your studio
-before, and now can at least fiddle around with the non-hw-synth-dependent
-parts of your song, while still having your \emph{full} song with you.
-
-\paragraph{Applying effects on MIDI tracks}
-If you have many physical audio inputs, you might already be able to
-apply effect chains on MIDI tracks, by wiring the synthes' audio
-outputs to your soundcard's inputs, and applying the effects on
-dedicated input tracks you have to create. This requires you to have
-expensive hardware, and is pretty complicated, because you need one
-additional track per MIDI synth.
-
-This feature allows you to apply effects on single MIDI tracks, and not
-only on full MIDI synthes, and doesn't require you to be have that
-many physical audio inputs (you need to manually replug your synthes,
-however).
-
-\subsection{Possible scenarios}
-\paragraph{Setting it up}
-Create a wave track, MusE will allow you to set or unset prerendering
-for every plugin in the plugin rack (recording the actual track is
-useless because it would be a plain copy).
-Create a MIDI track, MusE will ask you on which physical audio input
-your synth is connected. Setting up multiple synthes on one physical
-audio in is allowed, see below.
-
-\paragraph{Pre-rendering stuff}
-When the user presses the "pre-render" button, all tracks which have
-been changed since their last pre-rendering will be re-rendered.
-If you have multiple hardware synthes set up as they were connected
-to one physical audio input port, MusE will prompt you to first plug
-the proper cable in.
-
-\paragraph{Making changes}
-Change a note in a MIDI part, move or delete a part or change automation
-parameters. MusE will temporarily disable the pre-rendered information
-and instead generate the sound via sending out MIDI events, piping stuff
-through effect chains or similar. If you play back the whole song, or
-if you manually trigger a re-rendering of a track via the context menu,
-MusE will play back the stuff, record it again and re-enable the
-pre-rendered information.
-
-
-\subsection{Extensions}
-\paragraph{Automatic discovery of physical audio connections}
-The user plugs all (or only some) synthes' audio outs into the available
-audio inputs, then runs automatic discovery. This will send MIDI events
-to each synthesizer, and look on which audio in there's activity. Then
-it will assume that the synthesizer is connected to that particular
-audio in. Audio ins which show activity before any MIDI events were
-sent are not considered, as they're probably connected to microphones
-or other noise-generating non-synthes.
-
-\paragraph{Audio export}
-As described in the Use cases, MusE can allow you to export your song
-in some multitrack audio format.
-
-\paragraph{Cheap/Faked changes}
-For expensive or unavailable synthes, changing the Volume midi controller,
-the Pan controller or similar "easy" controllers will not trigger a
-complete re-rendering, but instead "fake" the change, by changing
-the volume data directly on the recorded wave. This might require some
-learning and might even get pretty complicated.
-
-\paragraph{Intelligent re-recording}
-For tiny changes, MusE shall only re-render the relevant part. If you
-change some MIDI notes, then begin re-recording shortly before the
-changes, and end re-recording as soon as the recorded stuff doesn't
-differ to much from the stuff coming from the synth. Then properly
-blend the old recording with the updated part.
-
-
-
-\section{Slotted editors}
-Currently, MusE has the pianoroll editor, drum editor, score editor,
-then the controller editor which is inside the pianoroll/drum editor.
-All these editors have a very similar concept: the "time axis" is
-vertical and (almost) linear, they handle parts, and events are
-manipulated similarly.
-
-A unified editor shall be created which allows you to combine different
-kinds of editors in one window, properly aligned against each other.
-These "different kinds of editors" shall be handled as "slots"; one
-unified editor window consists of:
-\begin{itemize}
-\item A menu bar, containing stuff suitable for the complete window,
- which might include window name, MDI-ness etc.
-\item A toolbar which contains controls suitable for every single slot.
-\item A container with one or more slots; the slots can be scrolled in
- y-direction if there are multipe slots.
-\item A time-scrollbar with zoom
-\end{itemize}
-
-Each slot contains the following:
-\begin{itemize}
-\item A menu button, button box or control panel for setting up this
- particular slot. This could contain "note head colors", "show
- a transposing instrument" etc for score edit slots, "event
- rectangle color", "grid size" and "snap to grid" for pianoroll/
- drum editors.
-\item The actual canvas
-\item A y-direction scroll bar, possibly with zoom control (for
- pianoroll editor)
-\end{itemize}
-
-The main window does not show its scroll bar if there is only one slot,
-because the slot's scrollbar is sufficient then.
-
-Slots can be added, destroyed, moved around, maybe even merged (if the
-slot types allow it); basically, you can compare them with the staves
-in the score editor.
-
-The slots shall align against each other, that is, if a score editor
-slot displays a key change with lots of accidentials, then all other
-slots shall either also display the key change (if they're score slots)
-or display a gap. Events which happen at the same time shall be at the
-same x-coordinate, regardless which slot they are.
-
-\section{Controller master values}
-All controllers (MIDI-controllers and also automation controllers)
-shall have one set of "master values" which allow you to set a gain and
-a bias. Instead of the actual set value, $\textrm{value} * \textrm{bias}
-+ textrm{bias}$ shall be sent to the MIDI device / the plugin. For
-controllers like "pan", the unbiased values shall be transformed, that
-is, a pan of 64, with $\textrm{bias}=2$ and $\textrm{gain}=0.5$, shall
-be transformed to 66 (because 64 is actually 0, while 0 is actually -64).
-These values shall be set in the arranger and whereever the actual
-controller/automation values can be edited.
-
-\section{Enabled-indicator while recording}
-The MusE-plugin-GUIs shall display a small LED displaying whether a
-controller is currently enabled or disabled. By clicking this LED, the
-enabled state shall be switched.
-
-Furthermore, there shall be a dedicated window which only lets you switch
-enabled/disabled states. This will be useful when using external GUIs
-or the MIDI-controller-to-automation feature, to re-enable a controller
-when in \usym{AUTO{\_}TOUCH} mode.
-
-
-
-\section{Linear automation editing}
-While holding some modifier key (like shift), operating the MusE-native-
-GUI sliders shall only generate control points when clicking and when
-releasing the slider. This will result in linear graphs for continous
-controllers, and in large steps for discrete controllers (which is in
-particular useful for stuff like "which low/high-pass filter type to use").
-
-Maybe make this behaviour default for discrete controllers?
-
-\section{Symbolic names for MIDI ports} \label{symbolic_ports}
-MIDI ports shall have a user-defined symbolic name (like "Korg" or "Yamaha DX 7").
-The mapping between these symbolic names and the hardware port (like
-"ALSA midi out port") is stored in the global configuration.
-
-Song files only specify the symbolic names as the ports associated with
-their tracks. No information about physical devices/port names, but only
-symbolic names are stored in the song file.
-
-This resolves the issues mentioned in \ref{portconfig_sucks}, and also
-allows the user to share his pieces with other people: They would only
-have to set up that symbolic-to-hardware mapping once (collisions are
-unlikely, because an equal symbolic name should usually mean the same
-device) and are happy, instead of having to re-map \emph{every} port
-for \emph{every} song.
-
\end{document}
-% TODO: song type etc? kill it!
-% song len box: same
-
-% TODO: unified automation and midi ctrls:
-% both shall be editable through the same editors
-% four modes: 1. discrete
-% 2. continous (plus a global and per-port setting for the max rate)
-% 3. switch (not necessarily ON/OFF; signals with color plus text annotation)
-% 4. raw (no graph, instead a box with the value sent out (for "all voices off")
-% they shall be copy-and-pastable, at least between compatible modes
-% they shall be slotted, like pianoroll
-% maybe also "overlapping", like arranger (?)
-% midi recording tries to make out straight lines (like non-ended automation streams)
-%
-
-
-% new song (in general: load as template) plus "overwrite port config"
-% should re-create the default jack devices and autoconnect them.
-
-% what's audio aux for?
-
-% bug in arranger/pcanvas/automation: if a controlpoint is directly on
-% a line of another ctrl graph, you can't click it
-
diff --git a/muse2/doc/pdf/developer_docs.pdf b/muse2/doc/pdf/developer_docs.pdf
new file mode 100644
index 00000000..65b7c1b7
--- /dev/null
+++ b/muse2/doc/pdf/developer_docs.pdf
Binary files differ
diff --git a/muse2/doc/documentation.pdf b/muse2/doc/pdf/documentation.pdf
index e14767da..6caa08cf 100644
--- a/muse2/doc/documentation.pdf
+++ b/muse2/doc/pdf/documentation.pdf
Binary files differ