Show writing.texi syntax highlighted
@node Writing applications
@chapter Writing applications
@menu
* Including libraries and linking::
* Example programs::
* Writing Qt4 applications::
* Other programming issues::
* Interoperability::
@end menu
@node Including libraries and linking
@section Including libraries and linking
@cindex Compiling, programs
@cindex Linking, programs
To use any marsyas code in your program(s), you need to include the
Marsyas libraries in your project.
@subsection ... using qmake
The easiest way to compile Marsyas programs is to use qmake. You may do
this even if you used autotools to configure Marsyas itself; the author
of this documentation uses autotools to build Marsyas, and qmake to
build his programs.
Create a @file{my_program_name.pro} file:
@example
# your files
SOURCES = my_program_name.cpp
#HEADERS += extra_file.h
#SOURCES += extra_file.cpp
DEPTH += ../../
# these files are common to every Marsyas/QT app
# you will need to update these paths (and the paths in backend.h)
# if you copy this directory elsewhere.
HEADERS += $$DEPTH/apps/Qt4Apps/MarSystemQtWrapper.h
SOURCES += $$DEPTH/apps/Qt4Apps/MarSystemQtWrapper.cpp
#MARSYAS_INSTALL_DIR = $@{HOME@}/usr/
MARSYAS_INSTALL_DIR = /usr/local
message("If Marsyas was installed, it went into $$MARSYAS_INSTALL_DIR, right?")
INCLUDEPATH += $$MARSYAS_INSTALL_DIR/include/marsyas
# in case you have not installed Marsyas
INCLUDEPATH += $$DEPTH/lib/release
LIBPATH += $$DEPTH/lib/release
INCLUDEPATH += $$DEPTH/marsyas/
unix:LIBS += -lmarsyas -L$$MARSYAS_INSTALL_DIR/lib # -lmad -lvorbis -lvorbisfile
!macx:LIBS += -lasound
macx:LIBS += -framework CoreAudio -framework CoreMidi -framework CoreFoundation
@end example
Then type @code{qmake} to generate a Makefile. Now you many compile
normally.
@subsection ... writing your own Makefile
We @emph{highly} recommend that you use qmake to create a Makefile.
However, if you enjoy swearing at your computer and cursing k&r, rms,
gnu, and every other three-letter programmer acronym in existence, you
may create a file called @file{Makefile} which contains
@example
all:
rm -f *.o
g++ -Wall -O2 -I./ -I/usr/local/include/marsyas -c -o myfile.o myfile.cpp
g++ -Lusr/local/lib -o myfile myfile.o -lmarsyas -lasound
@end example
@noindent
(place a tab in front of the three lower lines instead of spaces)
If you installed marsyas in a location other than @file{/usr/local/}, then
change the @code{-I} and @code{-L} directories accordingly. For example,
if you installed marsyas in @file{$@{HOME@}/usr/}, then you would use
@code{-I$@{HOME@}/usr/include/marsyas} and @code{-L$@{HOME@}/usr/lib}. Once
the @file{Makefile} is written, simply type @code{make} to compile
your file.
@subsubheading MacOS X
To compile Marsyas projects in OSX, use the same @file{Makefile} as is used
in other *nixes, but replace the final line with
@example
g++ -Lusr/local/lib -o myfile myfile.o -lmarsyas -framework CoreAudio \
-framework CoreMidi -framework CoreFoundation
@end example
@subsection ... on Windows Visual Studio
Please see the documentation for your compiler / development
environment.
@node Example programs
@section Example programs
The most efficient way to learn how to write programs that use MarSystem
is to read these examples. We recommend that you use these examples as
templates when you begin to write your own programs.
@menu
* Hello World (playing an audio file)::
* Reading and altering controls::
* Writing data to text files::
* Getting data from the network::
* Command-line options::
@end menu
@node Hello World (playing an audio file)
@subsection Hello World (playing an audio file)
@cindex Hello world
@cindex Playing an audio file
Instead of printing @qq{Hello World!}, we shall play a sound file. This is
relatively straightforward: we create a @code{MarSystem} which is a
series of @code{SoundFileSource}, @code{Gain}, and @code{AudioSink}. Once
the network is created and the controls are given, we call @code{tick()} to
make time pass until we have finished playing the file.
@examplefile{helloworld.cpp}
@node Reading and altering controls
@subsection Reading and altering controls
Here we have modified the example from the previous section: we have added
the ability to start at an arbitrary position (time) inside the audio file.
To calculate the starting position in the file, we must know the sample rate
and number of channels. We get this information from the
@code{SoundFileSource} with @code{getctrl}.
@examplefile{controls.cpp}
@node Writing data to text files
@subsection Writing data to text files
Extract data from a network for further analysis (plotting,
other programs, etc) is fairly easy to do with @code{PlotSink}.
@examplefile{writefile.cpp}
@node Getting data from the network
@subsection Getting data from the network
Putting together a network of MarSystems is all well and good,
but you probably want to do something with that data. In this
example we simply print it to the screen, but the important
thing to note is that we have the data at the level of C programming.
@examplefile{gettingdata.cpp}
@node Command-line options
@subsection Command-line options
Getting options from the command-line is fairly easy; Marsyas provides
a handy object which parses the command-line for you.
@examplefile{commandOptions.cpp}
@node Writing Qt4 applications
@section Writing Qt4 applications
Writing applications that use Marsyas and Qt4 is quite simple, thanks to
@file{libmarsasqt}.
@warning{ Marsyas compiled with autotools does not compile
@file{libmarsyasqt} by default. To enable it, please pass
@code{--enable-marsyasqt} to configure.}
@menu
* Including and linking to libmarsyasqt::
* MarSystemQtWrapper::
* Passing controls to a MarSystemQtWrapper::
* Qt4 example::
* Other Qt4 issues::
@end menu
@node Including and linking to libmarsyasqt
@subsection Including and linking to libmarsyasqt
Create a @file{.pro} file based on this template:
@example
### your files
SOURCES = main.cpp
HEADERS = mainwindow.h
SOURCES += mainwindow.cpp
HEADERS += backend.h
SOURCES += backend.cpp
### if running inside the source tree
MARSYAS_INSTALL_DIR = ../../../
INCLUDEPATH += $$MARSYAS_INSTALL_DIR/src/marsyasqt_wrapper/
LIBPATH += $$MARSYAS_INSTALL_DIR/lib/release/
### if installed elsewhere
#MARSYAS_INSTALL_DIR = /usr/local
#MARSYAS_INSTALL_DIR = $@{HOME@}/usr/
#INCLUDEPATH += $$MARSYAS_INSTALL_DIR/src/marsyas/
#LIBPATH += $$MARSYAS_INSTALL_DIR/lib/
unix:LIBS += -lmarsyas -lmarsyasqt
unix:!macx:LIBS += -lasound
macx:LIBS += -framework CoreAudio -framework CoreMidi -framework CoreFoundation
@end example
It is @strong{highly} recommended that you separate the Qt code (ie
@code{mainwindow.cpp}) from the Marsyas code (ie @code{backend.cpp}).
@node MarSystemQtWrapper
@subsection MarSystemQtWrapper
The actual interaction between Qt and Marsyas is performed with a
@code{MarSystemQtWrapper} object. Add the following lines to your
header file that deals with Marsyas:
@example
#include "MarSystemQtWrapper.h"
using namespace MarsyasQt;
@end example
You may now create a pointer to a MarSystemQtWrapper in your object:
@example
MarSystemQtWrapper *mrsWrapper;
@end example
To use this object in your source file, create a MarSystem like normal,
then pass it to a new @code{MarSystemQtWrapper} object:
@example
MarSystemManager mng;
playbacknet = mng.create("Series", "playbacknet");
... set up playbacknet...
// wrap it up to make it pretend to be a Qt object:
mrsWrapper = new MarSystemQtWrapper(playbacknet);
mrsWrapper->start();
mrsWrapper->play();
... do something for a while...
mrsWrapper->stop();
delete mrsWrapper;
@end example
@node Passing controls to a MarSystemQtWrapper
@subsection Passing controls to a MarSystemQtWrapper
@cindex MarControlPtr
Since your MarSystem is wrapped up, you cannot access controls using the
normal methods. Instead, you must use a MarControlPtr:
@example
MarControlPtr filenamePtr;
MarControlPtr positionPtr;
filenamePtr = mrsWrapper->getctrl("SoundFileSource/src/mrs_string/filename");
positionPtr = mrsWrapper->getctrl("SoundFileSource/src/mrs_natural/pos");
mrsWrapper->updctrl(filenamePtr,fileName);
... wait a bit...
newPos = (mrs_natural) positionPtr->to<mrs_natural>();
@end example
@node Qt4 example
@subsection Qt4 example
To get started, look at the Qt4 tutorial files:
@examplefilenewpage{tutorial.pro}
@examplefilenewpage{main.cpp}
@examplefilenewpage{mainwindow.h}
@examplefilenewpage{mainwindow.cpp}
@examplefilenewpage{backend.h}
@examplefilenewpage{backend.cpp}
After examining that project, see @file{apps/Qt4Apps/MarPlayer/}, followed by
the other examples in the @file{apps/Qt4Apps/} directory.
@node Other Qt4 issues
@subsection Other Qt4 issues
TODO: beautify
Question and answer:
@example
I'd like to analyze sound file to extract pitches and amplitudes. I
have working code without using MarSystemQtWrapper, but for GUI display
reasons, I'd like to do this analysis in a separate thread. (ie a
MarSystemQtWrapper)
Is there any way to do this kind of thing inside a MarSystemQtWrapper?
while (allNet->getctrl("mrs_bool/notEmpty")->toBool())
allNet->tick();
@end example
add the control you are interested to the monitored
controls by calling trackctrl (or something like that)
in MarSystemQtWrapper. The MarSystemQtWrapper
will emit a signal either any time the control is changed
or at period intervals depending on the withTimer
settting. Either way you can connect the signal
ctrlChanged(MarControlPtr cname);
to a slot in your GUI and then call allnet->pause()
when that happens.
-----
this is working on Meaws, but I'll need to read my code again to figure
out how it works. Fortunately, I write nice clean readable code. :) -gp
@node Other programming issues
@section Other programming issues
@menu
* Scheduler::
* Visualizing data with gnuplot::
@end menu
@node Scheduler
@subsection Scheduler
To schedule events using the new scheduler code, see the
Marsyas Expression Syntax documentation at
@uref{http://www.cs.uvic.ca/~inb/work/expr.html}
@node Visualizing data with gnuplot
@subsection Visualizing data with gnuplot
Gnuplot is an open-source data plotting utility available on every
operating system that Marsyas supports. More information (including
downloads and installation instructions) can be found on the
@uref{http://www.gnuplot.info/,Gnuplot website}.
Data in Marsyas can be plotted easily: simply write the realvec to
a text file and call gnuplot on the result.
@example
void someFunction() @{
string filename = "dataToPlot.txt";
realvec data;
data.allocate(size);
// ... do whatever processing here...
data.writeText( filename );
data.~realvec();
@}
@end example
After compiling and running the program, the @code{dataToPlot.txt} file
may be plotted with gnuplot.
@example
gnuplot> plot "dataToPlot.txt"
@end example
@node Interoperability
@section Interoperability
@menu
* Open Sound Control (OSC)::
* WEKA::
* MATLAB::
* Python::
* OCaml::
@end menu
@node Open Sound Control (OSC)
@subsection Open Sound Control (OSC)
@WANTED{@emph{can} be done; read the source code.}
@node WEKA
@subsection WEKA
@WANTED{@emph{can} be done; read the source code.}
@node MATLAB
@subsection MATLAB
MATLAB is a
@WANTED{general blurb and whatnot.}
@subheading Marsyas -> MATLAB
To export data from Marsyas into MATLAB, simply add
@WANTED{code here}
@example
@end example
@noindent
to your .cpp source file, and
@WANTED{code here}
@example
@end example
@noindent
to your MATLAB file.
@subheading Marsyas <- MATLAB
To import data into Marsyas from MATLAB, simply add
@WANTED{code here}
@example
@end example
@noindent
to your .cpp source file, and
@WANTED{code here}
@example
@end example
@noindent
to your MATLAB file.
@node Python
@subsection Python
It @emph{can} be done; read the source code.
@node OCaml
@subsection OCaml
To combine Marsyas and OCaml, see the MarsyasOCaml documentation at
@uref{http://www.cs.uvic.ca/~inb/work/marsyasOCaml/}
See more files for this project here