@c =================================================================== @c
@c    serrano/prgm/project/bigloo/manuals/multimedia.texi              @c
@c    ------------------------------------------------------------     @c
@c    Author      :  Manuel Serrano                                    @c
@c    Creation    :  Mon Jun  2 07:36:46 2008                          @c
@c    Last change :                                                    @c
@c    Copyright   :  2008 Manuel Serrano                               @c
@c    ------------------------------------------------------------     @c
@c    Multimedia programming                                           @c
@c =================================================================== @c

@c ------------------------------------------------------------------- @c
@c    Multimedia ...                                                   @c
@c ------------------------------------------------------------------- @c
@node Multimedia, Mail, Database, Top
@comment  node-name,  next,  previous,  up
@chapter Multimedia
@cindex multimedia

Bigloo provides various facilities for programming multimedia
applications. It provides functions for parsing images and sounds and
functions for controlling music players. All the functions, variables,
and classes presented in the document are accessible via the
@code{multimedia} library. Here is an example of module that uses this
library:

@smalllisp
;; Extract the thumbnail of a digital photography.
(module thumbnail
   (library multimedia)
   (main main))

(define (main argv)
   (when (and (pair? (cdr argv)) (file-exists? (cadr argv)))
      (let ((ex (jpeg-exif (cadr argv))))
          (when (exif? ex)
             (display (exif-thumbnail ex))))))
@end smalllisp

@menu
* Photography::
* Music::
* Color::
@end menu

@c ------------------------------------------------------------------- @c
@c    Photography ...                                                  @c
@c ------------------------------------------------------------------- @c
@node Photography, Music, , Multimedia
@comment  node-name,  next,  previous, up
@section Photography
@cindex Photography

The multimedia library provides functions for accessing the metadata
generated by digital camera.

@c -- jpeg-exif ------------------------------------------------------ @c
@deffn {bigloo multimedia procedure} jpeg-exif file-name
The function @code{jpeg-exif} extracts the EXIF 
(@url{http://en.wikipedia.org/wiki/Exif}) metadata of a JPEG file as created
by digital camera. The argument @var{file-name} is the name of the JPEG 
file. If the file contains an EXIF section it is returned as an instance
of the @code{exif} class. Otherwise, this function returns @code{#f}.
@end deffn

@c -- jpeg-exif-comment-set! ----------------------------------------- @c
@deffn {bigloo multimedia procedure} jpeg-exif-comment-set! file-name text

Set the comment of the EXIF metadata section of the file file-name
to @var{text}.
@end deffn

@c -- exif ----------------------------------------------------------- @c
@deffn {bigloo multimedia class} exif
@smalllisp
(class exif
   (version (default #f))
   (jpeg-encoding (default #f))
   (jpeg-compress (default #f))
   (comment (default #f))
   (commentpos (default #f))
   (commentlen (default #f))
   (date (default #f))
   (make (default #f))
   (model (default #f))
   (orientation (default 'landscape))
   (width (default #f))
   (height (default #f))
   (ewidth (default #f))
   (eheight (default #f))
   (xresolution (default #f))
   (yresolution (default #f))
   (resolution-unit (default #f))
   (focal-length (default #f))
   (flash (default #f))
   (fnumber (default #f))
   (iso (default #f))
   (shutter-speed-value (default #f))
   (exposure-time (default #f))
   (exposure-bias-value (default #f))
   (aperture (default #f))
   (metering-mode (default #f))
   (cdd-width (default #f))
   (focal-plane-xres (default #f))
   (focal-plane-units (default #f))
   (thumbnail (default #f))
   (thumbnail-path (default #f))
   (thumbnail-offset (default #f))
   (thumbnail-length (default #f)))
@end smalllisp

The instance of the @code{exif} class maps the EXIF metadata found in JPEG
files into Bigloo objects. Since all fields are optional they are untyped.
@end deffn

@c -- exif-date->date ------------------------------------------------ @c
@deffn {bigloo multimedia procedure} exif-date->date
Parses an exif date, i.e., a string of characters, and returns 
corresponding date. Raises an @var{&io-parse-error} if the string does
not represents an exif date whose syntax is given by the following regular
expression:

@smalllisp
  [0-9][0-9][0-9]:[0-9][0-9]:[0-9][0-9] :[0-9][0-9]:[0-9][0-9]:[0-9][0-9]
@end smalllisp

@end deffn

@c ------------------------------------------------------------------- @c
@c    Music ...                                                        @c
@c ------------------------------------------------------------------- @c
@node Music, Color, Photography, Multimedia
@comment  node-name,  next,  previous, up
@section Music
@cindex Music

The multimedia library provides an extensive set of functions for dealing
with music. It provides functions for accessing the metadata of certain
music file formats, it provides functions for controlling the volume
of the hardware mixers and it provides functions for playing and controlling
music playback.

@menu
* Metadata and Playlist::
* Mixer::
* Playback::
* MPD::
@end menu

@c ------------------------------------------------------------------- @c
@c    Metadata and Playlist                                            @c
@c ------------------------------------------------------------------- @c
@node Metadata and Playlist, Mixer, , Music
@comment  node-name,  next,  previous, up
@subsection Metadata and Playlist
@cindex id3, m3u

@c -- read-m3u ------------------------------------------------------- @c
@deffn {bigloo multimedia procedure} read-m3u input-port
@deffnx {bigloo multimedia procedure} write-m3u list output-port

The function @code{read-m3u} reads a playlist expressed in the M3U
format from @var{input-port} and returns a list of songs. The function
@code{write-m3u} encode such a list encoded in the M3U format to an
output port.
@end deffn

@c -- mp3-id3 -------------------------------------------------------- @c
@deffn {bigloo multimedia procedure} file-musictag file-name
@deffnx {bigloo multimedia procedure} mp3-musictag file-name
@deffnx {bigloo multimedia procedure} ogg-musictag file-name
@deffnx {bigloo multimedia procedure} flac-musictag file-name
These functions extract the metadata of a music file named @var{file-name}.

The function @code{mp3-musictag} returns the ID3 tag section if it
exists. Otherwise, it returns @code{#f}. The function @code{ogg-musictag}
and @code{flac-musictag} returns the vorbis comment if it exists.
@end deffn

@c -- musictag ------------------------------------------------------- @c
@deffn {bigloo multimedia class} musictag
@smalllisp
(abstract-class musictag
   (title::bstring read-only)
   (artist::bstring read-only)
   (orchestra::obj read-only (default #f))
   (interpret::obj read-only (default #f))
   (album::bstring read-only)
   (year::int read-only)
   (comment::bstring read-only)
   (genre::bstring read-only)
   (track::int (default -1)))
@end smalllisp

This class is used as the base class of music tag formats.
@end deffn

@c -- id3 ------------------------------------------------------------ @c
@deffn {bigloo multimedia class} id3::musictag
@smalllisp
(class id3::musictag
   version::bstring
   (orchestra::obj read-only (default #f))
   (conductor::obj read-only (default #f))
   (recording read-only (default #f))
   (cd::obj (default #f)))
@end smalllisp

This class is used to reify the ID3 metadata used in the MP3 format.
@end deffn

@c -- vorbis --------------------------------------------------------- @c
@deffn {bigloo multimedia class} vorbis::musictag
@smalllisp
(class vorbis::musictag)
@end smalllisp

This class is used to reify the Vorbis comments of OGG and Flac files.
@end deffn

@c ------------------------------------------------------------------- @c
@c    Mixer                                                            @c
@c ------------------------------------------------------------------- @c
@node Mixer, Playback, Metadata and Playlist, Music
@comment  node-name,  next,  previous, up
@subsection Mixer
@cindex mixer

Bigloo proposes various functions and classes for controlling the
audio volume of sound cards.

@c -- mixer ---------------------------------------------------------- @c
@deffn {bigloo multimedia class} mixer
@smalllisp
(class mixer
   (devices::pair-nil (default '())))
@end smalllisp

The field @var{devices} is a list of available channels.
@end deffn

@c -- mixer-close ---------------------------------------------------- @c
@deffn {bigloo multimedia procedure} mixer-close mix
Closes a mixer. The argument @var{mix} must be an instance of
the @code{mixer} class.
@end deffn

@c -- mixer-volume-get ----------------------------------------------- @c
@deffn {bigloo multimedia procedure} mixer-volume-get mix channel
@deffnx {bigloo multimedia procedure} mixer-volume-set! mix channel leftv rightv
The function @var{mixer-volume-get} returns the left and right volume
levels (two values) of the @var{channel} of the mixer @var{mix}. The 
@var{channel} is denoted by its name and is represented as a string of
characters. The argument @var{mix} is an instance of the @code{mixer} class.

The function @var{mixer-volume-set!} changes the audio level of a mixer
channel.
@end deffn

@c -- soundcard ------------------------------------------------------ @c
@deffn {bigloo multimedia class} soundcard::mixer
@smalllisp
(class soundcard::mixer
   (device::bstring read-only))
@end smalllisp

The instances of the class @code{soundcard}, a subclass of the
@code{mixer} class, are used to access physical soundcard as supported
by operating systems. The class field @var{device} stands for the name
of the system device (e.g., @code{"/dev/mixer"} for the Linux
OS). During the initialization of the instance, the device is opened
and initialized.
@end deffn

@c ------------------------------------------------------------------- @c
@c    Playback                                                         @c
@c ------------------------------------------------------------------- @c
@node Playback, MPD, Mixer, Music
@comment  node-name,  next,  previous, up
@subsection Playback

Bigloo supports various functions for playing music. These functions
rely on two data structure: @emph{music players} and @emph{music status}.
The first ones are used to control player back-ends. The second ones are
used to get information about the music being played. The following 
example shows how a simple music player using either MPlayer, MPG123, or
MPC can be programmed with Bigloo.

@smalllisp
(module musicplay
   (library multimedia)
   (main main))

(define (main args)
   (let ((files '())
	 (backend 'mplayer)
	 (command #f))
      (args-parse (cdr args)
	 (("--mpg123" (help "Select the mpg123 back-end"))
	  (set! backend 'mpg123))
	 (("--mpc" (help "Select the mpc back-end"))
	  (set! backend 'mpc))
	 (("--mplayer" (help "Select the mplayer back-end"))
	  (set! backend 'mplayer))
	 (("--command" ?cmd (help "Set the command path"))
	  (set! command cmd))
	 (("--help" (help "This help"))
	  (print "usage: music [options] file ...")
	  (args-parse-usage #f)
	  (exit 0))
	 (else
	  (set! files (cons else files))))
      ;; create a music player
      (let ((player (case backend
		       ((mpg123)
			(if command
			    (instantiate::mpg123
			       (path command))
			    (instantiate::mpg123)))
		       ((mplayer)
			(if command
			    (instantiate::mplayer
			       (path command))
			    (instantiate::mplayer)))
		       ((mpc)
			(instantiate::mpc)))))
         ;; fill the music play list
	 (for-each (lambda (p) (music-playlist-add! player p)) (reverse files))
         ;; start playing
	 (music-play player)
         ;; run an event loop with call-backs associated to some events
	 (music-event-loop player
            :onstate (lambda (status)
                        (with-access::musicstatus status (state song volume)
                           (print "state   : " state)
                           (print "song    : " song)))
	    :onmeta (lambda (meta)
		       (print "meta    : " meta))
	    :onvolume (lambda (volume)
		       (print "volume  : " volume))))))
@end smalllisp

@c -- music ---------------------------------------------------------- @c
@deffn {bigloo multimedia abstract class} music
@smalllisp
(abstract-class music
   (frequency::long (default 2000000))
@end smalllisp

This abstract class is the root class of all music players.
@end deffn

@c -- musicproc ------------------------------------------------------ @c
@deffn {bigloo multimedia class} musicproc::music
@smalllisp
(class musicproc::music
   (charset::symbol (default 'ISO-LATIN-1)))
@end smalllisp

This class is used to reify player that are run in an external process.
@end deffn

@c -- mplayer -------------------------------------------------------- @c
@deffn {bigloo multimedia class} mplayer::musicproc
@smalllisp
(class mplayer::musicproc
   (path::bstring read-only (default "mplayer"))
   (args::pair-nil read-only (default '("-vo" "null" "-quiet" "-slave" "-idle")))
   (ao::obj read-only (default #unspecified))
   (ac::obj read-only (default #unspecified)))
@end smalllisp

A player based on the external software @code{MPlayer}. Creating such a player
spawns in background a MPlayer process.

@end deffn

@c -- mpg123 --------------------------------------------------------- @c
@deffn {bigloo multimedia class} mpg123::musicproc
@smalllisp
(class mpg123::musicproc
   (path::bstring read-only (default "mpg123"))
   (args::pair-nil read-only (default '("--remote"))))
@end smalllisp

A player based on the external software @code{mpg123}.

@end deffn

@c -- mpc ------------------------------------------------------------ @c
@deffn {bigloo multimedia class} mpc::music
@smalllisp
(class mpc::music
   (hello read-only (default #f))
   (host read-only (default "localhost"))
   (port read-only (default 6600))
   (timeout read-only (default 10008993))
   (prefix (default #f)))
@end smalllisp

A MPC client.

@itemize @bullet
@item @code{hello}: an optional string written when the connection
is establish with the MPD server.
@item @code{prefix}: an optional path prefix to be removed from music 
playlist. This is needed because MPD can only play music files registered
in is private database. The file names used by MPD are relative a 
root directory used to fill the database. The @code{prefix} field allows
programmer to write portable code that manages play list file names 
independently of the player selected.
@end itemize
@end deffn

@c -- musicstatus ---------------------------------------------------- @c
@deffn {bigloo multimedia class} musicstatus
@smalllisp
(class musicstatus
   (state::symbol (default 'stop))
   (volume::obj (default -1))
   (repeat::bool (default #f))
   (random::bool (default #f))
   (playlistid::int (default -1))
   (playlistlength::int (default 0))
   (xfade::int (default 0))
   (song::int (default 0))
   (songid::int (default 0))
   (songpos (default 0))
   (songlength::int (default 0))
   (bitrate::int (default 0))
   (khz::int (default 0))
   (err::obj (default #f)))
@end smalllisp

The instances of the class @code{musicstatus} denote that state of a 
player.
@end deffn

@c -- music-close ---------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-close music
@deffnx {bigloo multimedia procedure} music-reset! music
@deffnx {bigloo multimedia procedure} music-closed? music
Closes, resets, and tests the state of a music player.
@end deffn

@c -- music-playlist ------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-playlist-get music
@deffnx {bigloo multimedia procedure} music-playlist-add! music song
@deffnx {bigloo multimedia procedure} music-playlist-delete! music int
@deffnx {bigloo multimedia procedure} music-playlist-clear! music
These functions controls the playlist used by a player. 

Note: The @var{song} argument is an UTF8 encoded string (see
Section @ref{Unicode (UCS-2) Strings}) @emph{whatever} the local file
system encoding is. The function @code{music-playlist-get} returns a
list of UTF8 encoded names.

@itemize @bullet

@item @code{music-playlist-get}: returns the list of songs (UTF8 names) 
 of the current playlist.
@item @code{music-playlist-add!}: adds an extra song (UTF8 name) at the end 
 of the playlist.
@item @code{music-delete!}: removes the song number @var{int} from the playlist.
@item @code{music-clear!}: erases the whole playlist.
@end itemize
@end deffn

@c -- music-play ----------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-play music [song]
@deffnx {bigloo multimedia procedure} music-seek music time [song]
@deffnx {bigloo multimedia procedure} music-stop music
@deffnx {bigloo multimedia procedure} music-pause music
@deffnx {bigloo multimedia procedure} music-next music
@deffnx {bigloo multimedia procedure} music-prev music
These functions changes the state of the music player. The function
@code{music-seek} seeks the playback position to the position @var{time}, 
which is an integer denoting a number of seconds.
@end deffn

@c -- music-crossfade ------------------------------------------------ @c
@deffn {bigloo multimedia procedure} music-crossfade music int
@deffnx {bigloo multimedia procedure} music-random-set! music bool
@deffnx {bigloo multimedia procedure} music-repeat-set! music bool
These functions controls how songs playback should follow each other.
@end deffn

@c -- music-volume-get ----------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-volume-get music
@deffnx {bigloo multimedia procedure} music-volume-set! music vol
Get and set the audio volume of a player. Some player use the native mixer
supported by the operating system some others use a software mixer unrelated
to the hardware.
@end deffn

@c -- music-status --------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-status music
@deffnx {bigloo multimedia procedure} music-update-status! music status
The function @code{music-status} returns an instance of the @code{musicstatus}
class which denotes the state of the player. The function 
@code{music-update-status!} updates this status.
@end deffn

@c -- music-song ----------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-song music
@deffnx {bigloo multimedia procedure} music-songpos music
These two functions return the number of the song being played and the 
position in the song. These functions are somehow redundant with the
function @code{music-status} because the status also contains information
about the playback song and playback position. However, for some players
getting the music song and the playback position is cheaper than getting
the whole player status.
@end deffn

@c -- music-meta ----------------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-meta music
Returns the metadata the current song.
@end deffn

@c -- music-reset-error! --------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-reset-error! music
Reset the previous errors detected by a player.
@end deffn

@c -- music-event-loop ----------------------------------------------- @c
@deffn {bigloo multimedia procedure} music-event-loop music [:onstate] [:onmeta] [:onerror] [:onvolume]

The function @code{music-event-loop} enable event notifications when the state
of a player changes. The keyword arguments are:

@itemize @bullet
@item @code{:onstate}, a function of one parameter. When the player state 
changes, this function is called with an instance of @code{musicstatus} 
as first actual parameter.
@item @code{:onmeta}, a function of two parameters. This function is
called when a metadata is detected in the music currently played.
@item @code{:onerror}, a function of one parameter, invoked when an error
is detected.
@item @code{:onvolume}, a function of one parameter, invoked when the volume
changes.
@end itemize

@end deffn


@c ------------------------------------------------------------------- @c
@c    MPD                                                              @c
@c ------------------------------------------------------------------- @c
@node MPD, , Playback, Music
@comment  node-name,  next,  previous, up
@subsection Music Player Daemon

Music Player Daemon (MPD in short) allows remote access for playing
music @url{http://www.musicpd.org}. MPD is designed for integrating a
computer into a stereo system that provides control for music playback
over a local network. The Bigloo class @code{mpc} implements a @code{mpd}
client. All Bigloo players can be access via the MPD protocol, using the

The following example shows how to access a MPlayer music player using the
MPD protocol with a simple Bigloo program:

@smalllisp
(module mpd
   (library multimedia pthread)
   (main main))
   
(define (main argv)
   (let ((db (instantiate::mpd-database
		(directories (cdr argv))))
	 (serv (make-server-socket 6600))
	 (music (instantiate::mplayer)))
      (let loop ()
	 (thread-start! (make-mpd-connection-thread music db sock))
	 (loop))))

(define (make-mpd-connection-thread music db sock)
   (instantiate::pthread
      (body (lambda ()
	       (let ((pi (socket-input sock))
		     (po (socket-output sock)))
		  (input-timeout-set! pi 10000)
		  (output-timeout-set! po 10000)
		  (unwind-protect
		     (mpd music pi po db)
		     (socket-close sock)))))))
@end smalllisp

@c -- mpd ------------------------------------------------------------ @c
@deffn {bigloo multimedia procedure} mpd music input-port output-port database [:log]
The function @code{mpd} implements a MPD server. It reads commands from the
@var{input-port} and write results to @var{output-port}. The argument
@var{database}, an instance of the @code{mpd-database} class, describes the
music material that can be delivered by this player.

@end deffn

@c -- mpd-database --------------------------------------------------- @c
@deffn {bigloo multimedia class} mpd-database
@smalllisp
(class mpd-database
   (directories::pair-nil read-only)
@end smalllisp

The field @code{directories} contains the list of the directories that contains
music files.
@end deffn

@c ------------------------------------------------------------------- @c
@c    Music ...                                                        @c
@c ------------------------------------------------------------------- @c
@node Color,, Music, Multimedia
@comment  node-name,  next,  previous, up
@section Color
@cindex Color

The multimedia library provides functions for dealing with colors.

@c -- hsv->rgb ------------------------------------------------------- @c
@deffn {bigloo multimedia procedure} hsv->rgb h s v
@deffnx {bigloo multimedia procedure} hsl->rgb h s l
@deffnx {bigloo multimedia procedure} rgb-hsv r g b
@deffnx {bigloo multimedia procedure} rgb-hsl r g b
These procedures converts from and to HSV, HSL, and RGB representations.
The argument @var{h} is an integer in the range @code{[0..360]}, 
the arguments @var{s}, @var{v}, and @var{l} in the range @code{[0..100]}. The
arguments @var{r}, @var{g}, and @var{b} are in the range @code{[0..255]}.
These procedures returns multiple-values.

@smalllisp
(multiple-value-bind (r g b)
   (hsv->rgb 340 34 56)
   (list r g b)) @result{} (143 94 110)
(multiple-value-bind (h s v)
   (rgb->hsv 255 0 0)
   (list h s v)) @result{} (0 100 100)
@end smalllisp
@end deffn


