[SCM] gsequencer/master: Imported Upstream version 0.4.2-68

jkraehemann-guest at users.alioth.debian.org jkraehemann-guest at users.alioth.debian.org
Thu Jun 18 15:14:23 UTC 2015


The following commit has been merged in the master branch:
commit b3873d9f3923a112467269320c9491a787ad481f
Author: Joël Krähemann <jkraehemann at gmail.com>
Date:   Thu Jun 18 16:52:25 2015 +0200

    Imported Upstream version 0.4.2-68

diff --git a/Makefile.am b/Makefile.am
index 36e9667..5874793 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,10 +10,52 @@ LDFLAGS = -fPIE -pie -Wl,-z,relro -Wl,-z,now
 # this lists the binaries to produce, the (non-PHONY, binary) targets in
 # the previous manual Makefile
 noinst_LIBRARIES = 
-bin_PROGRAMS = ags
-EXTRA_DIST = gsequencer.share acsite.m4 ags.1
+bin_PROGRAMS = ags midi2xml
+EXTRA_DIST = gsequencer.share acsite.m4 ags.1 midi2xml.1 README
 CLEANFILES =
-man1_MANS = ags.1
+man1_MANS = ags.1 midi2xml.1
+
+appdatadir = $(datadir)/applications
+appdata_DATA = ags.desktop
+
+EXTRA_DIST += ags.desktop.in
+CLEANFILES += $(appdata_DATA)
+
+docdir = $(datadir)/doc/gsequencer
+doc_DATA = README
+
+# documentation
+userdoc = \
+	doc/usersBook.xml \
+	doc/appa.xml \
+	doc/usersBook/appb.xml \
+	doc/usersBook/chap1.xml \
+	doc/usersBook/chap2.xml \
+	doc/usersBook/chap3.xml \
+	doc/usersBook/chap4.xml \
+	doc/usersBook/preface.xml
+
+userdocimages = \
+	$(top_srcdir)/doc/images/ags_export_window.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-input.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-resize_channels.png \
+	$(top_srcdir)/doc/images/ags_navigation.png \
+	$(top_srcdir)/doc/images/ags_synth.png \
+	$(top_srcdir)/doc/images/ags_audio_preferences.png \
+	$(top_srcdir)/doc/images/ags_ffplayer.png \
+	$(top_srcdir)/doc/images/ags_ladspa_browser.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-link_input.png \
+	$(top_srcdir)/doc/images/ags_matrix.png \
+	$(top_srcdir)/doc/images/ags_panel.png \
+	$(top_srcdir)/doc/images/ags-toolbar.png \
+	$(top_srcdir)/doc/images/ags_drum.png \
+	$(top_srcdir)/doc/images/ags_generic_preferences.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-output.png \
+	$(top_srcdir)/doc/images/ags_mixer.png \
+	$(top_srcdir)/doc/images/ags_performance_preferences.png \
+	$(top_srcdir)/doc/images/ags_server_preferences.png
+
+EXTRA_DIST += $(userdoc) $(userdocimages)
 
 # library
 libags_a_CFLAGS= $(GOBJECT_CFLAGS) $(LIBXML2_CFLAGS) 
@@ -25,22 +67,37 @@ ags_CFLAGS= $(CFLAGS) $(UUID_CFLAGS) $(LIBASOUND2_CFLAGS) $(LIBAO_CFLAGS) $(LIBX
 ags_LDFLAGS= -ldl $(LDFLAGS) $(UUID_LIBS) $(LIBASOUND2_LIBS) $(LIBAO_LIBS) $(LIBXML2_LIBS) $(OPENSSL_LIBS) $(SNDFILE_LIBS) $(LIBINSTPATCH_LIBS) $(GOBJECT_LIBS) $(GDKPIXBUF_LIBS) $(CAIRO_LIBS) $(GTK_LIBS) $(XMLRPC_LIBS) $(XMLRPC_UTIL_LIBS) $(XMLRPC_SERVER_ABYSS_LIBS) $(XMLRPC_SERVER_CGI_LIBS) $(XMLRPC_SERVER_LIBS) -lm -lrt -lX11 -pthread
 ags_LDADD = 
 
-appdatadir = $(datadir)/applications
-appdata_DATA = ags.desktop 
+ags_SOURCES = ./src/ags-lib/object/ags_connectable.c ./src/ags-lib/object/ags_connectable.h src/ags/lib/ags_combo_box_text.c src/ags/lib/ags_list.c src/ags/lib/ags_container.c src/ags/lib/ags_parameter.h src/ags/lib/ags_list.h src/ags/lib/ags_log.c src/ags/lib/ags_container.h src/ags/lib/ags_combo_box_text.h src/ags/lib/ags_log.h src/ags/lib/ags_parameter.c src/ags/X/editor/ags_notebook_callbacks.c src/ags/X/editor/ags_meter.h src/ags/X/editor/ags_toolbar.h src/ags/X/editor/ags_machine_radio_button.h src/ags/X/editor/ags_file_selection_callbacks.h src/ags/X/editor/ags_notebook_callbacks.h src/ags/X/editor/ags_note_edit.h src/ags/X/editor/ags_meter_callbacks.c src/ags/X/editor/ags_notebook.h src/ags/X/editor/ags_sf2_chooser.h src/ags/X/editor/ags_toolbar_mode_stock.h src/ags/X/editor/ags_meter_callbacks.h src/ags/X/editor/ags_toolbar_callbacks.c src/ags/X/editor/ags_machine_selector.c src/ags/X/editor/ags_machine_selector_callbacks.c src/ags/X/editor/ags_machine_radio_button.c src/ags/X/editor/ags_sf2_chooser.c src/ags/X/editor/ags_machine_selector_callbacks.h src/ags/X/editor/ags_sf2_chooser_callbacks.c src/ags/X/editor/ags_notebook.c src/ags/X/editor/ags_note_edit_callbacks.c src/ags/X/editor/ags_file_selection_callbacks.c src/ags/X/editor/ags_machine_selection.c src/ags/X/editor/ags_inline_player_callbacks.h src/ags/X/editor/ags_inline_player.c src/ags/X/editor/ags_meter.c src/ags/X/editor/ags_file_selection.h src/ags/X/editor/ags_inline_player.h src/ags/X/editor/ags_sf2_chooser_callbacks.h src/ags/X/editor/ags_file_selection.c src/ags/X/editor/ags_machine_selector.h src/ags/X/editor/ags_note_edit_callbacks.h src/ags/X/editor/ags_note_edit.c src/ags/X/editor/ags_inline_player_callbacks.c src/ags/X/editor/ags_toolbar_callbacks.h src/ags/X/editor/ags_machine_selection.h src/ags/X/editor/ags_toolbar.c src/ags/X/ags_line_callbacks.h src/ags/X/ags_plugin_preferences.c src/ags/X/ags_link_editor.c src/ags/X/ags_pad_callbacks.h src/ags/X/ags_machine_callbacks.c src/ags/X/ags_server_preferences_callbacks.h src/ags/X/ags_listing_editor_callbacks.c src/ags/X/ags_link_collection_editor_callbacks.c src/ags/X/ags_generic_preferences_callbacks.c src/ags/X/ags_property_collection_editor_callbacks.c src/ags/X/ags_property_collection_editor.h src/ags/X/ags_resize_editor.h src/ags/X/ags_property_editor.h src/ags/X/ags_window_callbacks.h src/ags/X/ags_property_editor_callbacks.c src/ags/X/machine/ags_synth_callbacks.h src/ags/X/machine/ags_synth.c src/ags/X/machine/ags_mixer.c src/ags/X/machine/ags_matrix_callbacks.c src/ags/X/machine/ags_panel_input_line.c src/ags/X/machine/ags_synth_input_line.c src/ags/X/machine/ags_drum_callbacks.h src/ags/X/machine/ags_mixer_callbacks.c src/ags/X/machine/ags_synth_callbacks.c src/ags/X/machine/ags_ffplayer_callbacks.h src/ags/X/machine/ags_drum_input_line.h src/ags/X/machine/ags_matrix.h src/ags/X/machine/ags_mixer_input_line.c src/ags/X/machine/ags_oscillator.c src/ags/X/machine/ags_oscillator.h src/ags/X/machine/ags_oscillator_callbacks.h src/ags/X/machine/ags_mixer.h src/ags/X/machine/ags_panel_input_pad.h src/ags/X/machine/ags_panel_input_pad.c src/ags/X/machine/ags_matrix.c src/ags/X/machine/ags_panel.h src/ags/X/machine/ags_drum_output_line_callbacks.c src/ags/X/machine/ags_ffplayer.h src/ags/X/machine/ags_panel_callbacks.c src/ags/X/machine/ags_mixer_input_pad.c src/ags/X/machine/ags_panel.c src/ags/X/machine/ags_drum.c src/ags/X/machine/ags_matrix_callbacks.h src/ags/X/machine/ags_drum_output_line.h src/ags/X/machine/ags_drum_output_pad.h src/ags/X/machine/ags_synth_input_pad.h src/ags/X/machine/ags_panel_callbacks.h src/ags/X/machine/ags_ffplayer.c src/ags/X/machine/ags_drum_output_line_callbacks.h src/ags/X/machine/ags_drum_output_pad_callbacks.c src/ags/X/machine/ags_drum_output_pad_callbacks.h src/ags/X/machine/ags_drum_input_pad_callbacks.h src/ags/X/machine/ags_oscillator_callbacks.c src/ags/X/machine/ags_drum_callbacks.c src/ags/X/machine/ags_synth_input_line.h src/ags/X/machine/ags_drum_input_pad_callbacks.c src/ags/X/machine/ags_drum_input_pad.c src/ags/X/machine/ags_panel_input_line.h src/ags/X/machine/ags_drum_input_line_callbacks.h src/ags/X/machine/ags_drum_output_line.c src/ags/X/machine/ags_mixer_callbacks.h src/ags/X/machine/ags_synth.h src/ags/X/machine/ags_mixer_input_line.h src/ags/X/machine/ags_drum.h src/ags/X/machine/ags_drum_input_line.c src/ags/X/machine/ags_ffplayer_callbacks.c src/ags/X/machine/ags_drum_output_pad.c src/ags/X/machine/ags_drum_input_pad.h src/ags/X/machine/ags_drum_input_line_callbacks.c src/ags/X/machine/ags_mixer_input_pad.h src/ags/X/machine/ags_synth_input_pad.c src/ags/X/ags_server_preferences.h src/ags/X/ags_line_editor_callbacks.h src/ags/X/ags_pad_editor_callbacks.c src/ags/X/ags_listing_editor_callbacks.h src/ags/X/ags_line_member_callbacks.c src/ags/X/ags_editor.h src/ags/X/ags_machine_editor.h src/ags/X/ags_plugin_preferences_callbacks.h src/ags/X/ags_export_window_callbacks.h src/ags/X/ags_editor_callbacks.c src/ags/X/ags_pad_editor.h src/ags/X/ags_server_preferences.c src/ags/X/ags_line_editor.c src/ags/X/ags_ladspa_browser.h src/ags/X/ags_audio_preferences.c src/ags/X/ags_pad.c src/ags/X/ags_line.c src/ags/X/ags_menu_bar_callbacks.c src/ags/X/ags_generic_preferences_callbacks.h src/ags/X/ags_pad.h src/ags/X/ags_audio_preferences_callbacks.h src/ags/X/ags_generic_preferences.c src/ags/X/ags_window.c src/ags/X/ags_machine_editor_callbacks.h src/ags/X/ags_editor_callbacks.h src/ags/X/ags_menu_bar_callbacks.h src/ags/X/ags_line_member_editor.h src/ags/X/ags_property_collection_editor_callbacks.h src/ags/X/ags_line_editor_callbacks.c src/ags/X/ags_property_editor.c src/ags/X/ags_link_editor_callbacks.c src/ags/X/ags_server_preferences_callbacks.c src/ags/X/ags_pad_callbacks.c src/ags/X/ags_line_member.h src/ags/X/ags_audio_preferences_callbacks.c src/ags/X/ags_performance_preferences.h src/ags/X/ags_property_collection_editor.c src/ags/X/ags_performance_preferences_callbacks.h src/ags/X/ags_line.h src/ags/X/ags_machine.c src/ags/X/ags_preferences_callbacks.c src/ags/X/ags_export_window.c src/ags/X/ags_menu_bar.c src/ags/X/ags_plugin_preferences_callbacks.c src/ags/X/ags_line_member_callbacks.h src/ags/X/ags_preferences.c src/ags/X/ags_export_window.h src/ags/X/ags_pad_editor_callbacks.h src/ags/X/ags_window.h src/ags/X/ags_machine_callbacks.h src/ags/X/ags_machine.h src/ags/X/ags_line_callbacks.c src/ags/X/ags_link_editor_callbacks.h src/ags/X/ags_navigation_callbacks.h src/ags/X/ags_pad_editor.c src/ags/X/ags_ladspa_browser.c src/ags/X/ags_editor.c src/ags/X/ags_resize_editor.c src/ags/X/ags_property_listing_editor.c src/ags/X/ags_property_editor_callbacks.h src/ags/X/ags_line_member_editor_callbacks.h src/ags/X/ags_window_callbacks.c src/ags/X/ags_audio_preferences.h src/ags/X/ags_navigation_callbacks.c src/ags/X/ags_plugin_preferences.h src/ags/X/ags_performance_preferences_callbacks.c src/ags/X/ags_line_member.c src/ags/X/ags_preferences.h src/ags/X/ags_generic_preferences.h src/ags/X/ags_navigation.h src/ags/X/ags_listing_editor.h src/ags/X/ags_performance_preferences.c src/ags/X/ags_link_editor.h src/ags/X/ags_ladspa_browser_callbacks.c src/ags/X/ags_link_collection_editor.c src/ags/X/ags_preferences_callbacks.h src/ags/X/ags_machine_editor_callbacks.c src/ags/X/ags_menu_bar.h src/ags/X/ags_export_window_callbacks.c src/ags/X/ags_line_member_editor_callbacks.c src/ags/X/ags_link_collection_editor.h src/ags/X/ags_link_collection_editor_callbacks.h src/ags/X/ags_property_listing_editor.h src/ags/X/ags_navigation.c src/ags/X/ags_machine_editor.c src/ags/X/ags_line_member_editor.c src/ags/X/ags_ladspa_browser_callbacks.h src/ags/X/ags_line_editor.h src/ags/X/ags_listing_editor.c src/ags/object/ags_applicable.c src/ags/object/ags_seekable.h src/ags/object/ags_packable.c src/ags/object/ags_persistable.h src/ags/object/ags_packable.h src/ags/object/ags_applicable.h src/ags/object/ags_main_loop.c src/ags/object/ags_soundcard.c src/ags/object/ags_marshal.c src/ags/object/ags_mutable.h src/ags/object/ags_plugin.h src/ags/object/ags_stackable.h src/ags/object/ags_runnable.c src/ags/object/ags_tactable.h src/ags/object/ags_mutable.c src/ags/object/ags_runnable.h src/ags/object/ags_effect.c src/ags/object/ags_playable.c src/ags/object/ags_dynamic_connectable.c src/ags/object/ags_seekable.c src/ags/object/ags_countable.c src/ags/object/ags_plugin.c src/ags/object/ags_tree_iterator.h src/ags/object/ags_playable.h src/ags/object/ags_effect.h src/ags/object/ags_soundcard.h src/ags/object/ags_countable.h src/ags/object/ags_marshal.h src/ags/object/ags_portlet.h src/ags/object/ags_dynamic_connectable.h src/ags/object/ags_tactable.c src/ags/object/ags_tree_iterator.c src/ags/object/ags_persistable.c src/ags/object/ags_main_loop.h src/ags/object/ags_stackable.c src/ags/object/ags_portlet.c src/ags/util/ags_id_generator.c src/ags/util/ags_id_generator.h src/ags/widget/ags_led.h src/ags/widget/ags_expander_set.c src/ags/widget/ags_expander_set.h src/ags/widget/ags_menu.c src/ags/widget/ags_hindicator.h src/ags/widget/ags_menu.h src/ags/widget/ags_timebar.c src/ags/widget/ags_dial.c src/ags/widget/ags_ruler.h src/ags/widget/ags_dial.h src/ags/widget/ags_segment.c src/ags/widget/ags_htimebar.c src/ags/widget/ags_option_menu.h src/ags/widget/ags_indicator.c src/ags/widget/ags_htimebar.h src/ags/widget/ags_option_menu.c src/ags/widget/ags_expander.h src/ags/widget/ags_menu_item.h src/ags/widget/ags_hindicator.c src/ags/widget/ags_cartesian.h src/ags/widget/ags_indicator.h src/ags/widget/ags_cartesian.c src/ags/widget/ags_menu_item.c src/ags/widget/ags_waveform.c src/ags/widget/ags_ruler.c src/ags/widget/ags_expander.c src/ags/widget/ags_vindicator.c src/ags/widget/ags_timebar.h src/ags/widget/ags_led.c src/ags/widget/ags_waveform.h src/ags/widget/ags_table.c src/ags/widget/ags_table.h src/ags/widget/ags_vindicator.h src/ags/widget/ags_segment.h src/ags/main.c src/ags/audio/task/ags_export_output.h src/ags/audio/task/ags_set_output_device.c src/ags/audio/task/ags_add_audio.h src/ags/audio/task/ags_set_samplerate.c src/ags/audio/task/ags_remove_point_from_selection.c src/ags/audio/task/ags_save_file.h src/ags/audio/task/ags_set_buffer_size.h src/ags/audio/task/ags_link_channel.c src/ags/audio/task/ags_save_file.c src/ags/audio/task/ags_append_audio_threaded.h src/ags/audio/task/ags_cancel_channel.h src/ags/audio/task/ags_apply_synth.h src/ags/audio/task/ags_seek_devout.h src/ags/audio/task/ags_append_recall.h src/ags/audio/task/ags_add_audio_signal.c src/ags/audio/task/ags_unref_audio_signal.c src/ags/audio/task/ags_remove_region_from_selection.c src/ags/audio/task/ags_change_indicator.h src/ags/audio/task/ags_remove_point_from_selection.h src/ags/audio/task/ags_set_audio_channels.h src/ags/audio/task/ags_scroll_on_play.h src/ags/audio/task/ags_remove_audio.h src/ags/audio/task/ags_remove_recall_container.c src/ags/audio/task/ags_remove_recall.c src/ags/audio/task/ags_seek_devout.c src/ags/audio/task/ags_append_recall.c src/ags/audio/task/ags_free_selection.h src/ags/audio/task/ags_add_recall_container.c src/ags/audio/task/ags_add_recall.c src/ags/audio/task/ags_export_output.c src/ags/audio/task/ags_init_channel.h src/ags/audio/task/ags_remove_note.c src/ags/audio/task/ags_apply_wavetable.h src/ags/audio/task/ags_add_audio_signal.h src/ags/audio/task/ags_cancel_recall.h src/ags/audio/task/ags_set_audio_channels.c src/ags/audio/task/ags_cancel_audio.c src/ags/audio/task/ags_unref_audio_signal.h src/ags/audio/task/ags_add_region_to_selection.c src/ags/audio/task/ags_change_tact.h src/ags/audio/task/ags_init_audio.c src/ags/audio/task/ags_channel_set_recycling.c src/ags/audio/task/ags_display_tact.c src/ags/audio/task/ags_add_point_to_selection.h src/ags/audio/task/ags_toggle_pattern_bit.h src/ags/audio/task/ags_append_channel.c src/ags/audio/task/ags_change_indicator.c src/ags/audio/task/ags_add_note.c src/ags/audio/task/ags_channel_set_recycling.h src/ags/audio/task/ags_cancel_audio.h src/ags/audio/task/recall/ags_set_muted.c src/ags/audio/task/recall/ags_set_muted.h src/ags/audio/task/recall/ags_apply_sequencer_length.c src/ags/audio/task/recall/ags_apply_bpm.h src/ags/audio/task/recall/ags_apply_tact.c src/ags/audio/task/recall/ags_apply_bpm.c src/ags/audio/task/recall/ags_apply_sequencer_length.h src/ags/audio/task/recall/ags_apply_tact.h src/ags/audio/task/ags_remove_region_from_selection.h src/ags/audio/task/ags_cancel_channel.c src/ags/audio/task/ags_add_recall_container.h src/ags/audio/task/ags_add_recall.h src/ags/audio/task/ags_add_note.h src/ags/audio/task/ags_start_devout.c src/ags/audio/task/ags_append_audio_threaded.c src/ags/audio/task/ags_append_audio.c src/ags/audio/task/ags_init_channel.c src/ags/audio/task/ags_remove_audio_signal.h src/ags/audio/task/ags_toggle_led.c src/ags/audio/task/ags_set_buffer_size.c src/ags/audio/task/ags_add_region_to_selection.h src/ags/audio/task/ags_audio_set_recycling.h src/ags/audio/task/ags_toggle_led.h src/ags/audio/task/ags_resize_audio.h src/ags/audio/task/ags_free_selection.c src/ags/audio/task/ags_add_audio.c src/ags/audio/task/ags_set_samplerate.h src/ags/audio/task/ags_apply_synth.c src/ags/audio/task/ags_open_single_file.h src/ags/audio/task/ags_remove_audio.c src/ags/audio/task/ags_cancel_recall.c src/ags/audio/task/ags_init_audio.h src/ags/audio/task/ags_remove_note.h src/ags/audio/task/ags_remove_audio_signal.c src/ags/audio/task/ags_audio_set_recycling.c src/ags/audio/task/ags_add_point_to_selection.c src/ags/audio/task/ags_scroll_on_play.c src/ags/audio/task/ags_set_devout_play_flags.c src/ags/audio/task/ags_apply_wavetable.c src/ags/audio/task/ags_add_line_member.c src/ags/audio/task/ags_open_file.h src/ags/audio/task/ags_set_output_device.h src/ags/audio/task/ags_toggle_pattern_bit.c src/ags/audio/task/ags_open_file.c src/ags/audio/task/ags_open_single_file.c src/ags/audio/task/ags_append_audio.h src/ags/audio/task/ags_start_devout.h src/ags/audio/task/ags_display_tact.h src/ags/audio/task/ags_remove_recall_container.h src/ags/audio/task/ags_remove_recall.h src/ags/audio/task/ags_change_tact.c src/ags/audio/task/ags_append_channel.h src/ags/audio/task/ags_resize_audio.c src/ags/audio/task/ags_link_channel.h src/ags/audio/task/ags_add_line_member.h src/ags/audio/task/ags_set_devout_play_flags.h src/ags/audio/ags_devout.c src/ags/audio/ags_recall_channel.h src/ags/audio/ags_timestamp_factory.h src/ags/audio/ags_garbage_collector.c src/ags/audio/ags_garbage_collector.h src/ags/audio/ags_recall_container.c src/ags/audio/ags_timestamp.c src/ags/audio/ags_channel_iter.h src/ags/audio/ags_recall_channel_run.c src/ags/audio/ags_audio.h src/ags/audio/ags_port.c src/ags/audio/ags_notation.c src/ags/audio/ags_recall_dependency.h src/ags/audio/ags_recycling.c src/ags/audio/ags_recall_audio_signal.h src/ags/audio/ags_input.c src/ags/audio/ags_synths.c src/ags/audio/ags_input.h src/ags/audio/ags_recycling_container.h src/ags/audio/ags_recall_id.h src/ags/audio/ags_note.c src/ags/audio/ags_timestamp_factory.c src/ags/audio/ags_channel.c src/ags/audio/ags_recall_audio.c src/ags/audio/ags_audio_signal.c src/ags/audio/ags_output.h src/ags/audio/ags_libao.c src/ags/audio/file/ags_ipatch_sf2_reader.c src/ags/audio/file/ags_audio_file_xml.h src/ags/audio/file/ags_ipatch.c src/ags/audio/file/ags_audio_file.c src/ags/audio/file/ags_sndfile.h src/ags/audio/file/ags_ipatch.h src/ags/audio/file/ags_audio_file.h src/ags/audio/file/ags_ipatch_sf2_reader.h src/ags/audio/file/ags_audio_file_xml.c src/ags/audio/file/ags_sndfile.c src/ags/audio/ags_devout.h src/ags/audio/ags_port.h src/ags/audio/ags_note.h src/ags/audio/ags_timestamp.h src/ags/audio/ags_notation.h src/ags/audio/ags_recall_audio_run.c src/ags/audio/ags_recycling_container.c src/ags/audio/ags_audio_signal.h src/ags/audio/ags_recall_recycling.h src/ags/audio/recall/ags_mute_audio.h src/ags/audio/recall/ags_mute_audio_run.h src/ags/audio/recall/ags_clone_channel.c src/ags/audio/recall/ags_copy_channel.c src/ags/audio/recall/ags_copy_pattern_channel.c src/ags/audio/recall/ags_copy_recycling.c src/ags/audio/recall/ags_volume_audio_signal.h src/ags/audio/recall/ags_play_channel.h src/ags/audio/recall/ags_play_notation_audio_run.c src/ags/audio/recall/ags_buffer_audio_signal.c src/ags/audio/recall/ags_play_channel_run.c src/ags/audio/recall/ags_stream_channel_run.c src/ags/audio/recall/ags_copy_notation_audio_run.c src/ags/audio/recall/ags_mute_channel.c src/ags/audio/recall/ags_count_beats_audio.h src/ags/audio/recall/ags_copy_pattern_audio.c src/ags/audio/recall/ags_copy_pattern_audio_run.c src/ags/audio/recall/ags_clone_channel_run.h src/ags/audio/recall/ags_delay_audio.h src/ags/audio/recall/ags_copy_notation_audio_run.h src/ags/audio/recall/ags_stream.c src/ags/audio/recall/ags_play_audio_file.h src/ags/audio/recall/ags_loop_channel_run.c src/ags/audio/recall/ags_play_pattern.c src/ags/audio/recall/ags_stream_channel_run.h src/ags/audio/recall/ags_amplifier.h src/ags/audio/recall/ags_echo.c src/ags/audio/recall/ags_play_note.c src/ags/audio/recall/ags_buffer_channel.c src/ags/audio/recall/ags_clone_channel_run.c src/ags/audio/recall/ags_peak_channel.h src/ags/audio/recall/ags_peak_recycling.h src/ags/audio/recall/ags_peak_audio_signal.h src/ags/audio/recall/ags_play_recycling.h src/ags/audio/recall/ags_stream_channel.h src/ags/audio/recall/ags_amplifier.c src/ags/audio/recall/ags_mute_audio_signal.h src/ags/audio/recall/ags_copy_notation_audio.c src/ags/audio/recall/ags_buffer_channel_run.h src/ags/audio/recall/ags_copy_recycling.h src/ags/audio/recall/ags_down_mix.h src/ags/audio/recall/ags_volume_recycling.h src/ags/audio/recall/ags_volume_channel_run.h src/ags/audio/recall/ags_stream_channel.c src/ags/audio/recall/ags_echo.h src/ags/audio/recall/ags_delay_audio_run.h src/ags/audio/recall/ags_stream_audio_signal.h src/ags/audio/recall/ags_mute_recycling.c src/ags/audio/recall/ags_play_pattern.h src/ags/audio/recall/ags_delay_audio.c src/ags/audio/recall/ags_buffer_recycling.c src/ags/audio/recall/ags_stream_recycling.h src/ags/audio/recall/ags_play_audio_signal.c src/ags/audio/recall/ags_play_channel_run_master.h src/ags/audio/recall/ags_volume_recycling.c src/ags/audio/recall/ags_loop_channel.c src/ags/audio/recall/ags_buffer_recycling.h src/ags/audio/recall/ags_copy_pattern_channel_run.h src/ags/audio/recall/ags_peak_channel_run.c src/ags/audio/recall/ags_peak_recycling.c src/ags/audio/recall/ags_peak_audio_signal.c src/ags/audio/recall/ags_loop_channel.h src/ags/audio/recall/ags_play_audio.h src/ags/audio/recall/ags_copy_audio_signal.c src/ags/audio/recall/ags_mute_channel_run.h src/ags/audio/recall/ags_copy_channel.h src/ags/audio/recall/ags_play_notation_audio.h src/ags/audio/recall/ags_play_note.h src/ags/audio/recall/ags_synths.h src/ags/audio/recall/ags_play_recycling.c src/ags/audio/recall/ags_mute_channel_run.c src/ags/audio/recall/ags_buffer_channel.h src/ags/audio/recall/ags_play_notation_audio_run.h src/ags/audio/recall/ags_volume_channel_run.c src/ags/audio/recall/ags_play_channel_run_master.c src/ags/audio/recall/ags_stream.h src/ags/audio/recall/ags_copy_pattern_channel.h src/ags/audio/recall/ags_play_channel_run.h src/ags/audio/recall/ags_mute_channel.h src/ags/audio/recall/ags_mute_audio.c src/ags/audio/recall/ags_mute_audio_run.c src/ags/audio/recall/ags_volume_channel.h src/ags/audio/recall/ags_volume_audio_signal.c src/ags/audio/recall/ags_stream_audio_signal.c src/ags/audio/recall/ags_count_beats_audio_run.h src/ags/audio/recall/ags_copy_audio_signal.h src/ags/audio/recall/ags_copy_channel_run.c src/ags/audio/recall/ags_delay_audio_run.c src/ags/audio/recall/ags_mute_audio_signal.c src/ags/audio/recall/ags_copy_notation_audio.h src/ags/audio/recall/ags_clone_channel.h src/ags/audio/recall/ags_buffer_channel_run.c src/ags/audio/recall/ags_play_audio.c src/ags/audio/recall/ags_copy_pattern_audio.h src/ags/audio/recall/ags_count_beats_audio.c src/ags/audio/recall/ags_play_channel.c src/ags/audio/recall/ags_count_beats_audio_run.c src/ags/audio/recall/ags_copy_pattern_audio_run.h src/ags/audio/recall/ags_stream_recycling.c src/ags/audio/recall/ags_play_audio_file.c src/ags/audio/recall/ags_play_notation_audio.c src/ags/audio/recall/ags_loop_channel_run.h src/ags/audio/recall/ags_mute_recycling.h src/ags/audio/recall/ags_peak_channel.c src/ags/audio/recall/ags_buffer_audio_signal.h src/ags/audio/recall/ags_peak_channel_run.h src/ags/audio/recall/ags_volume_channel.c src/ags/audio/recall/ags_play_audio_signal.h src/ags/audio/recall/ags_copy_channel_run.h src/ags/audio/recall/ags_copy_pattern_channel_run.c src/ags/audio/ags_recall_ladspa.h src/ags/audio/ags_recall_recycling.c src/ags/audio/ags_recall.h src/ags/audio/ags_recall_channel_run.h src/ags/audio/ags_recall_audio.h src/ags/audio/ags_channel.h src/ags/audio/ags_pattern.c src/ags/audio/ags_synths.h src/ags/audio/ags_recall_factory.h src/ags/audio/ags_recall_audio_signal.c src/ags/audio/ags_config.h src/ags/audio/ags_effect.h src/ags/audio/ags_pattern.h src/ags/audio/ags_output.c src/ags/audio/ags_recall_channel_run_dummy.c src/ags/audio/ags_recall_dependency.c src/ags/audio/ags_channel_iter.c src/ags/audio/ags_recall_channel_run_dummy.h src/ags/audio/ags_recall.c src/ags/audio/ags_recall_ladspa_run.h src/ags/audio/ags_recall_recycling_dummy.h src/ags/audio/ags_libao.h src/ags/audio/ags_task.h src/ags/audio/ags_config.c src/ags/audio/ags_recall_channel.c src/ags/audio/ags_audio.c src/ags/audio/ags_recall_ladspa_run.c src/ags/audio/ags_recall_audio_run.h src/ags/audio/ags_recall_id.c src/ags/audio/ags_task.c src/ags/audio/ags_recall_ladspa.c src/ags/audio/ags_recall_factory.c src/ags/audio/ags_recall_container.h src/ags/audio/ags_recycling.h src/ags/audio/ags_recall_recycling_dummy.c src/ags/file/ags_file_util.h src/ags/file/ags_file_sound.h src/ags/file/ags_file_thread.h src/ags/file/ags_file_gui.h src/ags/file/ags_file_lookup.h src/ags/file/ags_file_id_ref.c src/ags/file/ags_file.h src/ags/file/ags_file_link.c src/ags/file/ags_file_write.h src/ags/file/ags_file_read.h src/ags/file/ags_file_id_ref.h src/ags/file/ags_file_sound.c src/ags/file/ags_file_thread.c src/ags/file/ags_file_util.c src/ags/file/ags_file_lookup.c src/ags/file/ags_file_launch.c src/ags/file/ags_file_stock.h src/ags/file/ags_file_gui.c src/ags/file/ags_file.c src/ags/file/ags_file_launch.h src/ags/file/ags_file_link.h src/ags/thread/ags_record_thread.c src/ags/thread/ags_thread_pool.h src/ags/thread/ags_timestamp_thread.h src/ags/thread/ags_mutex_manager.h src/ags/thread/ags_mutex_manager.c src/ags/thread/ags_task_thread.h src/ags/thread/ags_audio_loop.h src/ags/thread/ags_gui_task_thread.h src/ags/thread/ags_task_completion.h src/ags/thread/ags_task_completion.c src/ags/thread/ags_recycling_thread.h src/ags/thread/ags_autosave_thread.h src/ags/thread/ags_returnable_thread.c src/ags/thread/ags_autosave_thread.c src/ags/thread/ags_export_thread.h src/ags/thread/ags_history.h src/ags/thread/ags_iterator_thread.h src/ags/thread/ags_devout_thread.c src/ags/thread/ags_thread_pool.c src/ags/thread/ags_gui_task_thread.c src/ags/thread/ags_gui_thread.h src/ags/thread/ags_task_thread.c src/ags/thread/ags_timestamp_thread.c src/ags/thread/ags_thread-posix.h src/ags/thread/ags_async_queue.h src/ags/thread/ags_record_thread.h src/ags/thread/ags_recycling_thread_callbacks.c src/ags/thread/ags_recycling_thread_callbacks.h src/ags/thread/ags_iterator_thread.c src/ags/thread/ags_async_queue.c src/ags/thread/ags_export_thread.c src/ags/thread/ags_audio_loop.c src/ags/thread/ags_returnable_thread.h src/ags/thread/ags_recycling_thread.c src/ags/thread/ags_devout_thread.h src/ags/thread/ags_single_thread.h src/ags/thread/ags_thread-posix.c src/ags/thread/ags_history.c src/ags/thread/ags_gui_thread.c src/ags/thread/ags_single_thread.c src/ags/server/ags_registry.c src/ags/server/ags_registry.h src/ags/server/ags_server.h src/ags/server/ags_remote_task.h src/ags/server/ags_remote_task.c src/ags/server/ags_server.c src/ags/plugin/ags_plugin_stock.h src/ags/plugin/ags_plugin_factory.h src/ags/plugin/ags_ladspa_manager.h src/ags/plugin/ags_plugin_factory.c src/ags/plugin/ags_ladspa_manager.c src/ags/main.h
 
-EXTRA_DIST += ags.desktop.in
-CLEANFILES += $(appdata_DATA)
+midi2xml_CFLAGS= $(CFLAGS) $(LIBXML2_CFLAGS) $(GOBJECT_CFLAGS)
+midi2xml_LDFLAGS= -ldl $(LDFLAGS) $(LIBXML2_LIBS) $(GOBJECT_LIBS)
+
+midi2xml_SOURCES = src/midi2ags/main.c src/midi2ags/midi/ags_midi_parser.c src/midi2ags/midi/ags_midi_parser.h src/midi2ags/object/ags_marshal.c src/midi2ags/object/ags_marshal.h
 
-ags_SOURCES = ./src/ags-lib/object/ags_connectable.c ./src/ags-lib/object/ags_connectable.h src/ags/lib/ags_combo_box_text.c src/ags/lib/ags_list.c src/ags/lib/ags_container.c src/ags/lib/ags_parameter.h src/ags/lib/ags_list.h src/ags/lib/ags_log.c src/ags/lib/ags_container.h src/ags/lib/ags_combo_box_text.h src/ags/lib/ags_log.h src/ags/lib/ags_parameter.c src/ags/X/editor/ags_notebook_callbacks.c src/ags/X/editor/ags_meter.h src/ags/X/editor/ags_toolbar.h src/ags/X/editor/ags_machine_radio_button.h src/ags/X/editor/ags_file_selection_callbacks.h src/ags/X/editor/ags_notebook_callbacks.h src/ags/X/editor/ags_note_edit.h src/ags/X/editor/ags_meter_callbacks.c src/ags/X/editor/ags_notebook.h src/ags/X/editor/ags_sf2_chooser.h src/ags/X/editor/ags_toolbar_mode_stock.h src/ags/X/editor/ags_meter_callbacks.h src/ags/X/editor/ags_toolbar_callbacks.c src/ags/X/editor/ags_machine_selector.c src/ags/X/editor/ags_machine_selector_callbacks.c src/ags/X/editor/ags_machine_radio_button.c src/ags/X/editor/ags_sf2_chooser.c src/ags/X/editor/ags_machine_selector_callbacks.h src/ags/X/editor/ags_sf2_chooser_callbacks.c src/ags/X/editor/ags_notebook.c src/ags/X/editor/ags_note_edit_callbacks.c src/ags/X/editor/ags_file_selection_callbacks.c src/ags/X/editor/ags_machine_selection.c src/ags/X/editor/ags_inline_player_callbacks.h src/ags/X/editor/ags_inline_player.c src/ags/X/editor/ags_meter.c src/ags/X/editor/ags_file_selection.h src/ags/X/editor/ags_inline_player.h src/ags/X/editor/ags_sf2_chooser_callbacks.h src/ags/X/editor/ags_file_selection.c src/ags/X/editor/ags_machine_selector.h src/ags/X/editor/ags_note_edit_callbacks.h src/ags/X/editor/ags_note_edit.c src/ags/X/editor/ags_inline_player_callbacks.c src/ags/X/editor/ags_toolbar_callbacks.h src/ags/X/editor/ags_machine_selection.h src/ags/X/editor/ags_toolbar.c src/ags/X/ags_line_callbacks.h src/ags/X/ags_plugin_preferences.c src/ags/X/ags_link_editor.c src/ags/X/ags_pad_callbacks.h src/ags/X/ags_machine_callbacks.c src/ags/X/ags_server_preferences_callbacks.h src/ags/X/ags_listing_editor_callbacks.c src/ags/X/ags_link_collection_editor_callbacks.c src/ags/X/ags_generic_preferences_callbacks.c src/ags/X/ags_property_collection_editor_callbacks.c src/ags/X/ags_property_collection_editor.h src/ags/X/ags_resize_editor.h src/ags/X/ags_property_editor.h src/ags/X/ags_window_callbacks.h src/ags/X/ags_property_editor_callbacks.c src/ags/X/machine/ags_synth_callbacks.h src/ags/X/machine/ags_synth.c src/ags/X/machine/ags_mixer.c src/ags/X/machine/ags_matrix_callbacks.c src/ags/X/machine/ags_panel_input_line.c src/ags/X/machine/ags_synth_input_line.c src/ags/X/machine/ags_drum_callbacks.h src/ags/X/machine/ags_mixer_callbacks.c src/ags/X/machine/ags_synth_callbacks.c src/ags/X/machine/ags_ffplayer_callbacks.h src/ags/X/machine/ags_drum_input_line.h src/ags/X/machine/ags_matrix.h src/ags/X/machine/ags_mixer_input_line.c src/ags/X/machine/ags_oscillator.c src/ags/X/machine/ags_oscillator.h src/ags/X/machine/ags_oscillator_callbacks.h src/ags/X/machine/ags_mixer.h src/ags/X/machine/ags_panel_input_pad.h src/ags/X/machine/ags_panel_input_pad.c src/ags/X/machine/ags_matrix.c src/ags/X/machine/ags_panel.h src/ags/X/machine/ags_drum_output_line_callbacks.c src/ags/X/machine/ags_ffplayer.h src/ags/X/machine/ags_panel_callbacks.c src/ags/X/machine/ags_mixer_input_pad.c src/ags/X/machine/ags_panel.c src/ags/X/machine/ags_drum.c src/ags/X/machine/ags_matrix_callbacks.h src/ags/X/machine/ags_drum_output_line.h src/ags/X/machine/ags_drum_output_pad.h src/ags/X/machine/ags_synth_input_pad.h src/ags/X/machine/ags_panel_callbacks.h src/ags/X/machine/ags_ffplayer.c src/ags/X/machine/ags_drum_output_line_callbacks.h src/ags/X/machine/ags_drum_output_pad_callbacks.c src/ags/X/machine/ags_drum_output_pad_callbacks.h src/ags/X/machine/ags_drum_input_pad_callbacks.h src/ags/X/machine/ags_oscillator_callbacks.c src/ags/X/machine/ags_drum_callbacks.c src/ags/X/machine/ags_synth_input_line.h src/ags/X/machine/ags_drum_input_pad_callbacks.c src/ags/X/machine/ags_drum_input_pad.c src/ags/X/machine/ags_panel_input_line.h src/ags/X/machine/ags_drum_input_line_callbacks.h src/ags/X/machine/ags_drum_output_line.c src/ags/X/machine/ags_mixer_callbacks.h src/ags/X/machine/ags_synth.h src/ags/X/machine/ags_mixer_input_line.h src/ags/X/machine/ags_drum.h src/ags/X/machine/ags_drum_input_line.c src/ags/X/machine/ags_ffplayer_callbacks.c src/ags/X/machine/ags_drum_output_pad.c src/ags/X/machine/ags_drum_input_pad.h src/ags/X/machine/ags_drum_input_line_callbacks.c src/ags/X/machine/ags_mixer_input_pad.h src/ags/X/machine/ags_synth_input_pad.c src/ags/X/ags_server_preferences.h src/ags/X/ags_line_editor_callbacks.h src/ags/X/ags_pad_editor_callbacks.c src/ags/X/ags_listing_editor_callbacks.h src/ags/X/ags_line_member_callbacks.c src/ags/X/ags_editor.h src/ags/X/ags_machine_editor.h src/ags/X/ags_plugin_preferences_callbacks.h src/ags/X/ags_export_window_callbacks.h src/ags/X/ags_editor_callbacks.c src/ags/X/ags_pad_editor.h src/ags/X/ags_server_preferences.c src/ags/X/ags_line_editor.c src/ags/X/ags_ladspa_browser.h src/ags/X/ags_audio_preferences.c src/ags/X/ags_pad.c src/ags/X/ags_line.c src/ags/X/ags_menu_bar_callbacks.c src/ags/X/ags_generic_preferences_callbacks.h src/ags/X/ags_pad.h src/ags/X/ags_audio_preferences_callbacks.h src/ags/X/ags_generic_preferences.c src/ags/X/ags_window.c src/ags/X/ags_machine_editor_callbacks.h src/ags/X/ags_editor_callbacks.h src/ags/X/ags_menu_bar_callbacks.h src/ags/X/ags_line_member_editor.h src/ags/X/ags_property_collection_editor_callbacks.h src/ags/X/ags_line_editor_callbacks.c src/ags/X/ags_property_editor.c src/ags/X/ags_link_editor_callbacks.c src/ags/X/ags_server_preferences_callbacks.c src/ags/X/ags_pad_callbacks.c src/ags/X/ags_line_member.h src/ags/X/ags_audio_preferences_callbacks.c src/ags/X/ags_performance_preferences.h src/ags/X/ags_property_collection_editor.c src/ags/X/ags_performance_preferences_callbacks.h src/ags/X/ags_line.h src/ags/X/ags_machine.c src/ags/X/ags_preferences_callbacks.c src/ags/X/ags_export_window.c src/ags/X/ags_menu_bar.c src/ags/X/ags_plugin_preferences_callbacks.c src/ags/X/ags_line_member_callbacks.h src/ags/X/ags_preferences.c src/ags/X/ags_export_window.h src/ags/X/ags_pad_editor_callbacks.h src/ags/X/ags_window.h src/ags/X/ags_machine_callbacks.h src/ags/X/ags_machine.h src/ags/X/ags_line_callbacks.c src/ags/X/ags_link_editor_callbacks.h src/ags/X/ags_navigation_callbacks.h src/ags/X/ags_pad_editor.c src/ags/X/ags_ladspa_browser.c src/ags/X/ags_editor.c src/ags/X/ags_resize_editor.c src/ags/X/ags_property_listing_editor.c src/ags/X/ags_property_editor_callbacks.h src/ags/X/ags_line_member_editor_callbacks.h src/ags/X/ags_window_callbacks.c src/ags/X/ags_audio_preferences.h src/ags/X/ags_navigation_callbacks.c src/ags/X/ags_plugin_preferences.h src/ags/X/ags_performance_preferences_callbacks.c src/ags/X/ags_line_member.c src/ags/X/ags_preferences.h src/ags/X/ags_generic_preferences.h src/ags/X/ags_navigation.h src/ags/X/ags_listing_editor.h src/ags/X/ags_performance_preferences.c src/ags/X/ags_link_editor.h src/ags/X/ags_ladspa_browser_callbacks.c src/ags/X/ags_link_collection_editor.c src/ags/X/ags_preferences_callbacks.h src/ags/X/ags_machine_editor_callbacks.c src/ags/X/ags_menu_bar.h src/ags/X/ags_export_window_callbacks.c src/ags/X/ags_line_member_editor_callbacks.c src/ags/X/ags_link_collection_editor.h src/ags/X/ags_link_collection_editor_callbacks.h src/ags/X/ags_property_listing_editor.h src/ags/X/ags_navigation.c src/ags/X/ags_machine_editor.c src/ags/X/ags_line_member_editor.c src/ags/X/ags_ladspa_browser_callbacks.h src/ags/X/ags_line_editor.h src/ags/X/ags_listing_editor.c src/ags/object/ags_applicable.c src/ags/object/ags_seekable.h src/ags/object/ags_packable.c src/ags/object/ags_persistable.h src/ags/object/ags_packable.h src/ags/object/ags_applicable.h src/ags/object/ags_main_loop.c src/ags/object/ags_soundcard.c src/ags/object/ags_marshal.c src/ags/object/ags_mutable.h src/ags/object/ags_plugin.h src/ags/object/ags_stackable.h src/ags/object/ags_runnable.c src/ags/object/ags_tactable.h src/ags/object/ags_mutable.c src/ags/object/ags_runnable.h src/ags/object/ags_effect.c src/ags/object/ags_playable.c src/ags/object/ags_dynamic_connectable.c src/ags/object/ags_seekable.c src/ags/object/ags_countable.c src/ags/object/ags_plugin.c src/ags/object/ags_tree_iterator.h src/ags/object/ags_playable.h src/ags/object/ags_effect.h src/ags/object/ags_soundcard.h src/ags/object/ags_countable.h src/ags/object/ags_marshal.h src/ags/object/ags_portlet.h src/ags/object/ags_dynamic_connectable.h src/ags/object/ags_tactable.c src/ags/object/ags_tree_iterator.c src/ags/object/ags_persistable.c src/ags/object/ags_main_loop.h src/ags/object/ags_stackable.c src/ags/object/ags_portlet.c src/ags/util/ags_id_generator.c src/ags/util/ags_id_generator.h src/ags/widget/ags_led.h src/ags/widget/ags_expander_set.c src/ags/widget/ags_expander_set.h src/ags/widget/ags_menu.c src/ags/widget/ags_hindicator.h src/ags/widget/ags_menu.h src/ags/widget/ags_timebar.c src/ags/widget/ags_dial.c src/ags/widget/ags_ruler.h src/ags/widget/ags_dial.h src/ags/widget/ags_segment.c src/ags/widget/ags_htimebar.c src/ags/widget/ags_option_menu.h src/ags/widget/ags_indicator.c src/ags/widget/ags_htimebar.h src/ags/widget/ags_option_menu.c src/ags/widget/ags_expander.h src/ags/widget/ags_menu_item.h src/ags/widget/ags_hindicator.c src/ags/widget/ags_cartesian.h src/ags/widget/ags_indicator.h src/ags/widget/ags_cartesian.c src/ags/widget/ags_menu_item.c src/ags/widget/ags_waveform.c src/ags/widget/ags_ruler.c src/ags/widget/ags_expander.c src/ags/widget/ags_vindicator.c src/ags/widget/ags_timebar.h src/ags/widget/ags_led.c src/ags/widget/ags_waveform.h src/ags/widget/ags_table.c src/ags/widget/ags_table.h src/ags/widget/ags_vindicator.h src/ags/widget/ags_segment.h src/ags/main.c src/ags/audio/task/ags_export_output.h src/ags/audio/task/ags_set_output_device.c src/ags/audio/task/ags_add_audio.h src/ags/audio/task/ags_set_samplerate.c src/ags/audio/task/ags_remove_point_from_selection.c src/ags/audio/task/ags_save_file.h src/ags/audio/task/ags_set_buffer_size.h src/ags/audio/task/ags_link_channel.c src/ags/audio/task/ags_save_file.c src/ags/audio/task/ags_append_audio_threaded.h src/ags/audio/task/ags_cancel_channel.h src/ags/audio/task/ags_apply_synth.h src/ags/audio/task/ags_seek_devout.h src/ags/audio/task/ags_append_recall.h src/ags/audio/task/ags_add_audio_signal.c src/ags/audio/task/ags_unref_audio_signal.c src/ags/audio/task/ags_remove_region_from_selection.c src/ags/audio/task/ags_change_indicator.h src/ags/audio/task/ags_remove_point_from_selection.h src/ags/audio/task/ags_set_audio_channels.h src/ags/audio/task/ags_scroll_on_play.h src/ags/audio/task/ags_remove_audio.h src/ags/audio/task/ags_remove_recall_container.c src/ags/audio/task/ags_remove_recall.c src/ags/audio/task/ags_seek_devout.c src/ags/audio/task/ags_append_recall.c src/ags/audio/task/ags_free_selection.h src/ags/audio/task/ags_add_recall_container.c src/ags/audio/task/ags_add_recall.c src/ags/audio/task/ags_export_output.c src/ags/audio/task/ags_init_channel.h src/ags/audio/task/ags_remove_note.c src/ags/audio/task/ags_apply_wavetable.h src/ags/audio/task/ags_add_audio_signal.h src/ags/audio/task/ags_cancel_recall.h src/ags/audio/task/ags_set_audio_channels.c src/ags/audio/task/ags_cancel_audio.c src/ags/audio/task/ags_unref_audio_signal.h src/ags/audio/task/ags_add_region_to_selection.c src/ags/audio/task/ags_change_tact.h src/ags/audio/task/ags_init_audio.c src/ags/audio/task/ags_channel_set_recycling.c src/ags/audio/task/ags_display_tact.c src/ags/audio/task/ags_add_point_to_selection.h src/ags/audio/task/ags_toggle_pattern_bit.h src/ags/audio/task/ags_append_channel.c src/ags/audio/task/ags_change_indicator.c src/ags/audio/task/ags_add_note.c src/ags/audio/task/ags_channel_set_recycling.h src/ags/audio/task/ags_cancel_audio.h src/ags/audio/task/recall/ags_set_muted.c src/ags/audio/task/recall/ags_set_muted.h src/ags/audio/task/recall/ags_apply_sequencer_length.c src/ags/audio/task/recall/ags_apply_bpm.h src/ags/audio/task/recall/ags_apply_tact.c src/ags/audio/task/recall/ags_apply_bpm.c src/ags/audio/task/recall/ags_apply_sequencer_length.h src/ags/audio/task/recall/ags_apply_tact.h src/ags/audio/task/ags_remove_region_from_selection.h src/ags/audio/task/ags_cancel_channel.c src/ags/audio/task/ags_add_recall_container.h src/ags/audio/task/ags_add_recall.h src/ags/audio/task/ags_add_note.h src/ags/audio/task/ags_start_devout.c src/ags/audio/task/ags_append_audio_threaded.c src/ags/audio/task/ags_append_audio.c src/ags/audio/task/ags_init_channel.c src/ags/audio/task/ags_remove_audio_signal.h src/ags/audio/task/ags_toggle_led.c src/ags/audio/task/ags_set_buffer_size.c src/ags/audio/task/ags_add_region_to_selection.h src/ags/audio/task/ags_audio_set_recycling.h src/ags/audio/task/ags_toggle_led.h src/ags/audio/task/ags_resize_audio.h src/ags/audio/task/ags_free_selection.c src/ags/audio/task/ags_add_audio.c src/ags/audio/task/ags_set_samplerate.h src/ags/audio/task/ags_apply_synth.c src/ags/audio/task/ags_open_single_file.h src/ags/audio/task/ags_remove_audio.c src/ags/audio/task/ags_cancel_recall.c src/ags/audio/task/ags_init_audio.h src/ags/audio/task/ags_remove_note.h src/ags/audio/task/ags_remove_audio_signal.c src/ags/audio/task/ags_audio_set_recycling.c src/ags/audio/task/ags_add_point_to_selection.c src/ags/audio/task/ags_scroll_on_play.c src/ags/audio/task/ags_set_devout_play_flags.c src/ags/audio/task/ags_apply_wavetable.c src/ags/audio/task/ags_add_line_member.c src/ags/audio/task/ags_open_file.h src/ags/audio/task/ags_set_output_device.h src/ags/audio/task/ags_toggle_pattern_bit.c src/ags/audio/task/ags_open_file.c src/ags/audio/task/ags_open_single_file.c src/ags/audio/task/ags_append_audio.h src/ags/audio/task/ags_start_devout.h src/ags/audio/task/ags_display_tact.h src/ags/audio/task/ags_remove_recall_container.h src/ags/audio/task/ags_remove_recall.h src/ags/audio/task/ags_change_tact.c src/ags/audio/task/ags_append_channel.h src/ags/audio/task/ags_resize_audio.c src/ags/audio/task/ags_link_channel.h src/ags/audio/task/ags_add_line_member.h src/ags/audio/task/ags_set_devout_play_flags.h src/ags/audio/ags_devout.c src/ags/audio/ags_recall_channel.h src/ags/audio/ags_timestamp_factory.h src/ags/audio/ags_garbage_collector.c src/ags/audio/ags_garbage_collector.h src/ags/audio/ags_recall_container.c src/ags/audio/ags_timestamp.c src/ags/audio/ags_channel_iter.h src/ags/audio/ags_recall_channel_run.c src/ags/audio/ags_audio.h src/ags/audio/ags_port.c src/ags/audio/ags_notation.c src/ags/audio/ags_recall_dependency.h src/ags/audio/ags_recycling.c src/ags/audio/ags_recall_audio_signal.h src/ags/audio/ags_input.c src/ags/audio/ags_synths.c src/ags/audio/ags_input.h src/ags/audio/ags_recycling_container.h src/ags/audio/ags_recall_id.h src/ags/audio/ags_note.c src/ags/audio/ags_timestamp_factory.c src/ags/audio/ags_channel.c src/ags/audio/ags_recall_audio.c src/ags/audio/ags_audio_signal.c src/ags/audio/ags_output.h src/ags/audio/ags_libao.c src/ags/audio/file/ags_ipatch_sf2_reader.c src/ags/audio/file/ags_audio_file_xml.h src/ags/audio/file/ags_ipatch.c src/ags/audio/file/ags_audio_file.c src/ags/audio/file/ags_sndfile.h src/ags/audio/file/ags_ipatch.h src/ags/audio/file/ags_audio_file.h src/ags/audio/file/ags_ipatch_sf2_reader.h src/ags/audio/file/ags_audio_file_xml.c src/ags/audio/file/ags_sndfile.c src/ags/audio/ags_devout.h src/ags/audio/ags_port.h src/ags/audio/ags_note.h src/ags/audio/ags_timestamp.h src/ags/audio/ags_notation.h src/ags/audio/ags_recall_audio_run.c src/ags/audio/ags_recycling_container.c src/ags/audio/ags_audio_signal.h src/ags/audio/ags_recall_recycling.h src/ags/audio/recall/ags_mute_audio.h src/ags/audio/recall/ags_mute_audio_run.h src/ags/audio/recall/ags_clone_channel.c src/ags/audio/recall/ags_copy_channel.c src/ags/audio/recall/ags_copy_pattern_channel.c src/ags/audio/recall/ags_copy_recycling.c src/ags/audio/recall/ags_volume_audio_signal.h src/ags/audio/recall/ags_play_channel.h src/ags/audio/recall/ags_play_notation_audio_run.c src/ags/audio/recall/ags_buffer_audio_signal.c src/ags/audio/recall/ags_play_channel_run.c src/ags/audio/recall/ags_stream_channel_run.c src/ags/audio/recall/ags_copy_notation_audio_run.c src/ags/audio/recall/ags_mute_channel.c src/ags/audio/recall/ags_count_beats_audio.h src/ags/audio/recall/ags_copy_pattern_audio.c src/ags/audio/recall/ags_copy_pattern_audio_run.c src/ags/audio/recall/ags_clone_channel_run.h src/ags/audio/recall/ags_delay_audio.h src/ags/audio/recall/ags_copy_notation_audio_run.h src/ags/audio/recall/ags_stream.c src/ags/audio/recall/ags_play_audio_file.h src/ags/audio/recall/ags_loop_channel_run.c src/ags/audio/recall/ags_play_pattern.c src/ags/audio/recall/ags_stream_channel_run.h src/ags/audio/recall/ags_amplifier.h src/ags/audio/recall/ags_echo.c src/ags/audio/recall/ags_play_note.c src/ags/audio/recall/ags_buffer_channel.c src/ags/audio/recall/ags_clone_channel_run.c src/ags/audio/recall/ags_peak_channel.h src/ags/audio/recall/ags_peak_recycling.h src/ags/audio/recall/ags_peak_audio_signal.h src/ags/audio/recall/ags_play_recycling.h src/ags/audio/recall/ags_stream_channel.h src/ags/audio/recall/ags_amplifier.c src/ags/audio/recall/ags_mute_audio_signal.h src/ags/audio/recall/ags_copy_notation_audio.c src/ags/audio/recall/ags_buffer_channel_run.h src/ags/audio/recall/ags_copy_recycling.h src/ags/audio/recall/ags_down_mix.h src/ags/audio/recall/ags_volume_recycling.h src/ags/audio/recall/ags_volume_channel_run.h src/ags/audio/recall/ags_stream_channel.c src/ags/audio/recall/ags_echo.h src/ags/audio/recall/ags_delay_audio_run.h src/ags/audio/recall/ags_stream_audio_signal.h src/ags/audio/recall/ags_mute_recycling.c src/ags/audio/recall/ags_play_pattern.h src/ags/audio/recall/ags_delay_audio.c src/ags/audio/recall/ags_buffer_recycling.c src/ags/audio/recall/ags_stream_recycling.h src/ags/audio/recall/ags_play_audio_signal.c src/ags/audio/recall/ags_play_channel_run_master.h src/ags/audio/recall/ags_volume_recycling.c src/ags/audio/recall/ags_loop_channel.c src/ags/audio/recall/ags_buffer_recycling.h src/ags/audio/recall/ags_copy_pattern_channel_run.h src/ags/audio/recall/ags_peak_channel_run.c src/ags/audio/recall/ags_peak_recycling.c src/ags/audio/recall/ags_peak_audio_signal.c src/ags/audio/recall/ags_loop_channel.h src/ags/audio/recall/ags_play_audio.h src/ags/audio/recall/ags_copy_audio_signal.c src/ags/audio/recall/ags_mute_channel_run.h src/ags/audio/recall/ags_copy_channel.h src/ags/audio/recall/ags_play_notation_audio.h src/ags/audio/recall/ags_play_note.h src/ags/audio/recall/ags_synths.h src/ags/audio/recall/ags_play_recycling.c src/ags/audio/recall/ags_mute_channel_run.c src/ags/audio/recall/ags_buffer_channel.h src/ags/audio/recall/ags_play_notation_audio_run.h src/ags/audio/recall/ags_volume_channel_run.c src/ags/audio/recall/ags_play_channel_run_master.c src/ags/audio/recall/ags_stream.h src/ags/audio/recall/ags_copy_pattern_channel.h src/ags/audio/recall/ags_play_channel_run.h src/ags/audio/recall/ags_mute_channel.h src/ags/audio/recall/ags_mute_audio.c src/ags/audio/recall/ags_mute_audio_run.c src/ags/audio/recall/ags_volume_channel.h src/ags/audio/recall/ags_volume_audio_signal.c src/ags/audio/recall/ags_stream_audio_signal.c src/ags/audio/recall/ags_count_beats_audio_run.h src/ags/audio/recall/ags_copy_audio_signal.h src/ags/audio/recall/ags_copy_channel_run.c src/ags/audio/recall/ags_delay_audio_run.c src/ags/audio/recall/ags_mute_audio_signal.c src/ags/audio/recall/ags_copy_notation_audio.h src/ags/audio/recall/ags_clone_channel.h src/ags/audio/recall/ags_buffer_channel_run.c src/ags/audio/recall/ags_play_audio.c src/ags/audio/recall/ags_copy_pattern_audio.h src/ags/audio/recall/ags_count_beats_audio.c src/ags/audio/recall/ags_play_channel.c src/ags/audio/recall/ags_count_beats_audio_run.c src/ags/audio/recall/ags_copy_pattern_audio_run.h src/ags/audio/recall/ags_stream_recycling.c src/ags/audio/recall/ags_play_audio_file.c src/ags/audio/recall/ags_play_notation_audio.c src/ags/audio/recall/ags_loop_channel_run.h src/ags/audio/recall/ags_mute_recycling.h src/ags/audio/recall/ags_peak_channel.c src/ags/audio/recall/ags_buffer_audio_signal.h src/ags/audio/recall/ags_peak_channel_run.h src/ags/audio/recall/ags_volume_channel.c src/ags/audio/recall/ags_play_audio_signal.h src/ags/audio/recall/ags_copy_channel_run.h src/ags/audio/recall/ags_copy_pattern_channel_run.c src/ags/audio/ags_recall_ladspa.h src/ags/audio/ags_recall_recycling.c src/ags/audio/ags_recall.h src/ags/audio/ags_recall_channel_run.h src/ags/audio/ags_recall_audio.h src/ags/audio/ags_channel.h src/ags/audio/ags_pattern.c src/ags/audio/ags_synths.h src/ags/audio/ags_recall_factory.h src/ags/audio/ags_recall_audio_signal.c src/ags/audio/ags_config.h src/ags/audio/ags_effect.h src/ags/audio/ags_pattern.h src/ags/audio/ags_output.c src/ags/audio/ags_recall_channel_run_dummy.c src/ags/audio/ags_recall_dependency.c src/ags/audio/ags_channel_iter.c src/ags/audio/ags_recall_channel_run_dummy.h src/ags/audio/ags_recall.c src/ags/audio/ags_recall_ladspa_run.h src/ags/audio/ags_recall_recycling_dummy.h src/ags/audio/ags_libao.h src/ags/audio/ags_task.h src/ags/audio/ags_config.c src/ags/audio/ags_recall_channel.c src/ags/audio/ags_audio.c src/ags/audio/ags_recall_ladspa_run.c src/ags/audio/ags_recall_audio_run.h src/ags/audio/ags_recall_id.c src/ags/audio/ags_task.c src/ags/audio/ags_recall_ladspa.c src/ags/audio/ags_recall_factory.c src/ags/audio/ags_recall_container.h src/ags/audio/ags_recycling.h src/ags/audio/ags_recall_recycling_dummy.c src/ags/file/ags_file_util.h src/ags/file/ags_file_sound.h src/ags/file/ags_file_thread.h src/ags/file/ags_file_gui.h src/ags/file/ags_file_lookup.h src/ags/file/ags_file_id_ref.c src/ags/file/ags_file.h src/ags/file/ags_file_link.c src/ags/file/ags_file_write.h src/ags/file/ags_file_read.h src/ags/file/ags_file_id_ref.h src/ags/file/ags_file_sound.c src/ags/file/ags_file_thread.c src/ags/file/ags_file_util.c src/ags/file/ags_file_lookup.c src/ags/file/ags_file_launch.c src/ags/file/ags_file_stock.h src/ags/file/ags_file_gui.c src/ags/file/ags_file.c src/ags/file/ags_file_launch.h src/ags/file/ags_file_link.h src/ags/thread/ags_record_thread.c src/ags/thread/ags_thread_pool.h src/ags/thread/ags_timestamp_thread.h src/ags/thread/ags_mutex_manager.h src/ags/thread/ags_mutex_manager.c src/ags/thread/ags_task_thread.h src/ags/thread/ags_audio_loop.h src/ags/thread/ags_gui_task_thread.h src/ags/thread/ags_task_completion.h src/ags/thread/ags_task_completion.c src/ags/thread/ags_recycling_thread.h src/ags/thread/ags_autosave_thread.h src/ags/thread/ags_returnable_thread.c src/ags/thread/ags_autosave_thread.c src/ags/thread/ags_export_thread.h src/ags/thread/ags_history.h src/ags/thread/ags_iterator_thread.h src/ags/thread/ags_devout_thread.c src/ags/thread/ags_thread_pool.c src/ags/thread/ags_gui_task_thread.c src/ags/thread/ags_gui_thread.h src/ags/thread/ags_task_thread.c src/ags/thread/ags_timestamp_thread.c src/ags/thread/ags_thread-posix.h src/ags/thread/ags_async_queue.h src/ags/thread/ags_record_thread.h src/ags/thread/ags_recycling_thread_callbacks.c src/ags/thread/ags_recycling_thread_callbacks.h src/ags/thread/ags_iterator_thread.c src/ags/thread/ags_async_queue.c src/ags/thread/ags_export_thread.c src/ags/thread/ags_audio_loop.c src/ags/thread/ags_returnable_thread.h src/ags/thread/ags_recycling_thread.c src/ags/thread/ags_devout_thread.h src/ags/thread/ags_single_thread.h src/ags/thread/ags_thread-posix.c src/ags/thread/ags_history.c src/ags/thread/ags_gui_thread.c src/ags/thread/ags_single_thread.c src/ags/server/ags_registry.c src/ags/server/ags_registry.h src/ags/server/ags_server.h src/ags/server/ags_remote_task.h src/ags/server/ags_remote_task.c src/ags/server/ags_server.c src/ags/plugin/ags_plugin_stock.h src/ags/plugin/ags_plugin_factory.h src/ags/plugin/ags_ladspa_manager.h src/ags/plugin/ags_plugin_factory.c src/ags/plugin/ags_ladspa_manager.c src/ags/main.h
 
 ags.desktop: ags.desktop.in
 	$(AM_V_GEN)sed -e 's,\@datadir\@,$(datadir),g' < "$<" > $@
 
-install-data-local:
+html:
+	mkdir -p html/
+	xsltproc --output html/ --xinclude /usr/share/xml/docbook/stylesheet/docbook-xsl/htmlhelp/htmlhelp.xsl $(top_srcdir)/doc/usersBook.xml
+
+all: html
+
+install-data-local: install-html
 	mkdir -p $(DESTDIR)/$(datadir)/gsequencer/icons
 	mkdir -p $(DESTDIR)/$(datadir)/gsequencer/images
 	cp $(top_srcdir)/gsequencer.share/icons/ags.xpm $(DESTDIR)/$(datadir)/gsequencer/icons/ags.xpm
 	cp $(top_srcdir)/gsequencer.share/images/ags.png $(DESTDIR)/$(datadir)/gsequencer/images/ags.png
 
+install-html:
+	mkdir -p $(DESTDIR)/$(datadir)/doc/gsequencer/{images,html}/
+	cp $(userdocimages) $(DESTDIR)/$(datadir)/doc/gsequencer/images/
+	cp html/* $(DESTDIR)/$(datadir)/doc/gsequencer/html/
+
 uninstall-hook:
 	rm -rf $(DESTDIR)/$(datadir)/gsequencer
+	rm -rf $(DESTDIR)/$(datadir)/doc/gsequencer
+
+clean-local:
+	rm -rf html
diff --git a/Makefile.in b/Makefile.in
index 7c131f6..bc5069e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -78,7 +78,7 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
-bin_PROGRAMS = ags$(EXEEXT)
+bin_PROGRAMS = ags$(EXEEXT) midi2xml$(EXEEXT)
 subdir = .
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/configure $(am__configure_deps) \
@@ -97,7 +97,7 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LIBRARIES = $(noinst_LIBRARIES)
 am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
-	"$(DESTDIR)$(appdatadir)"
+	"$(DESTDIR)$(appdatadir)" "$(DESTDIR)$(docdir)"
 PROGRAMS = $(bin_PROGRAMS)
 am_ags_OBJECTS = ags-ags_connectable.$(OBJEXT) \
 	ags-ags_combo_box_text.$(OBJEXT) ags-ags_list.$(OBJEXT) \
@@ -344,6 +344,13 @@ ags_OBJECTS = $(am_ags_OBJECTS)
 ags_DEPENDENCIES =
 ags_LINK = $(CCLD) $(ags_CFLAGS) $(CFLAGS) $(ags_LDFLAGS) $(LDFLAGS) \
 	-o $@
+am_midi2xml_OBJECTS = midi2xml-main.$(OBJEXT) \
+	midi2xml-ags_midi_parser.$(OBJEXT) \
+	midi2xml-ags_marshal.$(OBJEXT)
+midi2xml_OBJECTS = $(am_midi2xml_OBJECTS)
+midi2xml_LDADD = $(LDADD)
+midi2xml_LINK = $(CCLD) $(midi2xml_CFLAGS) $(CFLAGS) \
+	$(midi2xml_LDFLAGS) $(LDFLAGS) -o $@
 AM_V_P = $(am__v_P_ at AM_V@)
 am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -376,8 +383,8 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(ags_SOURCES)
-DIST_SOURCES = $(ags_SOURCES)
+SOURCES = $(ags_SOURCES) $(midi2xml_SOURCES)
+DIST_SOURCES = $(ags_SOURCES) $(midi2xml_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -413,7 +420,7 @@ am__uninstall_files_from_dir = { \
 man1dir = $(mandir)/man1
 NROFF = nroff
 MANS = $(man1_MANS)
-DATA = $(appdata_DATA)
+DATA = $(appdata_DATA) $(doc_DATA)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
 	$(LISP)config.h.in
 # Read a list of newline-separated strings from the standard input,
@@ -540,7 +547,7 @@ build_alias = @build_alias@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
-docdir = @docdir@
+docdir = $(datadir)/doc/gsequencer
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host_alias = @host_alias@
@@ -574,9 +581,45 @@ AM_CPPFLAGS = -I$(top_srcdir)/src -DDESTDIR=\"$(DESTDIR)$(datadir)\" -D_FORTIFY_
 # this lists the binaries to produce, the (non-PHONY, binary) targets in
 # the previous manual Makefile
 noinst_LIBRARIES = 
-EXTRA_DIST = gsequencer.share acsite.m4 ags.1 ags.desktop.in
+EXTRA_DIST = gsequencer.share acsite.m4 ags.1 midi2xml.1 README \
+	ags.desktop.in $(userdoc) $(userdocimages)
 CLEANFILES = $(appdata_DATA)
-man1_MANS = ags.1
+man1_MANS = ags.1 midi2xml.1
+appdatadir = $(datadir)/applications
+appdata_DATA = ags.desktop
+doc_DATA = README
+
+# documentation
+userdoc = \
+	doc/usersBook.xml \
+	doc/appa.xml \
+	doc/usersBook/appb.xml \
+	doc/usersBook/chap1.xml \
+	doc/usersBook/chap2.xml \
+	doc/usersBook/chap3.xml \
+	doc/usersBook/chap4.xml \
+	doc/usersBook/preface.xml
+
+userdocimages = \
+	$(top_srcdir)/doc/images/ags_export_window.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-input.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-resize_channels.png \
+	$(top_srcdir)/doc/images/ags_navigation.png \
+	$(top_srcdir)/doc/images/ags_synth.png \
+	$(top_srcdir)/doc/images/ags_audio_preferences.png \
+	$(top_srcdir)/doc/images/ags_ffplayer.png \
+	$(top_srcdir)/doc/images/ags_ladspa_browser.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-link_input.png \
+	$(top_srcdir)/doc/images/ags_matrix.png \
+	$(top_srcdir)/doc/images/ags_panel.png \
+	$(top_srcdir)/doc/images/ags-toolbar.png \
+	$(top_srcdir)/doc/images/ags_drum.png \
+	$(top_srcdir)/doc/images/ags_generic_preferences.png \
+	$(top_srcdir)/doc/images/ags_machine_properties-output.png \
+	$(top_srcdir)/doc/images/ags_mixer.png \
+	$(top_srcdir)/doc/images/ags_performance_preferences.png \
+	$(top_srcdir)/doc/images/ags_server_preferences.png
+
 
 # library
 libags_a_CFLAGS = $(GOBJECT_CFLAGS) $(LIBXML2_CFLAGS) 
@@ -586,8 +629,6 @@ libags_a_SOURCES =
 ags_CFLAGS = $(CFLAGS) $(UUID_CFLAGS) $(LIBASOUND2_CFLAGS) $(LIBAO_CFLAGS) $(LIBXML2_CFLAGS) $(OPENSSL_CFLAGS) $(SNDFILE_CFLAGS) $(LIBINSTPATCH_CFLAGS) $(GOBJECT_CFLAGS) $(GDKPIXBUF_CFLAGS) $(CAIRO_CFLAGS) $(GTK_CFLAGS) $(XMLRPC_CFLAGS) $(XMLRPC_UTIL_CFLAGS) $(XMLRPC_SERVER_ABYSS_CFLAGS) $(XMLRPC_SERVER_CGI_CFLAGS) $(XMLRPC_SERVER_CFLAGS) $(PTH_FLAGS)
 ags_LDFLAGS = -ldl $(LDFLAGS) $(UUID_LIBS) $(LIBASOUND2_LIBS) $(LIBAO_LIBS) $(LIBXML2_LIBS) $(OPENSSL_LIBS) $(SNDFILE_LIBS) $(LIBINSTPATCH_LIBS) $(GOBJECT_LIBS) $(GDKPIXBUF_LIBS) $(CAIRO_LIBS) $(GTK_LIBS) $(XMLRPC_LIBS) $(XMLRPC_UTIL_LIBS) $(XMLRPC_SERVER_ABYSS_LIBS) $(XMLRPC_SERVER_CGI_LIBS) $(XMLRPC_SERVER_LIBS) -lm -lrt -lX11 -pthread
 ags_LDADD = 
-appdatadir = $(datadir)/applications
-appdata_DATA = ags.desktop 
 ags_SOURCES = ./src/ags-lib/object/ags_connectable.c \
 	./src/ags-lib/object/ags_connectable.h \
 	src/ags/lib/ags_combo_box_text.c src/ags/lib/ags_list.c \
@@ -1145,6 +1186,9 @@ ags_SOURCES = ./src/ags-lib/object/ags_connectable.c \
 	src/ags/plugin/ags_ladspa_manager.h \
 	src/ags/plugin/ags_plugin_factory.c \
 	src/ags/plugin/ags_ladspa_manager.c src/ags/main.h
+midi2xml_CFLAGS = $(CFLAGS) $(LIBXML2_CFLAGS) $(GOBJECT_CFLAGS)
+midi2xml_LDFLAGS = -ldl $(LDFLAGS) $(LIBXML2_LIBS) $(GOBJECT_LIBS)
+midi2xml_SOURCES = src/midi2ags/main.c src/midi2ags/midi/ags_midi_parser.c src/midi2ags/midi/ags_midi_parser.h src/midi2ags/object/ags_marshal.c src/midi2ags/object/ags_marshal.h
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -1249,6 +1293,10 @@ ags$(EXEEXT): $(ags_OBJECTS) $(ags_DEPENDENCIES) $(EXTRA_ags_DEPENDENCIES)
 	@rm -f ags$(EXEEXT)
 	$(AM_V_CCLD)$(ags_LINK) $(ags_OBJECTS) $(ags_LDADD) $(LIBS)
 
+midi2xml$(EXEEXT): $(midi2xml_OBJECTS) $(midi2xml_DEPENDENCIES) $(EXTRA_midi2xml_DEPENDENCIES) 
+	@rm -f midi2xml$(EXEEXT)
+	$(AM_V_CCLD)$(midi2xml_LINK) $(midi2xml_OBJECTS) $(midi2xml_LDADD) $(LIBS)
+
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
 
@@ -1577,6 +1625,9 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ags-ags_window.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ags-ags_window_callbacks.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ags-main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/midi2xml-ags_marshal.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/midi2xml-ags_midi_parser.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/midi2xml-main.Po at am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -6099,6 +6150,48 @@ ags-ags_ladspa_manager.obj: src/ags/plugin/ags_ladspa_manager.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/ags/plugin/ags_ladspa_manager.c' object='ags-ags_ladspa_manager.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ags_CFLAGS) $(CFLAGS) -c -o ags-ags_ladspa_manager.obj `if test -f 'src/ags/plugin/ags_ladspa_manager.c'; then $(CYGPATH_W) 'src/ags/plugin/ags_ladspa_manager.c'; else $(CYGPATH_W) '$(srcdir)/src/ags/plugin/ags_ladspa_manager.c'; fi`
+
+midi2xml-main.o: src/midi2ags/main.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-main.o -MD -MP -MF $(DEPDIR)/midi2xml-main.Tpo -c -o midi2xml-main.o `test -f 'src/midi2ags/main.c' || echo '$(srcdir)/'`src/midi2ags/main.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-main.Tpo $(DEPDIR)/midi2xml-main.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/main.c' object='midi2xml-main.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-main.o `test -f 'src/midi2ags/main.c' || echo '$(srcdir)/'`src/midi2ags/main.c
+
+midi2xml-main.obj: src/midi2ags/main.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-main.obj -MD -MP -MF $(DEPDIR)/midi2xml-main.Tpo -c -o midi2xml-main.obj `if test -f 'src/midi2ags/main.c'; then $(CYGPATH_W) 'src/midi2ags/main.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/main.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-main.Tpo $(DEPDIR)/midi2xml-main.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/main.c' object='midi2xml-main.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-main.obj `if test -f 'src/midi2ags/main.c'; then $(CYGPATH_W) 'src/midi2ags/main.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/main.c'; fi`
+
+midi2xml-ags_midi_parser.o: src/midi2ags/midi/ags_midi_parser.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-ags_midi_parser.o -MD -MP -MF $(DEPDIR)/midi2xml-ags_midi_parser.Tpo -c -o midi2xml-ags_midi_parser.o `test -f 'src/midi2ags/midi/ags_midi_parser.c' || echo '$(srcdir)/'`src/midi2ags/midi/ags_midi_parser.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-ags_midi_parser.Tpo $(DEPDIR)/midi2xml-ags_midi_parser.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/midi/ags_midi_parser.c' object='midi2xml-ags_midi_parser.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-ags_midi_parser.o `test -f 'src/midi2ags/midi/ags_midi_parser.c' || echo '$(srcdir)/'`src/midi2ags/midi/ags_midi_parser.c
+
+midi2xml-ags_midi_parser.obj: src/midi2ags/midi/ags_midi_parser.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-ags_midi_parser.obj -MD -MP -MF $(DEPDIR)/midi2xml-ags_midi_parser.Tpo -c -o midi2xml-ags_midi_parser.obj `if test -f 'src/midi2ags/midi/ags_midi_parser.c'; then $(CYGPATH_W) 'src/midi2ags/midi/ags_midi_parser.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/midi/ags_midi_parser.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-ags_midi_parser.Tpo $(DEPDIR)/midi2xml-ags_midi_parser.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/midi/ags_midi_parser.c' object='midi2xml-ags_midi_parser.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-ags_midi_parser.obj `if test -f 'src/midi2ags/midi/ags_midi_parser.c'; then $(CYGPATH_W) 'src/midi2ags/midi/ags_midi_parser.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/midi/ags_midi_parser.c'; fi`
+
+midi2xml-ags_marshal.o: src/midi2ags/object/ags_marshal.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-ags_marshal.o -MD -MP -MF $(DEPDIR)/midi2xml-ags_marshal.Tpo -c -o midi2xml-ags_marshal.o `test -f 'src/midi2ags/object/ags_marshal.c' || echo '$(srcdir)/'`src/midi2ags/object/ags_marshal.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-ags_marshal.Tpo $(DEPDIR)/midi2xml-ags_marshal.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/object/ags_marshal.c' object='midi2xml-ags_marshal.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-ags_marshal.o `test -f 'src/midi2ags/object/ags_marshal.c' || echo '$(srcdir)/'`src/midi2ags/object/ags_marshal.c
+
+midi2xml-ags_marshal.obj: src/midi2ags/object/ags_marshal.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -MT midi2xml-ags_marshal.obj -MD -MP -MF $(DEPDIR)/midi2xml-ags_marshal.Tpo -c -o midi2xml-ags_marshal.obj `if test -f 'src/midi2ags/object/ags_marshal.c'; then $(CYGPATH_W) 'src/midi2ags/object/ags_marshal.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/object/ags_marshal.c'; fi`
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/midi2xml-ags_marshal.Tpo $(DEPDIR)/midi2xml-ags_marshal.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='src/midi2ags/object/ags_marshal.c' object='midi2xml-ags_marshal.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(midi2xml_CFLAGS) $(CFLAGS) -c -o midi2xml-ags_marshal.obj `if test -f 'src/midi2ags/object/ags_marshal.c'; then $(CYGPATH_W) 'src/midi2ags/object/ags_marshal.c'; else $(CYGPATH_W) '$(srcdir)/src/midi2ags/object/ags_marshal.c'; fi`
 install-man1: $(man1_MANS)
 	@$(NORMAL_INSTALL)
 	@list1='$(man1_MANS)'; \
@@ -6161,6 +6254,27 @@ uninstall-appdataDATA:
 	@list='$(appdata_DATA)'; test -n "$(appdatadir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
 	dir='$(DESTDIR)$(appdatadir)'; $(am__uninstall_files_from_dir)
+install-docDATA: $(doc_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(docdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(docdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \
+	done
+
+uninstall-docDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(doc_DATA)'; test -n "$(docdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(docdir)'; $(am__uninstall_files_from_dir)
 
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
@@ -6388,7 +6502,7 @@ check-am: all-am
 check: check-am
 all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS) $(DATA) config.h
 installdirs:
-	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(appdatadir)"; do \
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(appdatadir)" "$(DESTDIR)$(docdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
 	done
 install: install-am
@@ -6424,8 +6538,8 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-binPROGRAMS clean-generic clean-noinstLIBRARIES \
-	mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic clean-local \
+	clean-noinstLIBRARIES mostlyclean-am
 
 distclean: distclean-am
 	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -6438,15 +6552,14 @@ dvi: dvi-am
 
 dvi-am:
 
-html: html-am
-
 html-am:
 
 info: info-am
 
 info-am:
 
-install-data-am: install-appdataDATA install-data-local install-man
+install-data-am: install-appdataDATA install-data-local \
+	install-docDATA install-man
 
 install-dvi: install-dvi-am
 
@@ -6454,8 +6567,6 @@ install-dvi-am:
 
 install-exec-am: install-binPROGRAMS
 
-install-html: install-html-am
-
 install-html-am:
 
 install-info: install-info-am
@@ -6494,7 +6605,7 @@ ps: ps-am
 ps-am:
 
 uninstall-am: uninstall-appdataDATA uninstall-binPROGRAMS \
-	uninstall-man
+	uninstall-docDATA uninstall-man
 	@$(NORMAL_INSTALL)
 	$(MAKE) $(AM_MAKEFLAGS) uninstall-hook
 uninstall-man: uninstall-man1
@@ -6502,7 +6613,7 @@ uninstall-man: uninstall-man1
 .MAKE: all install-am install-strip uninstall-am
 
 .PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \
-	clean-binPROGRAMS clean-cscope clean-generic \
+	clean-binPROGRAMS clean-cscope clean-generic clean-local \
 	clean-noinstLIBRARIES cscope cscopelist-am ctags ctags-am dist \
 	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
 	dist-xz dist-zip distcheck distclean distclean-compile \
@@ -6510,28 +6621,44 @@ uninstall-man: uninstall-man1
 	distdir distuninstallcheck dvi dvi-am html html-am info \
 	info-am install install-am install-appdataDATA \
 	install-binPROGRAMS install-data install-data-am \
-	install-data-local install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-man1 install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
-	uninstall-am uninstall-appdataDATA uninstall-binPROGRAMS \
-	uninstall-hook uninstall-man uninstall-man1
+	install-data-local install-docDATA install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-man1 \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-appdataDATA \
+	uninstall-binPROGRAMS uninstall-docDATA uninstall-hook \
+	uninstall-man uninstall-man1
 
 
 ags.desktop: ags.desktop.in
 	$(AM_V_GEN)sed -e 's,\@datadir\@,$(datadir),g' < "$<" > $@
 
-install-data-local:
+html:
+	mkdir -p html/
+	xsltproc --output html/ --xinclude /usr/share/xml/docbook/stylesheet/docbook-xsl/htmlhelp/htmlhelp.xsl $(top_srcdir)/doc/usersBook.xml
+
+all: html
+
+install-data-local: install-html
 	mkdir -p $(DESTDIR)/$(datadir)/gsequencer/icons
 	mkdir -p $(DESTDIR)/$(datadir)/gsequencer/images
 	cp $(top_srcdir)/gsequencer.share/icons/ags.xpm $(DESTDIR)/$(datadir)/gsequencer/icons/ags.xpm
 	cp $(top_srcdir)/gsequencer.share/images/ags.png $(DESTDIR)/$(datadir)/gsequencer/images/ags.png
 
+install-html:
+	mkdir -p $(DESTDIR)/$(datadir)/doc/gsequencer/{images,html}/
+	cp $(userdocimages) $(DESTDIR)/$(datadir)/doc/gsequencer/images/
+	cp html/* $(DESTDIR)/$(datadir)/doc/gsequencer/html/
+
 uninstall-hook:
 	rm -rf $(DESTDIR)/$(datadir)/gsequencer
+	rm -rf $(DESTDIR)/$(datadir)/doc/gsequencer
+
+clean-local:
+	rm -rf html
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/configure b/configure
index 72c3b6e..07bd9e4 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ags 0.4.2-67.
+# Generated by GNU Autoconf 2.69 for ags 0.4.2-68.
 #
 # Report bugs to <jkraehemann at gmail.com>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ags'
 PACKAGE_TARNAME='ags'
-PACKAGE_VERSION='0.4.2-67'
-PACKAGE_STRING='ags 0.4.2-67'
+PACKAGE_VERSION='0.4.2-68'
+PACKAGE_STRING='ags 0.4.2-68'
 PACKAGE_BUGREPORT='jkraehemann at gmail.com'
 PACKAGE_URL=''
 
@@ -1317,7 +1317,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ags 0.4.2-67 to adapt to many kinds of systems.
+\`configure' configures ags 0.4.2-68 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1387,7 +1387,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ags 0.4.2-67:";;
+     short | recursive ) echo "Configuration of ags 0.4.2-68:";;
    esac
   cat <<\_ACEOF
 
@@ -1523,7 +1523,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ags configure 0.4.2-67
+ags configure 0.4.2-68
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2000,7 +2000,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ags $as_me 0.4.2-67, which was
+It was created by ags $as_me 0.4.2-68, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2866,7 +2866,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='ags'
- VERSION='0.4.2-67'
+ VERSION='0.4.2-68'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -7161,7 +7161,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ags $as_me 0.4.2-67, which was
+This file was extended by ags $as_me 0.4.2-68, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7227,7 +7227,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ags config.status 0.4.2-67
+ags config.status 0.4.2-68
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index b000043..e883c78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.69])
-AC_INIT([ags],[0.4.2-67],[jkraehemann at gmail.com])
+AC_INIT([ags],[0.4.2-68],[jkraehemann at gmail.com])
 AM_INIT_AUTOMAKE([foreign])
 AC_CONFIG_SRCDIR([config.h.in])
 AC_CONFIG_HEADERS([config.h])
diff --git a/doc/appa.xml b/doc/appa.xml
new file mode 100644
index 0000000..a3a3a34
--- /dev/null
+++ b/doc/appa.xml
@@ -0,0 +1,560 @@
+<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+<appendix id="fdl">
+  <title>GNU Free Documentation License</title>
+  <simpara>Version 1.3, 3 November 2008</simpara>
+  <simpara>
+    Copyright © 2000, 2001, 2002, 2007, 2008
+    <ulink url="http://www.fsf.org/">Free Software Foundation, Inc.</ulink>
+  </simpara>
+  <simpara>
+    Everyone is permitted to copy and distribute verbatim copies of this
+    license document, but changing it is not allowed.
+  </simpara>
+  <bridgehead id="section0" renderas="sect2">
+    0. PREAMBLE
+  </bridgehead>
+  <simpara>
+    The purpose of this License is to make a manual, textbook, or other
+    functional and useful document “free” in the sense of freedom:
+    to assure everyone the effective freedom to copy and redistribute it, with
+    or without modifying it, either commercially or
+    noncommercially. Secondarily, this License preserves for the author and
+    publisher a way to get credit for their work, while not being considered
+    responsible for modifications made by others.
+  </simpara>
+  <simpara>
+    This License is a kind of “copyleft”, which means that
+    derivative works of the document must themselves be free in the same
+    sense. It complements the GNU General Public License, which is a copyleft
+    license designed for free software.
+  </simpara>
+  <simpara>
+    We have designed this License in order to use it for manuals for free
+    software, because free software needs free documentation: a free program
+    should come with manuals providing the same freedoms that the software
+    does. But this License is not limited to software manuals; it can be used
+    for any textual work, regardless of subject matter or whether it is
+    published as a printed book. We recommend this License principally for
+    works whose purpose is instruction or reference.
+  </simpara>
+  <bridgehead id="section1" renderas="sect2">
+    1. APPLICABILITY AND DEFINITIONS
+  </bridgehead>
+  <simpara>
+    This License applies to any manual or other work, in any medium, that
+    contains a notice placed by the copyright holder saying it can be
+    distributed under the terms of this License. Such a notice grants a
+    world-wide, royalty-free license, unlimited in duration, to use that work
+    under the conditions stated herein. The “Document”, below,
+    refers to any such manual or work. Any member of the public is a licensee,
+    and is addressed as “you”. You accept the license if you copy,
+    modify or distribute the work in a way requiring permission under
+    copyright law.
+  </simpara>
+  <simpara>
+    A “Modified Version” of the Document means any work containing
+    the Document or a portion of it, either copied verbatim, or with
+    modifications and/or translated into another language.
+  </simpara>
+  <simpara>
+    A “Secondary Section” is a named appendix or a front-matter
+    section of the Document that deals exclusively with the relationship of
+    the publishers or authors of the Document to the Document&#x2019;s overall
+    subject (or to related matters) and contains nothing that could fall
+    directly within that overall subject. (Thus, if the Document is in part a
+    textbook of mathematics, a Secondary Section may not explain any
+    mathematics.) The relationship could be a matter of historical connection
+    with the subject or with related matters, or of legal, commercial,
+    philosophical, ethical or political position regarding them.
+  </simpara>
+  <simpara>
+    The “Invariant Sections” are certain Secondary Sections whose
+    titles are designated, as being those of Invariant Sections, in the notice
+    that says that the Document is released under this License. If a section
+    does not fit the above definition of Secondary then it is not allowed to
+    be designated as Invariant. The Document may contain zero Invariant
+    Sections. If the Document does not identify any Invariant Sections then
+    there are none.
+  </simpara>
+  <simpara>
+    The “Cover Texts” are certain short passages of text that are
+    listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says
+    that the Document is released under this License. A Front-Cover Text may
+    be at most 5 words, and a Back-Cover Text may be at most 25 words.
+  </simpara>
+  <simpara>
+    A “Transparent” copy of the Document means a machine-readable
+    copy, represented in a format whose specification is available to the
+    general public, that is suitable for revising the document
+    straightforwardly with generic text editors or (for images composed of
+    pixels) generic paint programs or (for drawings) some widely available
+    drawing editor, and that is suitable for input to text formatters or for
+    automatic translation to a variety of formats suitable for input to text
+    formatters. A copy made in an otherwise Transparent file format whose
+    markup, or absence of markup, has been arranged to thwart or discourage
+    subsequent modification by readers is not Transparent. An image format is
+    not Transparent if used for any substantial amount of text. A copy that is
+    not “Transparent” is called “Opaque”.
+  </simpara>
+  <simpara>
+    Examples of suitable formats for Transparent copies include plain ASCII
+    without markup, Texinfo input format, LaTeX input format, SGML or XML
+    using a publicly available DTD, and standard-conforming simple HTML,
+    PostScript or PDF designed for human modification. Examples of transparent
+    image formats include PNG, XCF and JPG. Opaque formats include proprietary
+    formats that can be read and edited only by proprietary word processors,
+    SGML or XML for which the DTD and/or processing tools are not generally
+    available, and the machine-generated HTML, PostScript or PDF produced by
+    some word processors for output purposes only.
+  </simpara>
+  <simpara>
+    The “Title Page” means, for a printed book, the title page
+    itself, plus such following pages as are needed to hold, legibly, the
+    material this License requires to appear in the title page. For works in
+    formats which do not have any title page as such, “Title Page”
+    means the text near the most prominent appearance of the work&#x2019;s
+    title, preceding the beginning of the body of the text.
+  </simpara>
+  <simpara>
+    The “publisher” means any person or entity that distributes
+    copies of the Document to the public.
+  </simpara>
+  <simpara>
+    A section “Entitled XYZ” means a named subunit of the Document
+    whose title either is precisely XYZ or contains XYZ in parentheses
+    following text that translates XYZ in another language. (Here XYZ stands
+    for a specific section name mentioned below, such as
+    “Acknowledgements”, “Dedications”,
+    “Endorsements”, or “History”.) To “Preserve
+    the Title” of such a section when you modify the Document means that
+    it remains a section “Entitled XYZ” according to this
+    definition.
+  </simpara>
+  <simpara>
+    The Document may include Warranty Disclaimers next to the notice which
+    states that this License applies to the Document. These Warranty
+    Disclaimers are considered to be included by reference in this License,
+    but only as regards disclaiming warranties: any other implication that
+    these Warranty Disclaimers may have is void and has no effect on the
+    meaning of this License.
+  </simpara>
+  <bridgehead id="section2" renderas="sect2">
+    2. VERBATIM COPYING
+  </bridgehead>
+  <simpara>
+    You may copy and distribute the Document in any medium, either
+    commercially or noncommercially, provided that this License, the copyright
+    notices, and the license notice saying this License applies to the
+    Document are reproduced in all copies, and that you add no other
+    conditions whatsoever to those of this License. You may not use technical
+    measures to obstruct or control the reading or further copying of the
+    copies you make or distribute. However, you may accept compensation in
+    exchange for copies. If you distribute a large enough number of copies you
+    must also follow the conditions in section 3.
+  </simpara>
+  <simpara>
+    You may also lend copies, under the same conditions stated above, and you
+    may publicly display copies.
+  </simpara>
+  <bridgehead id="section3" renderas="sect2">
+    3. COPYING IN QUANTITY
+  </bridgehead>
+  <simpara>
+    If you publish printed copies (or copies in media that commonly have
+    printed covers) of the Document, numbering more than 100, and the
+    Document&#x2019;s license notice requires Cover Texts, you must enclose
+    the copies in covers that carry, clearly and legibly, all these Cover
+    Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the
+    back cover. Both covers must also clearly and legibly identify you as the
+    publisher of these copies. The front cover must present the full title
+    with all words of the title equally prominent and visible. You may add
+    other material on the covers in addition. Copying with changes limited to
+    the covers, as long as they preserve the title of the Document and satisfy
+    these conditions, can be treated as verbatim copying in other respects.
+  </simpara>
+  <simpara>
+    If the required texts for either cover are too voluminous to fit legibly,
+    you should put the first ones listed (as many as fit reasonably) on the
+    actual cover, and continue the rest onto adjacent pages.
+  </simpara>
+  <simpara>
+    If you publish or distribute Opaque copies of the Document numbering more
+    than 100, you must either include a machine-readable Transparent copy
+    along with each Opaque copy, or state in or with each Opaque copy a
+    computer-network location from which the general network-using public has
+    access to download using public-standard network protocols a complete
+    Transparent copy of the Document, free of added material. If you use the
+    latter option, you must take reasonably prudent steps, when you begin
+    distribution of Opaque copies in quantity, to ensure that this Transparent
+    copy will remain thus accessible at the stated location until at least one
+    year after the last time you distribute an Opaque copy (directly or
+    through your agents or retailers) of that edition to the public.
+  </simpara>
+  <simpara>
+    It is requested, but not required, that you contact the authors of the
+    Document well before redistributing any large number of copies, to give
+    them a chance to provide you with an updated version of the Document.
+  </simpara>
+  <bridgehead id="section4" renderas="sect2">
+    4. MODIFICATIONS
+  </bridgehead>
+  <simpara>
+    You may copy and distribute a Modified Version of the Document under the
+    conditions of sections 2 and 3 above, provided that you release the
+    Modified Version under precisely this License, with the Modified Version
+    filling the role of the Document, thus licensing distribution and
+    modification of the Modified Version to whoever possesses a copy of it. In
+    addition, you must do these things in the Modified Version:
+  </simpara>
+  <orderedlist numeration="upperalpha">
+    <listitem>
+      <simpara>
+        Use in the Title Page (and on the covers, if any) a title distinct
+        from that of the Document, and from those of previous versions (which
+        should, if there were any, be listed in the History section of the
+        Document). You may use the same title as a previous version if the
+        original publisher of that version gives permission.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        List on the Title Page, as authors, one or more persons or entities
+        responsible for authorship of the modifications in the Modified
+        Version, together with at least five of the principal authors of the
+        Document (all of its principal authors, if it has fewer than five),
+        unless they release you from this requirement.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        State on the Title page the name of the publisher of the Modified
+        Version, as the publisher.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve all the copyright notices of the Document.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Add an appropriate copyright notice for your modifications adjacent to
+        the other copyright notices.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Include, immediately after the copyright notices, a license notice
+        giving the public permission to use the Modified Version under the
+        terms of this License, in the form shown in the Addendum below.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve in that license notice the full lists of Invariant Sections
+        and required Cover Texts given in the Document&#x2019;s license
+        notice.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Include an unaltered copy of this License.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve the section Entitled “History”, Preserve its
+        Title, and add to it an item stating at least the title, year, new
+        authors, and publisher of the Modified Version as given on the Title
+        Page. If there is no section Entitled “History” in the
+        Document, create one stating the title, year, authors, and publisher
+        of the Document as given on its Title Page, then add an item
+        describing the Modified Version as stated in the previous sentence.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve the network location, if any, given in the Document for
+        public access to a Transparent copy of the Document, and likewise the
+        network locations given in the Document for previous versions it was
+        based on.  These may be placed in the “History”
+        section. You may omit a network location for a work that was published
+        at least four years before the Document itself, or if the original
+        publisher of the version it refers to gives permission.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        For any section Entitled “Acknowledgements” or
+        “Dedications”, Preserve the Title of the section, and
+        preserve in the section all the substance and tone of each of the
+        contributor acknowledgements and/or dedications given therein.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve all the Invariant Sections of the Document, unaltered in
+        their text and in their titles. Section numbers or the equivalent are
+        not considered part of the section titles.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Delete any section Entitled “Endorsements”. Such a section
+        may not be included in the Modified Version.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Do not retitle any existing section to be Entitled
+        “Endorsements” or to conflict in title with any Invariant
+        Section.
+      </simpara>
+    </listitem>
+    <listitem>
+      <simpara>
+        Preserve any Warranty Disclaimers.
+      </simpara>
+    </listitem>
+  </orderedlist>
+  <simpara>
+    If the Modified Version includes new front-matter sections or appendices
+    that qualify as Secondary Sections and contain no material copied from the
+    Document, you may at your option designate some or all of these sections
+    as invariant. To do this, add their titles to the list of Invariant
+    Sections in the Modified Version&#x2019;s license notice. These titles
+    must be distinct from any other section titles.
+  </simpara>
+  <simpara>
+    You may add a section Entitled “Endorsements”, provided it
+    contains nothing but endorsements of your Modified Version by various
+    parties — for example, statements of peer review or that the text
+    has been approved by an organization as the authoritative definition of a
+    standard.
+  </simpara>
+  <simpara>
+    You may add a passage of up to five words as a Front-Cover Text, and a
+    passage of up to 25 words as a Back-Cover Text, to the end of the list of
+    Cover Texts in the Modified Version. Only one passage of Front-Cover Text
+    and one of Back-Cover Text may be added by (or through arrangements made
+    by) any one entity. If the Document already includes a cover text for the
+    same cover, previously added by you or by arrangement made by the same
+    entity you are acting on behalf of, you may not add another; but you may
+    replace the old one, on explicit permission from the previous publisher
+    that added the old one.
+  </simpara>
+  <simpara>
+    The author(s) and publisher(s) of the Document do not by this License give
+    permission to use their names for publicity for or to assert or imply
+    endorsement of any Modified Version.
+  </simpara>
+  <bridgehead id="section5" renderas="sect2">
+    5. COMBINING DOCUMENTS
+  </bridgehead>
+  <simpara>
+    You may combine the Document with other documents released under this
+    License, under the terms defined in section 4 above for modified versions,
+    provided that you include in the combination all of the Invariant Sections
+    of all of the original documents, unmodified, and list them all as
+    Invariant Sections of your combined work in its license notice, and that
+    you preserve all their Warranty Disclaimers.
+  </simpara>
+  <simpara>
+    The combined work need only contain one copy of this License, and multiple
+    identical Invariant Sections may be replaced with a single copy. If there
+    are multiple Invariant Sections with the same name but different contents,
+    make the title of each such section unique by adding at the end of it, in
+    parentheses, the name of the original author or publisher of that section
+    if known, or else a unique number. Make the same adjustment to the section
+    titles in the list of Invariant Sections in the license notice of the
+    combined work.
+  </simpara>
+  <simpara>
+    In the combination, you must combine any sections Entitled
+    “History” in the various original documents, forming one
+    section Entitled “History”; likewise combine any sections
+    Entitled “Acknowledgements”, and any sections Entitled
+    “Dedications”. You must delete all sections Entitled
+    “Endorsements”.
+  </simpara>
+  <bridgehead id="section6" renderas="sect2">
+    6. COLLECTIONS OF DOCUMENTS
+  </bridgehead>
+  <simpara>
+    You may make a collection consisting of the Document and other documents
+    released under this License, and replace the individual copies of this
+    License in the various documents with a single copy that is included in
+    the collection, provided that you follow the rules of this License for
+    verbatim copying of each of the documents in all other respects.
+  </simpara>
+  <simpara>
+    You may extract a single document from such a collection, and distribute
+    it individually under this License, provided you insert a copy of this
+    License into the extracted document, and follow this License in all other
+    respects regarding verbatim copying of that document.
+  </simpara>
+  <bridgehead id="section7" renderas="sect2">
+    7. AGGREGATION WITH INDEPENDENT WORKS
+  </bridgehead>
+  <simpara>
+    A compilation of the Document or its derivatives with other separate and
+    independent documents or works, in or on a volume of a storage or
+    distribution medium, is called an “aggregate” if the copyright
+    resulting from the compilation is not used to limit the legal rights of
+    the compilation&#x2019;s users beyond what the individual works
+    permit. When the Document is included in an aggregate, this License does
+    not apply to the other works in the aggregate which are not themselves
+    derivative works of the Document.
+  </simpara>
+  <simpara>
+    If the Cover Text requirement of section 3 is applicable to these copies
+    of the Document, then if the Document is less than one half of the entire
+    aggregate, the Document&#x2019;s Cover Texts may be placed on covers that
+    bracket the Document within the aggregate, or the electronic equivalent of
+    covers if the Document is in electronic form. Otherwise they must appear
+    on printed covers that bracket the whole aggregate.
+  </simpara>
+  <bridgehead id="section8" renderas="sect2">
+    8. TRANSLATION
+  </bridgehead>
+  <simpara>
+    Translation is considered a kind of modification, so you may distribute
+    translations of the Document under the terms of section 4. Replacing
+    Invariant Sections with translations requires special permission from
+    their copyright holders, but you may include translations of some or all
+    Invariant Sections in addition to the original versions of these Invariant
+    Sections. You may include a translation of this License, and all the
+    license notices in the Document, and any Warranty Disclaimers, provided
+    that you also include the original English version of this License and the
+    original versions of those notices and disclaimers. In case of a
+    disagreement between the translation and the original version of this
+    License or a notice or disclaimer, the original version will prevail.
+  </simpara>
+  <simpara>
+    If a section in the Document is Entitled “Acknowledgements”,
+    “Dedications”, or “History”, the requirement
+    (section 4) to Preserve its Title (section 1) will typically require
+    changing the actual title.
+  </simpara>
+  <bridgehead id="section9" renderas="sect2">
+    9. TERMINATION
+  </bridgehead>
+  <simpara>
+    You may not copy, modify, sublicense, or distribute the Document except as
+    expressly provided under this License. Any attempt otherwise to copy,
+    modify, sublicense, or distribute it is void, and will automatically
+    terminate your rights under this License.
+  </simpara>
+  <simpara>
+    However, if you cease all violation of this License, then your license
+    from a particular copyright holder is reinstated (a) provisionally, unless
+    and until the copyright holder explicitly and finally terminates your
+    license, and (b) permanently, if the copyright holder fails to notify you
+    of the violation by some reasonable means prior to 60 days after the
+    cessation.
+  </simpara>
+  <simpara>
+    Moreover, your license from a particular copyright holder is reinstated
+    permanently if the copyright holder notifies you of the violation by some
+    reasonable means, this is the first time you have received notice of
+    violation of this License (for any work) from that copyright holder, and
+    you cure the violation prior to 30 days after your receipt of the notice.
+  </simpara>
+  <simpara>
+    Termination of your rights under this section does not terminate the
+    licenses of parties who have received copies or rights from you under this
+    License. If your rights have been terminated and not permanently
+    reinstated, receipt of a copy of some or all of the same material does not
+    give you any rights to use it.
+  </simpara>
+  <bridgehead id="section10" renderas="sect2">
+    10. FUTURE REVISIONS OF THIS LICENSE
+  </bridgehead>
+  <simpara>
+    The Free Software Foundation may publish new, revised versions of the GNU
+    Free Documentation License from time to time. Such new versions will be
+    similar in spirit to the present version, but may differ in detail to
+    address new problems or concerns. See
+    <ulink url="http://www.gnu.org/copyleft/">Copyleft</ulink>.
+  </simpara>
+  <simpara>
+    Each version of the License is given a distinguishing version number. If
+    the Document specifies that a particular numbered version of this License
+    “or any later version” applies to it, you have the option of
+    following the terms and conditions either of that specified version or of
+    any later version that has been published (not as a draft) by the Free
+    Software Foundation. If the Document does not specify a version number of
+    this License, you may choose any version ever published (not as a draft)
+    by the Free Software Foundation. If the Document specifies that a proxy
+    can decide which future versions of this License can be used, that
+    proxy&#x2019;s public statement of acceptance of a version permanently
+    authorizes you to choose that version for the Document.
+  </simpara>
+  <bridgehead id="section11" renderas="sect2">
+    11. RELICENSING
+  </bridgehead>
+  <simpara>
+    “Massive Multiauthor Collaboration Site” (or “MMC
+    Site”) means any World Wide Web server that publishes copyrightable
+    works and also provides prominent facilities for anybody to edit those
+    works. A public wiki that anybody can edit is an example of such a
+    server. A “Massive Multiauthor Collaboration” (or
+    “MMC”) contained in the site means any set of copyrightable
+    works thus published on the MMC site.
+  </simpara>
+  <simpara>
+    “CC-BY-SA” means the Creative Commons Attribution-Share Alike
+    3.0 license published by Creative Commons Corporation, a not-for-profit
+    corporation with a principal place of business in San Francisco,
+    California, as well as future copyleft versions of that license published
+    by that same organization.
+  </simpara>
+  <simpara>
+    “Incorporate” means to publish or republish a Document, in
+    whole or in part, as part of another Document.
+  </simpara>
+  <simpara>
+    An MMC is “eligible for relicensing” if it is licensed under
+    this License, and if all works that were first published under this
+    License somewhere other than this MMC, and subsequently incorporated in
+    whole or in part into the MMC, (1) had no cover texts or invariant
+    sections, and (2) were thus incorporated prior to November 1, 2008.
+  </simpara>
+  <simpara>
+    The operator of an MMC Site may republish an MMC contained in the site
+    under CC-BY-SA on the same site at any time before August 1, 2009,
+    provided the MMC is eligible for relicensing.
+  </simpara>
+  <bridgehead id="addendum" renderas="sect2">
+    ADDENDUM: How to use this License for your documents
+  </bridgehead>
+  <simpara>
+    To use this License in a document you have written, include a copy of the
+    License in the document and put the following copyright and license
+    notices just after the title page:
+  </simpara>
+  <screen>Copyright © 2013 Joël Krähemann
+
+Permission is granted to copy, distribute and/or modify this document under the
+terms of the GNU Free Documentation License, Version 1.3 or any later version
+published by the Free Software Foundation; with no Invariant Sections, no
+Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in
+the section entitled “GNU Free Documentation License”.</screen>
+  <simpara>
+    If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+    replace the “with… Texts.” line with this:
+  </simpara>
+  <screen>with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts
+being LIST, and with the Back-Cover Texts being LIST.</screen>
+  <simpara>
+    If you have Invariant Sections without Cover Texts, or some other
+    combination of the three, merge those two alternatives to suit the
+    situation.
+  </simpara>
+  <simpara>
+    If your document contains nontrivial examples of program code, we
+    recommend releasing these examples in parallel under your choice of free
+    software license, such as the GNU General Public License, to permit their
+    use in free software.
+  </simpara>
+</appendix>
diff --git a/doc/images/ags-toolbar.png b/doc/images/ags-toolbar.png
new file mode 100644
index 0000000..5b922b2
Binary files /dev/null and b/doc/images/ags-toolbar.png differ
diff --git a/doc/images/ags_audio_preferences.png b/doc/images/ags_audio_preferences.png
new file mode 100644
index 0000000..138f0c0
Binary files /dev/null and b/doc/images/ags_audio_preferences.png differ
diff --git a/doc/images/ags_drum.png b/doc/images/ags_drum.png
new file mode 100644
index 0000000..a08a1c0
Binary files /dev/null and b/doc/images/ags_drum.png differ
diff --git a/doc/images/ags_export_window.png b/doc/images/ags_export_window.png
new file mode 100644
index 0000000..182792e
Binary files /dev/null and b/doc/images/ags_export_window.png differ
diff --git a/doc/images/ags_ffplayer.png b/doc/images/ags_ffplayer.png
new file mode 100644
index 0000000..bcb7bf3
Binary files /dev/null and b/doc/images/ags_ffplayer.png differ
diff --git a/doc/images/ags_generic_preferences.png b/doc/images/ags_generic_preferences.png
new file mode 100644
index 0000000..c513d1c
Binary files /dev/null and b/doc/images/ags_generic_preferences.png differ
diff --git a/doc/images/ags_ladspa_browser.png b/doc/images/ags_ladspa_browser.png
new file mode 100644
index 0000000..e8c9784
Binary files /dev/null and b/doc/images/ags_ladspa_browser.png differ
diff --git a/doc/images/ags_machine_properties-input.png b/doc/images/ags_machine_properties-input.png
new file mode 100644
index 0000000..e301172
Binary files /dev/null and b/doc/images/ags_machine_properties-input.png differ
diff --git a/doc/images/ags_machine_properties-link_input.png b/doc/images/ags_machine_properties-link_input.png
new file mode 100644
index 0000000..b4e31af
Binary files /dev/null and b/doc/images/ags_machine_properties-link_input.png differ
diff --git a/doc/images/ags_machine_properties-output.png b/doc/images/ags_machine_properties-output.png
new file mode 100644
index 0000000..6b57eb7
Binary files /dev/null and b/doc/images/ags_machine_properties-output.png differ
diff --git a/doc/images/ags_machine_properties-resize_channels.png b/doc/images/ags_machine_properties-resize_channels.png
new file mode 100644
index 0000000..851c48b
Binary files /dev/null and b/doc/images/ags_machine_properties-resize_channels.png differ
diff --git a/doc/images/ags_matrix.png b/doc/images/ags_matrix.png
new file mode 100644
index 0000000..436cce1
Binary files /dev/null and b/doc/images/ags_matrix.png differ
diff --git a/doc/images/ags_mixer.png b/doc/images/ags_mixer.png
new file mode 100644
index 0000000..187185d
Binary files /dev/null and b/doc/images/ags_mixer.png differ
diff --git a/doc/images/ags_navigation.png b/doc/images/ags_navigation.png
new file mode 100644
index 0000000..65ea10c
Binary files /dev/null and b/doc/images/ags_navigation.png differ
diff --git a/doc/images/ags_panel.png b/doc/images/ags_panel.png
new file mode 100644
index 0000000..a2b0830
Binary files /dev/null and b/doc/images/ags_panel.png differ
diff --git a/doc/images/ags_performance_preferences.png b/doc/images/ags_performance_preferences.png
new file mode 100644
index 0000000..15ef9ea
Binary files /dev/null and b/doc/images/ags_performance_preferences.png differ
diff --git a/doc/images/ags_server_preferences.png b/doc/images/ags_server_preferences.png
new file mode 100644
index 0000000..cd64304
Binary files /dev/null and b/doc/images/ags_server_preferences.png differ
diff --git a/doc/images/ags_synth.png b/doc/images/ags_synth.png
new file mode 100644
index 0000000..752fc16
Binary files /dev/null and b/doc/images/ags_synth.png differ
diff --git a/doc/usersBook.xml b/doc/usersBook.xml
new file mode 100644
index 0000000..231587e
--- /dev/null
+++ b/doc/usersBook.xml
@@ -0,0 +1,43 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY jkraehemann "Joël Krähemann">
+<!ENTITY bookpath ".">
+]>
+<book xmlns="http://docbook.org/ns/docbook"
+      xmlns:xi="http://www.w3.org/2001/XInclude" version="5.0">
+  <title>Advanced Gtk+ Sequencer</title>
+  <subtitle>User's Handbook</subtitle>
+
+  <info>
+      <legalnotice>
+	<para>
+	  Copyright (C)  &jkraehemann;.
+	  Permission is granted to copy, distribute and/or modify this document
+	  under the terms of the GNU Free Documentation License, Version 1.3
+	  or any later version published by the Free Software Foundation;
+	  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+	  A copy of the license is included in the section entitled "GNU
+	  Free Documentation License".
+	</para>
+      </legalnotice>
+      <author>
+	<personname>
+	  <firstname>Joël</firstname>
+	  <surname>Krähemann</surname>
+	</personname>
+      </author>
+  </info>
+
+  <dedication>
+    <para>This book is dedicated to my father †Hans-Jörg Krähemann.</para>
+  </dedication>
+
+  <xi:include href="&bookpath;/usersBook/preface.xml"/>
+  <xi:include href="&bookpath;/usersBook/chap1.xml"/> <!--menubar -->
+  <xi:include href="&bookpath;/usersBook/chap2.xml"/> <!-- machines/engines -->
+  <xi:include href="&bookpath;/usersBook/chap3.xml"/> <!-- editor -->
+  <xi:include href="&bookpath;/usersBook/chap4.xml"/> <!--navigation -->
+  <xi:include href="&bookpath;/appa.xml"/>
+  <xi:include href="&bookpath;/usersBook/appb.xml"/>
+
+</book>
diff --git a/doc/usersBook/appb.xml b/doc/usersBook/appb.xml
new file mode 100644
index 0000000..d6bdac7
--- /dev/null
+++ b/doc/usersBook/appb.xml
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding="utf-8"?>
+<appendix>
+  <title>Resources</title>
+  <para>
+    <!-- TODO:JK: write some content -->
+  </para>
+</appendix>
diff --git a/doc/usersBook/chap1.xml b/doc/usersBook/chap1.xml
new file mode 100644
index 0000000..580dd14
--- /dev/null
+++ b/doc/usersBook/chap1.xml
@@ -0,0 +1,168 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY ags "Advanced Gtk+ Sequencer">
+]>
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0">
+  <title>The menubar</title>
+  <para>
+    Within the mainbar you may do basic tasks like open/close files or show this help. In this section we cover
+    briefly the the different entries.
+  </para>
+
+  <sect1>
+    <title>File</title>
+    <para>
+      The file menu lets you do maintenance related to files or quit application.
+    </para>
+
+    <itemizedlist mark="bullet">
+      <listitem>
+	<para>
+	  Open - open an &ags; XML file.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Save - save your current work.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Save as - save your current work as a different filename.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Export - export to PCM audio file.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Quit - leave &ags;.
+	</para>
+      </listitem>
+    </itemizedlist>
+
+    <sect2>
+      <title>Export to PCM audio file</title>
+      <imagedata fileref="../images/ags_export_window.png" />
+      <para>
+	This shows you the export dialog. You may select filename to export to and duration of the exported track. BPM adjustment
+	is take from the navigation. Basically &ags; exports what you hear of the speakers.
+      </para>
+      <para>
+	With the export toggle button you can start exporting to PCM audio file or stop it at an arbitrary time.
+      </para>
+    </sect2>
+  </sect1>
+
+  <sect1>
+    <title>Edit</title>
+    <para>
+      The edit menu lets you add/remove audio machines or open preferences dialog.
+    </para>
+
+    <itemizedlist mark="bullet">
+      <listitem>
+	<para>
+	  Add - select of different machines
+	</para>
+
+	<itemizedlist mark="bullet">
+	  <listitem>
+	    <para>
+	      Panel - acts as your default sink.
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>
+	      Mixer - enables you to bundle your different output engines.
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>
+	      Drum - is used to do pattern editing using PCM audio files. 
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>
+	      Matrix - is used to pattern editing, intended to be linked against Synth.
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>
+	      Synth - is a software synthesizer.
+	    </para>
+	  </listitem>
+	  <listitem>
+	    <para>
+	      FFPlayer - may be used to open Soundfont2 audio file container format.
+	    </para>
+	  </listitem>
+	</itemizedlist>
+	
+      </listitem>
+      <listitem>
+	<para>
+	  Remove - the focused machine.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Preferences - open preferences dialog.
+	</para>
+      </listitem>
+    </itemizedlist>
+
+    <sect2>
+      <title>Preferences dialog</title>
+      <para>
+	Within preferences dialog you may choose between different topics. For each one one tab.
+      </para>
+
+      <sect3>
+	<title>Generic</title>
+	<imagedata fileref="../images/ags_generic_preferences.png" />
+	<para>
+	  The autosave thread option enables auto-saving to $HOME/.gsequencer directory.
+	</para>
+      </sect3>
+
+      <sect3>
+	<title>Audio</title>
+	<imagedata fileref="../images/ags_audio_preferences.png" />
+	<para>
+	  Sound card is your physical devices to do playback.
+	</para>
+	<para>
+	  Audio channels specifies the audio channels to allocate for output device.
+	</para>
+	<para>
+	  Samplerate affects the entire project. Your audio files have to be at very same rate further
+	  your device has to support the given rate.
+	</para>
+	<para>
+	  Buffer size is used for all audio buffers. Your soundcard has to support the passed buffer size.
+	</para>
+      </sect3>
+
+      <sect3>
+	<title>Performance</title>
+	<imagedata fileref="../images/ags_performance_preferences.png" />
+	<para>
+	  Auto-sense on stream is required for certain LADSPA plugins but may cause additional performance losses.
+	</para>
+      </sect3>
+
+      <sect3>
+	<title>Server</title>
+	<imagedata fileref="../images/ags_server_preferences.png" />
+	<para>
+	  Ignored for now.
+	</para>
+      </sect3>
+
+    </sect2>
+  </sect1>
+
+</chapter>
diff --git a/doc/usersBook/chap2.xml b/doc/usersBook/chap2.xml
new file mode 100644
index 0000000..2ec0df5
--- /dev/null
+++ b/doc/usersBook/chap2.xml
@@ -0,0 +1,138 @@
+<?xml version='1.0' encoding="utf-8"?>
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0">
+  <title>Engines</title>
+  <para>
+    You can add engines by activating the appropriate menu item within
+    the "add" submenu of the "edit" menu item. You may change the properties
+    of an engine by opening the properties dialog from the context menu.
+    From the context menu you may perform some other tasks, too.
+  </para>
+  <itemizedlist mark="bullet">
+    <listitem>
+      <para>
+	To move up or down an engine open context menu and activate "up"
+	respectively "down" entry.
+      </para>
+    </listitem>
+    <listitem>
+      <para>
+	To show or hide an engine open context menu and activate "show"
+	respectively "hide" entry. Note the engines won't be hidden entirely
+	they are just collapsed.
+      </para>
+    </listitem>
+    <listitem>
+      <para>
+	To rename an engine open context menu and activate "rename" entry.
+      </para>
+    </listitem>
+    <listitem>
+      <para>
+	To remove an engine open context menu and activate "destroy" entry.
+      </para>
+    </listitem>
+    <listitem>
+      <para>
+	To open properties dialog open context menu and activate "properties"
+	entry.
+      </para>
+    </listitem>
+  </itemizedlist>
+
+  <sect1>
+    <title>Machine Properties</title>
+    <para>
+      Within properties dialog you can link lines or add effects and adjust audio-channels/pads.
+    </para>
+    
+    <sect2>
+      <imagedata fileref="../images/ags_machine_properties-output.png" />
+      <para>
+	The output tab lets you mainly perform linking and adding effects.
+      </para>
+    </sect2>
+
+    <sect2>
+      <imagedata fileref="../images/ags_machine_properties-input.png" />
+      <para>
+	The input tab does the same as output tab in view of input lines.
+      </para>
+    </sect2>
+
+    <sect2>
+      <imagedata fileref="../images/ags_machine_properties-link_input.png" />
+      <para>
+	Do linking in batch mode.
+      </para>
+    </sect2>
+
+    <sect2>
+      <imagedata fileref="../images/ags_machine_properties-resize_channels.png" />
+      <para>
+	Adjust audio channels or input/output pads.
+      </para>
+    </sect2>
+
+    <sect2>
+      <imagedata fileref="../images/ags_ladspa_browser.png" />
+      <para>
+	The LADSPA browser gives you choice of available LADSPA plugin. It lets you modify
+	the controls to be used.
+      </para>
+    </sect2>
+    
+  </sect1>
+
+  <sect1>
+    <title>Panel</title>
+    <imagedata fileref="../images/ags_panel.png" />
+    <para>
+      The panel is used to output to your soundcard.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Mixer</title>
+    <imagedata fileref="../images/ags_mixer.png" />
+    <para>
+      Bundle audio lines with the mixer and perform toplevel stream manipulation.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Drum</title>
+    <imagedata fileref="../images/ags_drum.png" />
+    <para>
+      Produce an audio stream by defining a pattern. The drum supports opening
+      audio files and associate to its input.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Matrix</title>
+    <imagedata fileref="../images/ags_matrix.png" />
+    <para>
+      Produce an audio stream by defining a pattern. The matrix itselves doesn't
+      have any audio signals on its own input you may rather link it to a synth
+      engine.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Synth</title>
+    <imagedata fileref="../images/ags_synth.png" />
+    <para>
+      Produce audio data using its oscillators. The count of oscillators depends on number of
+      input lines.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>FFPlayer</title>
+    <imagedata fileref="../images/ags_ffplayer.png" />
+    <para>
+      Produce audio data by opening Soundfont2 audio file container format.
+    </para>
+  </sect1>
+
+</chapter>
diff --git a/doc/usersBook/chap3.xml b/doc/usersBook/chap3.xml
new file mode 100644
index 0000000..9a6c2ac
--- /dev/null
+++ b/doc/usersBook/chap3.xml
@@ -0,0 +1,104 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY indexMenuIcon "/usr/share/icons/Adwaita/32x32/actions/system-run.png">
+<!ENTITY cursorIcon "/usr/share/icons/Adwaita/32x32/actions/go-jump.png">
+<!ENTITY notesIcon "/usr/share/icons/Adwaita/32x32/mimetypes/audio-x-generic.png">
+<!ENTITY deleteIcon "/usr/share/icons/Adwaita/32x32/actions/edit-clear-all.png">
+<!ENTITY selectIcon "/usr/share/icons/Adwaita/32x32/actions/edit-select-all.png">
+<!ENTITY copyIcon "/usr/share/icons/Adwaita/32x32/actions/edit-copy.png">
+<!ENTITY cutIcon "/usr/share/icons/Adwaita/32x32/actions/edit-cut.png">
+<!ENTITY pasteIcon "/usr/share/icons/Adwaita/32x32/actions/edit-paste.png">
+]>
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0">
+  <title>Editor</title>
+  <para>
+    The editor features a piano roll. After linking an editor index with an enginge
+    You may perform tasks like adding notes or copy, cut and paste them. You may
+    change view segmentation, too.
+  </para>
+
+  <sect1>
+    <title>Linking</title>
+    <para>
+      Before you might perform any task with the editor you have to link engines
+      by adding an index. Then you should link it with an engine. That can all be
+      done by using the menu button <imagedata fileref="&indexMenuIcon;" /> of the
+      index list.
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Toolbar</title>
+    <imagedata fileref="../images/ags-toolbar.png" />
+    <para>
+      In the table below are the various buttons explained you may use for editing.
+    </para>
+    <table>
+      <title>AGS editor toolbar controls table.</title>
+      <tgroup cols="3" align="left" colsep='1' rowsep='1'>
+	<thead>
+	  <row>
+	    <entry>icon</entry>
+	    <entry>action</entry>
+	    <entry>description</entry>
+	  </row>
+	</thead>
+	<tbody>
+	  <row>
+	    <entry><imagedata fileref="&cursorIcon;" /></entry>
+	    <entry>cursor</entry>
+	    <entry>
+	      You may want to set the cursor to paste notes at the position where it
+	      is located.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="¬esIcon;" /></entry>
+	    <entry>notes</entry>
+	    <entry>
+	      Add notes by clicking within the piano roll and move to till them having
+	      the wished duration.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&deleteIcon;" /></entry>
+	    <entry>delete</entry>
+	    <entry>
+	      Delete notes by clicking on the note you don't want anymore.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&selectIcon;" /></entry>
+	    <entry>select</entry>
+	    <entry>
+	      Select notes to copy or cut them.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="©Icon;" /></entry>
+	    <entry>copy</entry>
+	    <entry>
+	      Copy notes to the clipboard.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&cutIcon;" /></entry>
+	    <entry>cut</entry>
+	    <entry>
+	      Cut notes to the clipboard.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&pasteIcon;" /></entry>
+	    <entry>paste</entry>
+	    <entry>
+	      Paste the previously copied or cutted notes at the cursor position or
+	      just insert them where they are/were located. 
+	    </entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </sect1>
+
+</chapter>
diff --git a/doc/usersBook/chap4.xml b/doc/usersBook/chap4.xml
new file mode 100644
index 0000000..34dc5b4
--- /dev/null
+++ b/doc/usersBook/chap4.xml
@@ -0,0 +1,86 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY backwardIcon "/usr/share/icons/Adwaita/32x32/actions/media-skip-backward.png">
+<!ENTITY previousIcon "/usr/share/icons/Adwaita/32x32/actions/media-seek-backward.png">
+<!ENTITY playIcon "/usr/share/icons/Adwaita/32x32/actions/media-playback-start.png">
+<!ENTITY stopIcon "/usr/share/icons/Adwaita/32x32/actions/media-playback-stop.png">
+<!ENTITY nextIcon "/usr/share/icons/Adwaita/32x32/actions/media-seek-forward.png">
+<!ENTITY forwardIcon "/usr/share/icons/Adwaita/32x32/actions/media-skip-forward.png">
+]>
+<chapter xmlns="http://docbook.org/ns/docbook" version="5.0">
+  <title>The navigation</title>
+  <imagedata fileref="../images/ags_navigation.png" />
+  <para>
+    With the navigation you have overall control of your song. Settings you perform
+    here may influence the behaviour of AGS.
+  </para>
+
+  <sect1>
+    <title>BPM</title>
+    <para>
+      The beats per minute (BPM for short) indicates the velocity of a song being
+      played. To adjust the BPM of the project in-/decrement the spinner labeled
+      with bpm. To edit patterns or notes at a more granular rate select the wished
+      tact within the appropriate engine or editor.
+    </para>
+    <para>
+      To calculate timings you divide 1 minute with the entered BPM and divide it
+      with basic. For example you have a BPM rate of 120 and a 4/4 tact you would
+      calculate the timing as follow:
+    </para>
+    <equation>
+      <mathphrase>t = 1 / 120 * (1 / 4)</mathphrase>
+    </equation>
+  </sect1>
+
+  <sect1>
+    <title>Playback controls</title>
+    <para>
+      With these controls you can play/stop a song or seek to the wished position.
+    </para>
+    <table>
+      <title>AGS playback controls table</title>
+      <tgroup cols="3" align="left" colsep='1' rowsep='1'>
+	<thead>
+	  <row>
+	    <entry>icon</entry>
+	    <entry>action</entry>
+	    <entry>description</entry>
+	  </row>
+	</thead>
+	<tbody>
+	  <row>
+	    <entry><imagedata fileref="&backwardIcon;" /></entry>
+	    <entry>backward</entry>
+	    <entry>Seeking back until it's pressed again.</entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&previousIcon;" /></entry>
+	    <entry>previous</entry>
+	    <entry>Seeking back until it's not pressed anymore.</entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&playIcon;" /></entry>
+	    <entry>play</entry>
+	    <entry>Starts the engines and the piano roll.</entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&stopIcon;" /></entry>
+	    <entry>stop</entry>
+	    <entry>Stops the engines and the piano roll.</entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&nextIcon;" /></entry>
+	    <entry>next</entry>
+	    <entry>Seeking forward until it's not pressed anymore.</entry>
+	  </row>
+	  <row>
+	    <entry><imagedata fileref="&forwardIcon;" /></entry>
+	    <entry>forward</entry>
+	    <entry>Seeking forward until it's pressed again.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+  </sect1>
+</chapter>
diff --git a/doc/usersBook/preface.xml b/doc/usersBook/preface.xml
new file mode 100644
index 0000000..1fa6716
--- /dev/null
+++ b/doc/usersBook/preface.xml
@@ -0,0 +1,34 @@
+<?xml version='1.0' encoding="utf-8"?>
+<!DOCTYPE book [
+<!ENTITY win98 "Microsoft Windows 98">
+<!ENTITY java2 "Sun Microsystem's Java 1.2">
+<!ENTITY n160 "Compaq Evo n160">
+<!ENTITY stallman "Richard Stallman">
+<!ENTITY ags "Advanced Gtk+ Sequencer">
+]>
+<preface>
+  <title>Foreword</title>
+  <para>
+    When I started to use GNU/Linux in 2001 I missed only one thing. A sequencer with a
+    nice GUI. There was already rosegarden available. But who didn't get stuck of midi
+    setup, yet? The time before I was using free software and became an affiliate to its
+    community I was using &win98; on my father's desktop computer and did my first steps
+    in &java2;.
+  </para>
+  <para>
+    My very first own Notebook was a &n160; and it's preinstalled &win98; had to vanish
+    because I became a fellow of &stallman;. Soon, I begun to code and older I became my
+    demands to ags increased. I developed the concept of the underlying audio library
+    myself as not graduated college student.
+  </para>
+  <para>
+    October 2005, I decided to reimplement &ags; from scratch in order to get rid of
+    inherited burden. And it was one big development process until I was almost satisfied
+    with it's design. There was a time in 2007 where I even wanted to replace GObject and
+    Gtk+ dependencies with my own libraries I begun to develop. I'm glad of didn't doing
+    so.
+  </para>
+  <para>
+    Thank you!
+  </para>
+</preface>
diff --git a/ags.1 b/midi2xml.1
similarity index 63%
copy from ags.1
copy to midi2xml.1
index e69afbb..69da606 100644
--- a/ags.1
+++ b/midi2xml.1
@@ -1,15 +1,15 @@
 '\" t
 .\"     Title: 
-      ags
+      midi2xml
     
 .\"    Author: [see the "AUTHOR" section]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
 .\"      Date: 2015-06-15
-.\"    Manual: ags v0.4.2
-.\"    Source: ags v0.4.2
+.\"    Manual: midi2xml v0.4.2
+.\"    Source: midi2xml v0.4.2
 .\"  Language: English
 .\"
-.TH "AGS" "1" "2015\-06\-15" "ags v0.4.2" "ags v0.4.2"
+.TH "MIDI2XML" "1" "2015\-06\-15" "midi2xml v0.4.2" "midi2xml v0.4.2"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -30,33 +30,24 @@
 .\" * MAIN CONTENT STARTS HERE *
 .\" -----------------------------------------------------------------
 .SH "NAME"
-ags \- Advanced Gtk+ Sequencer is an audio sequencer and composition editor
+midi2xml \- midi2xml converts your MIDI files to XML format
 .SH "SYNOPSIS"
-.HP \w'\fB/usr/bin/ags\fR\ 'u
-\fB/usr/bin/ags\fR [\-\-help] [\-\-version] [\-\-single\-thread] [\-\-filename\ \fIfile\fR...]
+.HP \w'\fB/usr/bin/midi2xml\fR\ 'u
+\fB/usr/bin/midi2xml\fR [\-\-help] [\-\-version] [file]
 .SH "DESCRIPTION"
 .PP
-Advanced GTK+ Sequencer is intended to use for music composition\&. It features a piano roll, as well a synth, matrix editor, drum machine, soundfont2 player, mixer and an output panel\&. It\(cqs designed to be highly configurable\&. You may add effects to its effect chain; and add or remove audio channels/pads\&. You may set up a fully functional network of engines, thus there is a link editor for linking audio lines\&.
-.PP
-LADSPA support has been added to version 0\&.4\&.2 as well export to WAV audio file\&.
-.PP
-\&...
+midi2xml takes your MIDI file from command line and outputs the resulting XML to stdout\&.
 .SH "OPTIONS"
 .PP
 The program follows the usual GNU command line syntax, with long options starting with two dashes (`\-\*(Aq)\&. A summary of options is included below\&. For a complete description, see the
 \fBinfo\fR(1)
 files\&.
 .PP
-\fB\-\-filename file\fR
+\fBfile\fR
 .RS 4
 Open file from command line\&.
 .RE
 .PP
-\fB\-\-single\-thread\fR
-.RS 4
-Run in single thread mode\&.
-.RE
-.PP
 \fB\-\-help\fR
 .RS 4
 Show summary of options\&.
diff --git a/src/ags/X/ags_audio_preferences.c b/src/ags/X/ags_audio_preferences.c
index 7392bea..170ac74 100644
--- a/src/ags/X/ags_audio_preferences.c
+++ b/src/ags/X/ags_audio_preferences.c
@@ -312,7 +312,9 @@ ags_audio_preferences_apply(AgsApplicable *applicable)
 			   &current,
 			   0,
 			   &value);
-  str = g_strdup(g_value_get_string(&value));
+  
+  //FIXME:JK: work-around for alsa-handle
+  str = g_strdup_printf("%s,0", g_value_get_string(&value));
   g_message("%s\0", str);
   ags_config_set(config,
 		 AGS_CONFIG_DEVOUT,
@@ -360,7 +362,7 @@ ags_audio_preferences_reset(AgsApplicable *applicable)
   GtkTreeIter current;
   GList *card_id, *card_name;
   GValue value =  {0,};
-  char *device, *str;
+  char *device, *str, *tmp;
   guint nth;
   gboolean found_card;
   int card_num;
@@ -382,14 +384,20 @@ ags_audio_preferences_reset(AgsApplicable *applicable)
   str = ags_config_get(config,
 		       AGS_CONFIG_DEVOUT,
 		       "alsa-handle\0");
+  g_message("%s\0", str);
   nth = 0;
   found_card = FALSE;
 
   while(card_id != NULL){
-    if(!g_ascii_strcasecmp(card_id->data,
+    //FIXME:JK: work-around for alsa-handle
+    tmp = g_strdup_printf("%s,0\0",
+			  card_id->data);
+    if(!g_ascii_strcasecmp(tmp,
 			   str)){
       found_card = TRUE;
     }
+
+    g_free(tmp);
     
     if(!found_card){
       nth++;
@@ -418,9 +426,6 @@ ags_audio_preferences_reset(AgsApplicable *applicable)
 	       "buffer_size\0", &buffer_size,
 	       NULL);
 
-
-  error = NULL;
-
   /*  */
   gtk_spin_button_set_value(audio_preferences->audio_channels,
 			    (gdouble) channels);
@@ -442,6 +447,8 @@ ags_audio_preferences_reset(AgsApplicable *applicable)
 			   0,
 			   &value);
   str = g_strdup(g_value_get_string(&value));
+
+  error = NULL;
   ags_devout_pcm_info(str,
   		      &channels_min, &channels_max,
   		      &rate_min, &rate_max,
diff --git a/src/ags/X/ags_audio_preferences.h b/src/ags/X/ags_audio_preferences.h
index e744c49..367335f 100644
--- a/src/ags/X/ags_audio_preferences.h
+++ b/src/ags/X/ags_audio_preferences.h
@@ -34,7 +34,7 @@ typedef struct _AgsAudioPreferencesClass AgsAudioPreferencesClass;
 struct _AgsAudioPreferences
 {
   GtkVBox vbox;
-
+  
   GtkComboBox *card;
   GtkSpinButton *audio_channels;
   GtkSpinButton *samplerate;
diff --git a/src/ags/X/ags_audio_preferences_callbacks.c b/src/ags/X/ags_audio_preferences_callbacks.c
index 798fdd0..8c112ff 100644
--- a/src/ags/X/ags_audio_preferences_callbacks.c
+++ b/src/ags/X/ags_audio_preferences_callbacks.c
@@ -77,8 +77,14 @@ ags_audio_preferences_card_changed_callback(GtkComboBox *combo,
   AgsSetOutputDevice *set_output_device;
   GtkListStore *model;
   GtkTreeIter current;
+  gchar *str;
+  guint channels, channels_min, channels_max;
+  guint rate, rate_min, rate_max;
+  guint buffer_size, buffer_size_min, buffer_size_max;
   GValue value =  {0,};
-  
+
+  GError *error;
+
   window = AGS_WINDOW(AGS_PREFERENCES(gtk_widget_get_ancestor(GTK_WIDGET(audio_preferences),
 							      AGS_TYPE_PREFERENCES))->window);
   devout = AGS_DEVOUT(window->devout);
@@ -95,16 +101,49 @@ ags_audio_preferences_card_changed_callback(GtkComboBox *combo,
 			   0,
 			   &value);
   
+  str = g_strdup(g_value_get_string(&value));
+  
   /* create set output device task */
   set_output_device = ags_set_output_device_new((GObject *) devout,
-						g_strdup(g_value_get_string(&value)));
+						str);
 
   /* append AgsSetOutputDevice */
   ags_task_thread_append_task(AGS_TASK_THREAD(AGS_AUDIO_LOOP(AGS_MAIN(devout->ags_main)->main_loop)->task_thread),
 			      AGS_TASK(set_output_device));
   
   /* reset dialog */
-  ags_audio_preferences_reset(audio_preferences);
+  error = NULL;
+  ags_devout_pcm_info(str,
+  		      &channels_min, &channels_max,
+  		      &rate_min, &rate_max,
+  		      &buffer_size_min, &buffer_size_max,
+  		      &error);
+
+  if(error != NULL){
+    GtkMessageDialog *dialog;
+
+    dialog = (GtkMessageDialog *) gtk_message_dialog_new((GtkWindow *) gtk_widget_get_ancestor(GTK_WIDGET(audio_preferences),
+											       AGS_TYPE_PREFERENCES),
+							 GTK_DIALOG_MODAL,
+							 GTK_MESSAGE_ERROR,
+							 GTK_BUTTONS_CLOSE,
+							 "%s\0", error->message);
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(GTK_WIDGET(dialog));
+
+    gtk_spin_button_set_range(audio_preferences->audio_channels, 0.0, 24.0);
+    gtk_spin_button_set_range(audio_preferences->samplerate, 1.0, 192000.0);
+    gtk_spin_button_set_range(audio_preferences->buffer_size, 1.0, 65535.0);
+
+    return;
+  }
+
+  gtk_spin_button_set_range(audio_preferences->audio_channels,
+			    channels_min, channels_max);
+  gtk_spin_button_set_range(audio_preferences->samplerate,
+			    rate_min, rate_max);
+  gtk_spin_button_set_range(audio_preferences->buffer_size,
+			    buffer_size_min, buffer_size_max);
 }
 
 void
diff --git a/src/ags/audio/ags_config.c b/src/ags/audio/ags_config.c
index 1483cdb..8be1774 100644
--- a/src/ags/audio/ags_config.c
+++ b/src/ags/audio/ags_config.c
@@ -223,7 +223,7 @@ ags_config_load_defaults(AgsConfig *config)
   ags_config_set(config, ags_config_devout, "buffer-size\0", "940\0");
   ags_config_set(config, ags_config_devout, "pcm-channels\0", "2\0");
   ags_config_set(config, ags_config_devout, "dsp-channels\0", "2\0");
-  ags_config_set(config, ags_config_devout, "alsa-handle\0", "hw:0\0");
+  ags_config_set(config, ags_config_devout, "alsa-handle\0", "hw:0,0\0");
 
   ags_config_set(config, ags_config_recall, "auto-sense\0", "true\0");
 }
@@ -495,10 +495,10 @@ ags_config_set(AgsConfig *config, gchar *group, gchar *key, gchar *value)
 		      "alsa-handle\0",
 		      11)){
       gchar *alsa_handle;
-    
+
       alsa_handle = value;
       g_object_set(G_OBJECT(devout),
-		   "device\0", alsa_handle,
+		   "device\0", g_strdup_printf("%s\0", alsa_handle),
 		   NULL);
     }
   }
diff --git a/src/ags/audio/ags_devout.c b/src/ags/audio/ags_devout.c
index 1a7182c..663f9d0 100644
--- a/src/ags/audio/ags_devout.c
+++ b/src/ags/audio/ags_devout.c
@@ -924,8 +924,8 @@ ags_devout_list_cards(GList **card_id, GList **card_name)
   snd_ctl_t *card_handle;
   snd_ctl_card_info_t *card_info;
   char *name;
-  gchar *str;
-  int card_num;
+  gchar *str, *tmp;
+  int card_num, dev_num;
   int error;
 
   *card_id = NULL;
@@ -943,9 +943,10 @@ ags_devout_list_cards(GList **card_id, GList **card_name)
       continue;
     }
 
-    str = g_strdup_printf("hw:%i\0", card_num);
+    tmp = 
+      str = g_strdup_printf("hw:%i\0", card_num);
     error = snd_ctl_open(&card_handle, str, 0);
-
+    
     if(error < 0){
       continue;
     }
@@ -991,6 +992,7 @@ ags_devout_pcm_info(char *card_id,
 		    guint *buffer_size_min, guint *buffer_size_max,
 		    GError **error)
 {
+  char *str;
   int rc;
   snd_pcm_t *handle;
   snd_pcm_hw_params_t *params;
@@ -1002,7 +1004,7 @@ ags_devout_pcm_info(char *card_id,
 
   /* Open PCM device for playback. */
   handle = NULL;
-  
+
   rc = snd_pcm_open(&handle, card_id, SND_PCM_STREAM_PLAYBACK, 0);
 
   if(rc < 0) {
diff --git a/src/ags/main.c b/src/ags/main.c
index 4bfa1b7..54f45a5 100644
--- a/src/ags/main.c
+++ b/src/ags/main.c
@@ -821,7 +821,8 @@ main(int argc, char **argv)
     if(!strncmp(argv[i], "--help\0", 7)){
       printf("GSequencer `ags` is an audio sequencer and notation editor\n\n\0");
 
-      printf("Usage:\n\t%s\n\t%s\n\t%s\n\t%s\n\nReport bugs to <jkraehemann at gmail.com>\n\0",
+      printf("Usage:\n\t%s\n\t%s\n\t%s\n\t%s\n\n",
+	     "Report bugs to <jkraehemann at gmail.com>\n\0",
 	     "--filename file     open file\0",
 	     "--single-thread     run in single thread mode\0",     
 	     "--help              display this help and exit\0",
diff --git a/src/midi2ags/main.c b/src/midi2ags/main.c
new file mode 100644
index 0000000..2f97aa9
--- /dev/null
+++ b/src/midi2ags/main.c
@@ -0,0 +1,60 @@
+#include <glib.h>
+#include <glib-object.h>
+
+#include <midi2ags/midi/ags_midi_parser.h>
+
+#include <stdio.h>
+
+#include <libxml/tree.h>
+
+int
+main(int argc, char **argv)
+{
+  AgsMidiParser *midi_parser;
+
+  FILE *out;
+  FILE *file;
+  
+  xmlChar *buffer;
+  gchar *filename;
+  size_t length;
+
+  if(argc == 2){
+
+    if(!strncmp(argv[1], "--help\0", 7)){
+      printf("midi2xml converts MIDI to XML\n\n\0");
+
+      printf("Usage:\n\t%s\n\t%s\n\t%s\n\t%s\n\n",
+	     "Report bugs to <jkraehemann at gmail.com>\n\0",
+	     "--help              display this help and exit\0",
+	     "--version           output version information and exit\0",
+	     "<file>              the file to be processed\0");
+      
+      exit(0);
+    }else if(!strncmp(argv[1], "--version\0", 10)){
+      printf("midi2xml 1.0.0\n\n\0");
+      
+      printf("%s\n%s\n%s\n\n\0",
+	     "Copyright (C) 2015 Joël Krähemann\0",
+	     "This is free software; see the source for copying conditions.  There is NO\0",
+	     "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\0");
+      
+      printf("Written by Joël Krähemann\n\0");
+      exit(0);
+    }else{
+      filename = argv[1];
+    }
+  }else{
+    return(-1);
+  }
+
+  file = fopen(filename, "r\0");
+  fseek(file, 0, SEEK_SET);
+  midi_parser = ags_midi_parser_new(file);
+
+  ags_midi_parser_parse_full(midi_parser);
+
+  xmlSaveFormatFileEnc("-", midi_parser->doc, "UTF-8", 1);
+  
+  return(0);
+}
diff --git a/src/midi2ags/midi/ags_midi_parser.c b/src/midi2ags/midi/ags_midi_parser.c
new file mode 100644
index 0000000..e855704
--- /dev/null
+++ b/src/midi2ags/midi/ags_midi_parser.c
@@ -0,0 +1,2276 @@
+/* AGS - Advanced GTK Sequencer
+ * Copyright (C) 2015 Joël Krähemann
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <midi2ags/midi/ags_midi_parser.h>
+#include <midi2ags/object/ags_marshal.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+void ags_midi_parser_class_init(AgsMidiParserClass *midi_parser);
+void ags_midi_parser_init(AgsMidiParser *midi_parser);
+void ags_midi_parser_set_property(GObject *gobject,
+				  guint prop_id,
+				  const GValue *value,
+				  GParamSpec *param_spec);
+void ags_midi_parser_get_property(GObject *gobject,
+				  guint prop_id,
+				  GValue *value,
+				  GParamSpec *param_spec);
+void ags_midi_parser_finalize(GObject *gobject);
+
+int ags_midi_parser_real_midi_getc(AgsMidiParser *midi_parser);
+void ags_midi_parser_real_on_error(AgsMidiParser *midi_parser,
+				   GError **error);
+
+xmlDoc* ags_midi_parser_real_parse_full(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_real_parse_header(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_real_parse_track(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_real_key_on(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_key_off(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_key_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_parameter(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_pitch_bend(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_program(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_change_channel_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_not_defined(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_real_sysex(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_system_common(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_real_meta_event(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_real_sequence_number(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_end_of_track(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_smpte(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_tempo(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_time_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_key_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_real_text_event(AgsMidiParser *midi_parser, guint meta_type);
+
+#define AGS_MIDI_PARSER_MAX_TEXT_LENGTH (4096)
+
+#define AGS_MIDI_EVENT "event\0"
+
+/**
+ * SECTION:ags_midi_parser
+ * @short_description: the menu bar.
+ * @title: AgsMidiParser
+ * @section_id:
+ * @include: ags/X/ags_midi_parser.h
+ *
+ * #AgsMidiParser reads your midi parsers.
+ */
+
+enum{
+  PROP_0,
+  PROP_FILE,
+};
+
+enum{
+  MIDI_GETC,
+  ON_ERROR,
+  PARSE_FULL,
+  PARSE_HEADER,
+  PARSE_TRACK,
+  KEY_ON,
+  KEY_OFF,
+  KEY_PRESSURE,
+  CHANGE_PARAMETER,
+  CHANGE_PITCH_BEND,
+  CHANGE_PROGRAM,
+  CHANGE_CHANNEL_PRESSURE,
+  NOT_DEFINED,
+  SYSEX,
+  SYSTEM_COMMON,
+  META_EVENT,
+  SEQUENCE_NUMBER,
+  END_OF_TRACK,
+  SMPTE,
+  TEMPO,
+  TIME_SIGNATURE,
+  KEY_SIGNATURE,
+  SEQUENCER_META_EVENT,
+  TEXT_EVENT,
+  LAST_SIGNAL,
+};
+
+static gpointer ags_midi_parser_parent_class = NULL;
+static guint midi_parser_signals[LAST_SIGNAL];
+
+GType
+ags_midi_parser_get_type(void)
+{
+  static GType ags_type_midi_parser = 0;
+
+  if(!ags_type_midi_parser){
+    static const GTypeInfo ags_midi_parser_info = {
+      sizeof (AgsMidiParserClass),
+      NULL, /* base_init */
+      NULL, /* base_finalize */
+      (GClassInitFunc) ags_midi_parser_class_init,
+      NULL, /* class_finalize */
+      NULL, /* class_data */
+      sizeof (AgsMidiParser),
+      0,    /* n_preallocs */
+      (GInstanceInitFunc) ags_midi_parser_init,
+    };
+
+    ags_type_midi_parser = g_type_register_static(G_TYPE_OBJECT,
+						  "AgsMidiParser\0", &ags_midi_parser_info,
+						  0);
+  }
+
+  return(ags_type_midi_parser);
+}
+
+void
+ags_midi_parser_class_init(AgsMidiParserClass *midi_parser)
+{
+  GObjectClass *gobject;
+  GParamSpec *param_spec;
+  
+  ags_midi_parser_parent_class = g_type_class_peek_parent(midi_parser);
+
+  /* GObjectClass */
+  gobject = (GObjectClass *) midi_parser;
+
+  gobject->set_property = ags_midi_parser_set_property;
+  gobject->get_property = ags_midi_parser_get_property;
+  
+  gobject->finalize = ags_midi_parser_finalize;
+
+  /**
+   * AgsMidiParser:dsp-channels:
+   *
+   * The dsp channel count
+   * 
+   * Since: 0.4.2
+   */
+  param_spec = g_param_spec_pointer("file\0",
+				    "the file stream\0",
+				    "The file stream to parse\0",
+				    G_PARAM_READABLE | G_PARAM_WRITABLE);
+  g_object_class_install_property(gobject,
+				  PROP_FILE,
+				  param_spec);
+
+  /* AgsMidiParser */
+  midi_parser->midi_getc = ags_midi_parser_real_midi_getc;
+  midi_parser->on_error = ags_midi_parser_real_on_error;
+
+  midi_parser->parse_header = ags_midi_parser_real_parse_header;
+  midi_parser->parse_track = ags_midi_parser_real_parse_track;
+
+  midi_parser->key_on = ags_midi_parser_real_key_on;
+  midi_parser->key_off = ags_midi_parser_real_key_off;
+  midi_parser->key_pressure = ags_midi_parser_real_key_pressure;
+  midi_parser->change_parameter = ags_midi_parser_real_change_parameter;
+  midi_parser->change_pitch_bend = ags_midi_parser_real_change_pitch_bend;
+  midi_parser->change_program = ags_midi_parser_real_change_program;
+  midi_parser->change_channel_pressure = ags_midi_parser_real_change_channel_pressure;
+  midi_parser->not_defined = ags_midi_parser_real_not_defined;
+
+  midi_parser->sysex = ags_midi_parser_real_sysex;
+  midi_parser->system_common = ags_midi_parser_real_system_common;
+
+  midi_parser->meta_event = ags_midi_parser_real_meta_event;
+  midi_parser->sequence_number = ags_midi_parser_real_sequence_number;
+  midi_parser->end_of_track = ags_midi_parser_real_end_of_track;
+  midi_parser->smpte = ags_midi_parser_real_smpte;
+  midi_parser->tempo = ags_midi_parser_real_tempo;
+  midi_parser->time_signature = ags_midi_parser_real_time_signature;
+  midi_parser->key_signature = ags_midi_parser_real_key_signature;
+  midi_parser->sequencer_meta_event = ags_midi_parser_real_sequencer_meta_event;
+  midi_parser->text_event = ags_midi_parser_real_text_event;
+
+  midi_parser->parse_full = ags_midi_parser_real_parse_full;
+  
+  /* signals */
+  /**
+   * AgsMidiParser::midi-getc:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::midi-getc signal is emited during parsing of event.
+   */
+  midi_parser_signals[MIDI_GETC] =
+    g_signal_new("midi-getc\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, midi_getc),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_INT__VOID,
+		 G_TYPE_INT, 0);
+
+  /**
+   * AgsMidiParser::on-error:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::on-error signal is emited during parsing of event.
+   */
+  midi_parser_signals[ON_ERROR] =
+    g_signal_new("on-error\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, on_error),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__VOID,
+		 G_TYPE_POINTER, 0);
+
+
+  /**
+   * AgsMidiParser::parse-header:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the header
+   *
+   * The ::parse-header signal is emited during parsing of header.
+   */
+  midi_parser_signals[PARSE_HEADER] =
+    g_signal_new("parse-header\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, parse_header),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__VOID,
+		 G_TYPE_POINTER, 0);
+
+  /**
+   * AgsMidiParser::parse-track:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the track
+   *
+   * The ::parse-track signal is emited during parsing of track.
+   */
+  midi_parser_signals[PARSE_TRACK] =
+    g_signal_new("parse-track\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, parse_track),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__VOID,
+		 G_TYPE_POINTER, 0);
+
+  /**
+   * AgsMidiParser::key-on:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::key-on signal is emited during parsing of event.
+   */
+  midi_parser_signals[KEY_ON] =
+    g_signal_new("key-on\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, key_on),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::key-off:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::key-off signal is emited during parsing of event.
+   */
+  midi_parser_signals[KEY_OFF] =
+    g_signal_new("key-off\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, key_off),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::key-pressure:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::key-pressure signal is emited during parsing of event.
+   */
+  midi_parser_signals[KEY_PRESSURE] =
+    g_signal_new("key-pressure\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, key_pressure),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::change-parameter:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::change-parameter signal is emited during parsing of event.
+   */
+  midi_parser_signals[CHANGE_PARAMETER] =
+    g_signal_new("change-parameter\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, change_parameter),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::change-pitch-bend:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::change-pitch-bend signal is emited during parsing of event.
+   */
+  midi_parser_signals[CHANGE_PITCH_BEND] =
+    g_signal_new("change-pitch-bend\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, change_pitch_bend),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::change-program:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::change-program signal is emited during parsing of event.
+   */
+  midi_parser_signals[CHANGE_PROGRAM] =
+    g_signal_new("change-program\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, change_program),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::change-channel-pressure:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::change-channel-pressure signal is emited during parsing of event.
+   */
+  midi_parser_signals[CHANGE_CHANNEL_PRESSURE] =
+    g_signal_new("change-channel-pressure\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, change_channel_pressure),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::not-defined:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::not-defined signal is emited during parsing of event.
+   */
+  midi_parser_signals[NOT_DEFINED] =
+    g_signal_new("not-defined\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, not_defined),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::sysex:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::sysex signal is emited during parsing of event.
+   */
+  midi_parser_signals[SYSEX] =
+    g_signal_new("sysex\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, sysex),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::system-common:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::system-common signal is emited during parsing of event.
+   */
+  midi_parser_signals[SYSTEM_COMMON] =
+    g_signal_new("system-common\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, system_common),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::meta-event:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::meta-event signal is emited during parsing of event.
+   */
+  midi_parser_signals[META_EVENT] =
+    g_signal_new("meta-event\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, meta_event),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::sequence-number:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::sequence-number signal is emited during parsing of event.
+   */
+  midi_parser_signals[SEQUENCE_NUMBER] =
+    g_signal_new("sequence-number\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, sequence_number),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::end-of-track:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::end-of-track signal is emited during parsing of event.
+   */
+  midi_parser_signals[END_OF_TRACK] =
+    g_signal_new("end-of-track\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, end_of_track),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::smpte:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::smpte signal is emited during parsing of event.
+   */
+  midi_parser_signals[SMPTE] =
+    g_signal_new("smpte\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, smpte),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::tempo:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::tempo signal is emited during parsing of event.
+   */
+  midi_parser_signals[TEMPO] =
+    g_signal_new("tempo\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, tempo),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::time-signature:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::time-signature signal is emited during parsing of event.
+   */
+  midi_parser_signals[TIME_SIGNATURE] =
+    g_signal_new("time-signature\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, time_signature),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::key-signature:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::key-signature signal is emited during parsing of event.
+   */
+  midi_parser_signals[KEY_SIGNATURE] =
+    g_signal_new("key-signature\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, key_signature),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::sequencer-meta-event:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::sequencer-meta-event signal is emited during parsing of event.
+   */
+  midi_parser_signals[SEQUENCER_META_EVENT] =
+    g_signal_new("sequencer-meta-event\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, sequencer_meta_event),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::text-event:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::text-event signal is emited during parsing of event.
+   */
+  midi_parser_signals[TEXT_EVENT] =
+    g_signal_new("text-event\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, text_event),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__UINT,
+		 G_TYPE_POINTER, 1,
+		 G_TYPE_UINT);
+
+  /**
+   * AgsMidiParser::parse-full:
+   * @midi_parser: the parser
+   *
+   * Returns: The XML node representing the event
+   *
+   * The ::parse-full signal is emited during parsing of midi file.
+   */
+  midi_parser_signals[PARSE_FULL] =
+    g_signal_new("parse-full\0",
+		 G_TYPE_FROM_CLASS(midi_parser),
+		 G_SIGNAL_RUN_LAST,
+		 G_STRUCT_OFFSET(AgsMidiParserClass, parse_full),
+		 NULL, NULL,
+		 g_cclosure_user_marshal_POINTER__VOID,
+		 G_TYPE_POINTER, 0);
+}
+
+void
+ags_midi_parser_init(AgsMidiParser *midi_parser)
+{
+  midi_parser->flags = 0;
+  
+  midi_parser->file = NULL;
+  midi_parser->nth_chunk = 0;
+
+  midi_parser->file_length = 0;
+  midi_parser->offset = 0;
+
+  midi_parser->current_time = 0;
+
+  midi_parser->doc = NULL;
+}
+
+void
+ags_midi_parser_set_property(GObject *gobject,
+			     guint prop_id,
+			     const GValue *value,
+			     GParamSpec *param_spec)
+{
+  AgsMidiParser *midi_parser;
+
+  midi_parser = AGS_MIDI_PARSER(gobject);
+  
+  switch(prop_id){
+  case PROP_FILE:
+    {
+      midi_parser->file = g_value_get_pointer(value);
+    }
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+    break;
+  }
+}
+
+void
+ags_midi_parser_get_property(GObject *gobject,
+			     guint prop_id,
+			     GValue *value,
+			     GParamSpec *param_spec)
+{
+  AgsMidiParser *midi_parser;
+
+  midi_parser = AGS_MIDI_PARSER(gobject);
+  
+  switch(prop_id){
+  case PROP_FILE:
+    {
+      g_value_set_pointer(value,
+			  midi_parser->file);
+    }
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
+    break;
+  }
+}
+
+void
+ags_midi_parser_finalize(GObject *gobject)
+{
+  G_OBJECT_CLASS(ags_midi_parser_parent_class)->finalize(gobject);
+}
+
+gint16
+ags_midi_parser_read_gint16(AgsMidiParser *midi_parser)
+{
+  char str[2];
+  gint16 value = 0;
+
+  str[0] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+  value = (str[0] & 0xff);
+  value = (value<<8) + (str[1] & 0xff);
+  
+  return(value);
+}
+
+gint32
+ags_midi_parser_read_gint24(AgsMidiParser *midi_parser)
+{
+  char str[4];
+  gint32 value = 0;
+  
+  str[0] = (char) 0x00;
+  str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[2] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[3] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+  value = (value<<8) + (str[1] & 0xff);
+  value = (value<<8) + (str[2] & 0xff);
+  value = (value<<8) + (str[3] & 0xff);
+  
+  return(value);
+}
+
+gint32
+ags_midi_parser_read_gint32(AgsMidiParser *midi_parser)
+{
+  char str[4];
+  gint32 value;
+  
+  str[0] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[1] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[2] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+  str[3] = (char) 0xff & ags_midi_parser_midi_getc(midi_parser);
+
+  value = (str[0] & 0xff);
+  value = (value<<8) + (str[1] & 0xff);
+  value = (value<<8) + (str[2] & 0xff);
+  value = (value<<8) + (str[3] & 0xff);
+  
+  return(value);
+}
+
+long
+ags_midi_parser_read_varlength(AgsMidiParser *midi_parser)
+{
+  long value;
+  guint i;
+  char c;
+  
+  c = ags_midi_parser_midi_getc(midi_parser);
+  value = c;
+  i = 1;
+  
+  if(c & 0x80){
+    value &= 0x7F;
+   
+    do{
+      value = (value << 7) + ((c = ags_midi_parser_midi_getc(midi_parser)) & 0x7F);
+      i++;
+    }while(c & 0x80);
+  }
+  
+  return(value);
+}
+
+gchar*
+ags_midi_parser_read_text(AgsMidiParser *midi_parser,
+			  gint length)
+{
+  gchar text[AGS_MIDI_PARSER_MAX_TEXT_LENGTH];
+  gchar c;
+  guint i;
+
+  memset(text, 0, AGS_MIDI_PARSER_MAX_TEXT_LENGTH * sizeof(char));
+  i = 0;
+  
+  while((length <= 0 ||
+	 i < length) && (c = (char) 0xff & ags_midi_parser_midi_getc(midi_parser)) != EOF){
+    if(c == '\0' || !(g_ascii_isalnum(c) ||
+		      g_ascii_ispunct(c) ||
+		      c == ' ')){
+      break;
+    }
+
+    text[i] = c;
+    i++;
+  }
+
+  text[i] = '\0';
+    
+  return(g_strdup(text));
+}
+
+gdouble
+ags_midi_parser_ticks_to_sec(AgsMidiParser *midi_parser,
+			     guint ticks, gint division, guint tempo)
+{
+  gdouble retval;
+  
+  if(division > 0){
+    retval = ((gdouble) ticks * tempo) /
+	      (gdouble) (division * 1000000.0);
+    return(retval);
+  }else{
+    gdouble smpte_format, smpte_resolution;
+
+    smpte_format = (gdouble) ((0xff00 & division) >> 8);
+    smpte_resolution = (gdouble) (0xff & division);
+
+    retval = (((gdouble) ticks) /
+	      (gdouble) (smpte_format * smpte_resolution * 1000000.0));
+    
+    return(retval);
+  }
+}
+
+int
+ags_midi_parser_midi_getc(AgsMidiParser *midi_parser)
+{
+  int c;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), '\0');
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[MIDI_GETC], 0,
+		&c);
+  g_object_unref((GObject *) midi_parser);
+
+  return(c);
+}
+
+int
+ags_midi_parser_real_midi_getc(AgsMidiParser *midi_parser)
+{
+  int c;
+
+  c = fgetc(midi_parser->file);
+  
+  if(c == EOF){
+    g_warning("reached end of file\0");
+    midi_parser->flags |= AGS_MIDI_PARSER_EOF;
+  }
+
+  return(c);
+}
+
+void
+ags_midi_parser_on_error(AgsMidiParser *midi_parser,
+			 GError **error)
+{
+  g_return_if_fail(AGS_IS_MIDI_PARSER(midi_parser));
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[ON_ERROR], 0,
+		error);
+  g_object_unref((GObject *) midi_parser);
+}
+
+void
+ags_midi_parser_real_on_error(AgsMidiParser *midi_parser,
+			      GError **error)
+{
+}
+
+xmlDoc*  
+ags_midi_parser_parse_full(AgsMidiParser *midi_parser)
+{
+  xmlDoc *doc;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[PARSE_FULL], 0,
+		&doc);
+  g_object_unref((GObject *) midi_parser);
+
+  return(doc);
+}
+
+xmlDoc*
+ags_midi_parser_real_parse_full(AgsMidiParser *midi_parser)
+{
+  xmlDoc *doc;
+  xmlNode *root_node;
+  xmlNode *tracks_node;
+  xmlNode *current;
+
+  GError *error;
+
+  midi_parser->doc = 
+    doc = xmlNewDoc("1.0\0");
+  root_node = xmlNewNode(NULL, "midi\0");
+  xmlDocSetRootElement(doc, root_node);
+
+  tracks_node = xmlNewNode(NULL, "midi-tracks\0");
+
+  error = NULL;
+
+  current = ags_midi_parser_parse_header(midi_parser);
+  xmlAddChild(root_node,
+	      current);
+#ifdef DEBUG
+  g_message("parsed header\0");
+#endif
+  
+  xmlAddChild(root_node,
+	      tracks_node);
+  
+  while(((AGS_MIDI_PARSER_EOF & (midi_parser->flags))) == 0){
+    current = ags_midi_parser_parse_track(midi_parser);
+    
+    if(current != NULL){
+      xmlAddChild(tracks_node,
+		  current);
+#ifdef DEBUG
+      g_message("parsed track\0");
+#endif
+    }else{
+      g_warning("skipped input\0");
+    }
+  }
+
+  return(doc);
+}
+
+xmlNode*  
+ags_midi_parser_parse_header(AgsMidiParser *midi_parser)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[PARSE_HEADER], 0,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_parse_header(AgsMidiParser *midi_parser)
+{
+  xmlNode *node;
+
+  static gchar header[] = "MThd";
+  guint format;
+  guint count;
+  guint division;
+  guint offset;
+  guint times;
+  guint beat, clicks;
+  guint n;
+  gchar c;
+  
+  n = 0;
+  
+  while(n < 4 &&
+	(AGS_MIDI_PARSER_EOF & (midi_parser->flags)) == 0){
+    c = ags_midi_parser_midi_getc(midi_parser);
+    
+    if(c == header[n]){
+      n++;
+    }else{
+      n = 0;
+    }
+  }
+  
+  node = xmlNewNode(NULL,
+		    "midi-header\0");
+
+  offset = (guint) ags_midi_parser_read_gint32(midi_parser);
+  format = (guint) ags_midi_parser_read_gint16(midi_parser);
+  count = (guint) ags_midi_parser_read_gint16(midi_parser);
+  division = (guint) ags_midi_parser_read_gint16(midi_parser);
+
+  xmlNewProp(node,
+	     "format\0",
+	     g_strdup_printf("%d\0", format));
+
+  if(division & 0x8000){
+    /* SMPTE */
+    times = 0; /* Can't do beats */
+
+    xmlNewProp(node,
+	       "division\0",
+	       g_strdup_printf("%d %d\0", -((-(division>>8))&0xff), division&0xff));
+  }else{
+    xmlNewProp(node,
+	       "division\0",
+	       g_strdup_printf("%d\0", division));
+  }
+  
+  if(format > 2){
+    fprintf(stderr, "Can't deal with format %d files\n", format);
+    exit(-1);
+  }
+  
+  beat =
+    clicks = division;
+
+  xmlNewProp(node,
+	     "beat\0",
+	     g_strdup_printf("%d\0", beat));
+
+  xmlNewProp(node,
+	     "track-count\0",
+	     g_strdup_printf("%d\0", count));
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_parse_track(AgsMidiParser *midi_parser)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[PARSE_TRACK], 0,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_parse_track(AgsMidiParser *midi_parser)
+{
+  xmlNode *node, *current;
+  static gchar track[] = "MTrk";
+  gint offset, start_offset;
+  long delta_time;
+  guint status;
+  guint n;
+  gchar c;
+
+  n = 0;
+  
+  while(n < 4 &&
+	(AGS_MIDI_PARSER_EOF & (midi_parser->flags)) == 0){
+    c = ags_midi_parser_midi_getc(midi_parser);
+    
+    if(c == track[n]){
+      n++;
+    }else{
+      n = 0;
+    }
+  }
+
+  if((AGS_MIDI_PARSER_EOF & (midi_parser->flags)) != 0){
+    return(NULL);
+  }
+
+  node = xmlNewNode(NULL, "midi-track\0");
+
+  offset = ags_midi_parser_read_gint32(midi_parser);
+
+#ifdef DEBUG
+  g_message("n = %d\noffset = %d\0", n, offset);
+#endif
+  
+  start_offset = ftell(midi_parser->file);
+
+  if(offset < 0){
+    return(NULL);
+  }
+
+  midi_parser->current_time = 0;
+  
+  for(; ftell(midi_parser->file) < start_offset + offset; ){
+    delta_time = ags_midi_parser_read_varlength(midi_parser);
+    midi_parser->current_time += delta_time;
+    
+    status = ags_midi_parser_midi_getc(midi_parser);
+    
+    if((0xf0 & (0xf0 & status)) != 0xf0){
+      current = ags_midi_parser_channel_message(midi_parser,
+						status);
+
+      if(current != NULL){
+	xmlNewProp(current,
+		   "delta-time\0",
+		   g_strdup_printf("%d\0", midi_parser->current_time));
+	
+	xmlAddChild(node,
+		    current);
+      }
+      
+#ifdef DEBUG
+      g_message("channel message");
+#endif
+    }else{
+#ifdef DEBUG
+      g_message("status message");
+#endif
+      
+      switch(status){
+      case 0xf0:
+	{
+	  /* start of system exclusive */
+	  ags_midi_parser_sysex(midi_parser,
+				status);
+
+	}
+      case 0xf1:
+      case 0xf2:
+      case 0xf3:
+      case 0xf4:
+      case 0xf5:
+      case 0xf6:
+	{
+	  ags_midi_parser_system_common(midi_parser,
+					status);
+	}
+	break;
+      case 0xf7:
+	{
+	  /* sysex continuation or arbitrary stuff */
+#ifdef DEBUG
+	  g_message("sysex end\0");
+#endif
+	}
+	break;
+      case 0xff:
+	{
+	  /* meta event */
+	  current = ags_midi_parser_meta_event(midi_parser,
+					       status);
+
+	  if(current != NULL){
+	    xmlNewProp(current,
+		       "delta-time\0",
+		       g_strdup_printf("%d\0", midi_parser->current_time));
+	    
+	    xmlAddChild(node,
+			current);
+	  }
+	}
+	break;
+      default:
+	g_warning("bad byte\0");
+	break;
+      }
+    }
+  }
+  
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_channel_message(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+
+  node = NULL;
+  
+  switch(status & 0xf0){
+  case 0x80:
+    {
+      node = ags_midi_parser_key_off(midi_parser, status);
+    }
+    break;
+  case 0x90:
+    {
+      node = ags_midi_parser_key_on(midi_parser, status);
+    }
+    break;
+  case 0xa0:
+    {
+      node = ags_midi_parser_key_pressure(midi_parser, status);
+    }
+    break;
+  case 0xb0:
+    {
+      node = ags_midi_parser_change_parameter(midi_parser, status);
+    }
+    break;
+  case 0xc0:
+    {
+      node = ags_midi_parser_change_program(midi_parser, status);
+    }
+    break;
+  case 0xd0:
+    {
+      node = ags_midi_parser_change_channel_pressure(midi_parser, status);
+    }
+    break;
+  case 0xe0:
+    {
+      node = ags_midi_parser_change_pitch_bend(midi_parser, status);
+    }
+    break;
+  }
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_key_on(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, note, velocity;
+
+  channel = 0xf & status;
+  note = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+  velocity = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "note-on\0");
+
+  xmlNewProp(node,
+	     "key\0",
+	     g_strdup_printf("%d\0", channel));
+
+  xmlNewProp(node,
+	     "note\0",
+	     g_strdup_printf("%d\0", note));
+
+  xmlNewProp(node,
+	     "velocity\0",
+	     g_strdup_printf("%d\0", velocity));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_key_on(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[KEY_ON], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_key_off(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, note, velocity;
+
+  channel = 0xf & status;
+  note = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+  velocity = (0x7f) & ags_midi_parser_midi_getc(midi_parser);
+
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+  
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "note-off\0");
+
+
+  xmlNewProp(node,
+	     "key\0",
+	     g_strdup_printf("%d\0", channel));
+
+  xmlNewProp(node,
+	     "note\0",
+	     g_strdup_printf("%d\0", note));
+
+  xmlNewProp(node,
+	     "velocity\0",
+	     g_strdup_printf("%d\0", velocity));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_key_off(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[KEY_OFF], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_key_pressure(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, note, pressure;
+
+  channel = 0xf & status;
+  note = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  pressure = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "polyphonic\0");
+	
+  xmlNewProp(node,
+	     "key\0",
+	     g_strdup_printf("%d\0", channel));
+  
+  xmlNewProp(node,
+	     "note\0",
+	     g_strdup_printf("%d\0", note));
+
+  xmlNewProp(node,
+	     "pressure\0",
+	     g_strdup_printf("%d\0", pressure));
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_key_pressure(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[KEY_PRESSURE], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_change_parameter(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, control, value;
+
+  channel = 0xf & status;
+  control = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  value = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  if(control < 120){
+    xmlNewProp(node,
+	       AGS_MIDI_EVENT,
+	       "change-parameter\0");
+
+    xmlNewProp(node,
+	       "channel\0",
+	       g_strdup_printf("%d\0", channel));
+
+    xmlNewProp(node,
+	       "control\0",
+	       g_strdup_printf("%d\0", control));
+
+    xmlNewProp(node,
+	       "value\0",
+	       g_strdup_printf("%d\0", value));
+  }else{
+    xmlNewProp(node,
+	       AGS_MIDI_EVENT,
+	       "change-mode\0");
+
+    xmlNewProp(node,
+	       "channel\0",
+	       g_strdup_printf("%d\0", channel));
+
+    switch(control){
+    case 120:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "all-sound-off\0");
+      }
+      break;
+    case 121:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "reset-control-all\0");
+	    
+	xmlNewProp(node,
+		   "value\0",
+		   g_strdup_printf("%d\0", value));
+      }
+      break;
+    case 122:
+      {
+	if(value == 0){
+	  xmlNewProp(node,
+		     "mode\0",
+		     "local-control-off\0");
+	}else{
+	  xmlNewProp(node,
+		     "mode\0",
+		     "local-control-on\0");
+	}
+      }
+      break;
+    case 123:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "all-notes-off");
+      }
+      break;
+    case 124:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "omni-mode-on");
+      }
+      break;
+    case 125:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "omni-mode-off\0");
+      }
+      break;
+    case 126:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "mono-mode-on\0");
+
+	xmlNewProp(node,
+		   "omni-off-channels\0",
+		   g_strdup_printf("%d\0", value));
+      }
+      break;
+    case 127:
+      {
+	xmlNewProp(node,
+		   "mode\0",
+		   "poly-mode-on\0");
+      }
+      break;
+    }
+  }
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_change_parameter(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[CHANGE_PARAMETER], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_change_pitch_bend(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, pitch, transmitter;
+
+  channel = 0xf & status;
+  pitch = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  transmitter = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     "channel\0",
+	     g_strdup_printf("%d\0", channel));
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "pitch-bend\0");
+
+  xmlNewProp(node,
+	     "pitch\0",
+	     g_strdup_printf("%d\0", pitch));	  
+
+  xmlNewProp(node,
+	     "transmitter\0",
+	     g_strdup_printf("%d\0", transmitter));	  
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_change_pitch_bend(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[CHANGE_PITCH_BEND], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_change_program(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, program;
+
+  channel = 0xf & status;
+  program = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "program-change\0");
+
+  xmlNewProp(node,
+	     "channel\0",
+	     g_strdup_printf("%d\0", channel));
+
+  xmlNewProp(node,
+	     "program\0",
+	     g_strdup_printf("%d\0", program));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_change_program(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[CHANGE_PROGRAM], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_change_channel_pressure(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int channel, pressure;
+
+  channel = 0xf & status;
+  pressure = 0x7f & ags_midi_parser_midi_getc(midi_parser);
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "channel-pressure\0");
+
+  xmlNewProp(node,
+	     "channel\0",
+	     g_strdup_printf("%d\0", channel));
+
+  xmlNewProp(node,
+	     "pressure\0",
+	     g_strdup_printf("%d\0", pressure));
+  
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_change_channel_pressure(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[CHANGE_CHANNEL_PRESSURE], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_not_defined(AgsMidiParser *midi_parser, guint status)
+{
+  return(NULL);
+}
+
+xmlNode*  
+ags_midi_parser_not_defined(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[NOT_DEFINED], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_sysex(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  gchar c;
+  
+  while((c = ags_midi_parser_midi_getc(midi_parser)) != 0xf7 &&
+	c != EOF);
+
+#ifdef DEBUG
+  g_message("discarded sysex\0");
+#endif
+}
+
+xmlNode*
+ags_midi_parser_sysex(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[SYSEX], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_real_system_common(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  int c;
+
+  node = NULL;
+  
+  switch(status){
+  case 0xf1:
+    {
+      guint quarter_frame;
+      
+      quarter_frame = 0xff & (ags_midi_parser_midi_getc(midi_parser));
+    }
+    break;
+  case 0xf2:
+    {
+      guint song_position;
+      
+      song_position = 0x7f & (ags_midi_parser_midi_getc(midi_parser)) << 7;
+      song_position = 0x7f & (ags_midi_parser_midi_getc(midi_parser));
+    }
+    break;
+  case 0xf3:
+    {
+      guint song_select;
+      
+      song_select = 0x7f & (ags_midi_parser_midi_getc(midi_parser));
+    }
+    break;
+  case 0xf4:
+    {
+#ifdef DEBUG
+      g_message("undefined\0");
+#endif
+    }
+    break;
+  case 0xf5:
+    {
+#ifdef DEBUG
+      g_message("undefined\0");
+#endif
+    }
+    break;
+  case 0xf6:
+    {
+#ifdef DEBUG
+      g_message("tune request\0");
+#endif
+    }
+    break;
+  }
+
+  return(node);
+}
+
+xmlNode*
+ags_midi_parser_system_common(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[SYSTEM_COMMON], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_meta_event(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  char chunk_meta_length[4];
+  guint meta_type;
+  
+  meta_type = 0xff & (ags_midi_parser_midi_getc(midi_parser));
+  midi_parser->offset += 1;
+
+  node = NULL;
+  
+  switch(meta_type){
+  case 0x00:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+
+      if(c == 0x02){
+	node = ags_midi_parser_sequence_number(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x01:      /* Text event */
+  case 0x02:      /* Copyright notice */
+  case 0x03:      /* Sequence/Track name */
+  case 0x04:      /* Instrument name */
+  case 0x05:      /* Lyric */
+  case 0x06:      /* Marker */
+  case 0x07:      /* Cue point */
+  case 0x08:
+  case 0x09:
+  case 0x0a:
+  case 0x0b:
+  case 0x0c:
+  case 0x0d:
+  case 0x0e:
+  case 0x0f:
+    {
+      /* These are all text events */
+      node = ags_midi_parser_text_event(midi_parser, meta_type);
+    }
+    break;
+  case 0x2f:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+
+      if(c == 0x0){
+	/* End of Track */
+	node = ags_midi_parser_end_of_track(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x51:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+
+      if(c == 0x03){
+	/* Set tempo */
+	node = ags_midi_parser_tempo(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x54:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+
+      if(c == 0x05){
+	node = ags_midi_parser_smpte(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x58:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+      
+      if(c == 0x04){
+	node = ags_midi_parser_time_signature(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x59:
+    {
+      int c;
+
+      c = ags_midi_parser_midi_getc(midi_parser);
+
+      if(c == 0x02){
+	node = ags_midi_parser_key_signature(midi_parser, meta_type);
+      }
+    }
+    break;
+  case 0x7f:
+    {
+      node = ags_midi_parser_sequencer_meta_event(midi_parser, meta_type);
+    }
+    break;
+  default:
+    {
+      node = xmlNewNode(NULL,
+			"midi-message\0");
+      xmlNewProp(node,
+		 AGS_MIDI_EVENT,
+		 "misc\0");
+    }
+  }
+	
+#ifdef DEBUG
+  g_message("meta type 0x%x\0", meta_type);
+#endif
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_meta_event(AgsMidiParser *midi_parser, guint status)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[META_EVENT], 0,
+		status,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_sequence_number(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  guint sequence;
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  sequence = (guint) ags_midi_parser_read_gint16(midi_parser);
+  
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "sequence-number\0");
+  
+  xmlNewProp(node,
+	     "sequence\0",
+	     g_strdup_printf("%d\0", sequence));
+    
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_sequence_number(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[SEQUENCE_NUMBER], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_end_of_track(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "end-of-track\0");
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_end_of_track(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[END_OF_TRACK], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_smpte(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  int hr, mn, se, fr, ff;
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  hr = ags_midi_parser_midi_getc(midi_parser);
+  mn = ags_midi_parser_midi_getc(midi_parser);
+  se = ags_midi_parser_midi_getc(midi_parser);
+  fr = ags_midi_parser_midi_getc(midi_parser);
+  ff = ags_midi_parser_midi_getc(midi_parser);
+  
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "smpte\0");
+  
+  xmlNewProp(node,
+	     "timestamp\0",
+	     g_strdup_printf("%d %d %d %d %d\0", hr, mn, se, fr, ff));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_smpte(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[SMPTE], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_tempo(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  gint tempo;
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  tempo = ags_midi_parser_read_gint24(midi_parser);
+  
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "tempo-number\0");
+  
+  xmlNewProp(node,
+	     "tempo\0",
+	     g_strdup_printf("%ld\0", tempo));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_tempo(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[TEMPO], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_time_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  int nn, dd, cc, bb;
+  int denom = 1;
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  nn = ags_midi_parser_midi_getc(midi_parser);
+  dd = ags_midi_parser_midi_getc(midi_parser);
+  cc = ags_midi_parser_midi_getc(midi_parser);
+  bb = ags_midi_parser_midi_getc(midi_parser);
+
+  while(dd-- > 0){
+    denom *= 2;
+  }
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "time-signature\0");
+
+  xmlNewProp(node,
+	     "timesig\0",
+	     g_strdup_printf("%d/%d %d %d\0", nn, denom, cc, bb));
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_time_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[TIME_SIGNATURE], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_key_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  int sf, mi;
+  
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  xmlNewProp(node,
+	     AGS_MIDI_EVENT,
+	     "key-signature\0");
+  
+  sf = ags_midi_parser_midi_getc(midi_parser);
+  mi = ags_midi_parser_midi_getc(midi_parser);
+
+  xmlNewProp(node,
+	     "keysig\0",
+	     g_strdup_printf("%d %s\0", (sf>127?sf-256:sf), (mi?"minor":"major")));
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_key_signature(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[KEY_SIGNATURE], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  guint len, id, data;
+
+  node = NULL;
+
+  len = ags_midi_parser_midi_getc(midi_parser);
+  id = ags_midi_parser_midi_getc(midi_parser);
+  data = ags_midi_parser_midi_getc(midi_parser);
+  
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[META_EVENT], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_real_text_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  gchar *text;
+  guint text_length;
+
+  node = xmlNewNode(NULL,
+		    "midi-message\0");
+
+  text_length = ags_midi_parser_read_varlength(midi_parser);
+  text = ags_midi_parser_read_text(midi_parser,
+				   text_length);
+  
+  switch(0x0f & meta_type){
+  case 0x01:      /* Text event */
+    break;
+  case 0x02:
+    {
+      /* Copyright notice */
+      xmlNewProp(node,
+		 "copyright\0",
+		 text);
+    }
+    break;
+  case 0x03:
+    {
+      /* Sequence/Track name */
+      xmlNewProp(node,
+		 "sequence-name\0",
+		 text);
+    }
+    break;
+  case 0x04:
+    {
+      /* Instrument name */
+      xmlNewProp(node,
+		 "instrument-name\0",
+		 text);
+    }
+    break;
+  case 0x05:      /* Lyric */
+    break;
+  case 0x06:      /* Marker */
+    break;
+  case 0x07:      /* Cue point */
+    break;
+  case 0x08:
+    break;
+  case 0x09:
+    break;
+  case 0x0a:
+    break;
+  case 0x0b:
+    break;
+  case 0x0c:
+    break;
+  case 0x0d:
+    break;
+  case 0x0e:
+    break;
+  case 0x0f:
+    break;
+  default:
+    g_warning("unknown text event\0");
+  }
+    
+  return(node);
+}
+
+xmlNode*  
+ags_midi_parser_text_event(AgsMidiParser *midi_parser, guint meta_type)
+{
+  xmlNode *node;
+  
+  g_return_val_if_fail(AGS_IS_MIDI_PARSER(midi_parser), NULL);
+  
+  g_object_ref((GObject *) midi_parser);
+  g_signal_emit(G_OBJECT(midi_parser),
+		midi_parser_signals[TEXT_EVENT], 0,
+		meta_type,
+		&node);
+  g_object_unref((GObject *) midi_parser);
+
+  return(node);
+}
+
+AgsMidiParser*
+ags_midi_parser_new(FILE *file)
+{
+  AgsMidiParser *midi_parser;
+  struct stat sb;
+  
+  midi_parser = (AgsMidiParser *) g_object_new(AGS_TYPE_MIDI_PARSER,
+					       "file\0", file,
+					       NULL);
+
+  
+  return(midi_parser);
+}
+
diff --git a/src/midi2ags/midi/ags_midi_parser.h b/src/midi2ags/midi/ags_midi_parser.h
new file mode 100644
index 0000000..ed13452
--- /dev/null
+++ b/src/midi2ags/midi/ags_midi_parser.h
@@ -0,0 +1,152 @@
+/* AGS - Advanced GTK Sequencer
+ * Copyright (C) 2015 Joël Krähemann
+ *
+ * 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 3 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __AGS_MIDI_PARSER_H__
+#define __AGS_MIDI_PARSER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libxml/tree.h>
+
+#define AGS_TYPE_MIDI_PARSER                (ags_midi_parser_get_type ())
+#define AGS_MIDI_PARSER(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj), AGS_TYPE_MIDI_PARSER, AgsMidiParser))
+#define AGS_MIDI_PARSER_CLASS(class)        (G_TYPE_CHECK_CLASS_CAST((class), AGS_TYPE_MIDI_PARSER, AgsMidiParserClass))
+#define AGS_IS_MIDI_PARSER(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), AGS_TYPE_MIDI_PARSER))
+#define AGS_IS_MIDI_PARSER_CLASS(class)     (G_TYPE_CHECK_CLASS_TYPE ((class), AGS_TYPE_MIDI_PARSER))
+#define AGS_MIDI_PARSER_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS ((obj), AGS_TYPE_MIDI_PARSER, AgsMidiParserClass))
+
+#define AGS_MIDI_PARSER_MTHD "MThd\0"
+#define AGS_MIDI_PARSER_MTCK "MTrk\0"
+
+typedef struct _AgsMidiParser AgsMidiParser;
+typedef struct _AgsMidiParserClass AgsMidiParserClass;
+
+typedef enum{
+  AGS_MIDI_PARSER_EOF  = 1,
+  AGS_MIDI_PARSER_EOT  = 1 << 1,
+}AgsMidiParserFlags;
+
+typedef enum{
+  AGS_MIDI_CHUNK_HEADER   = 1,
+  AGS_MIDI_CHUNK_TRACK    = 1 << 1,
+  AGS_MIDI_CHUNK_UNKNOWN  = 1 << 2,
+}AgsMidiChunkFlags;
+
+struct _AgsMidiParser
+{
+  GObject gobject;
+
+  guint flags;
+
+  FILE *file;
+  guint nth_chunk;
+
+  size_t file_length;
+  size_t offset;
+
+  guint current_time;
+
+  xmlDoc *doc;
+};
+
+struct _AgsMidiParserClass
+{
+  GObjectClass gobject;
+
+  int (*midi_getc)(AgsMidiParser *midi_parser);
+  void (*on_error)(AgsMidiParser *midi_parser,
+		   GError **error);
+  
+  xmlNode* (*parse_header)(AgsMidiParser *midi_parser);
+  xmlNode* (*parse_track)(AgsMidiParser *midi_parser);
+
+  xmlNode* (*key_on)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*key_off)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*key_pressure)(AgsMidiParser *midi_parser, guint status);
+
+  xmlNode* (*change_parameter)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*change_pitch_bend)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*change_program)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*change_channel_pressure)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*not_defined)(AgsMidiParser *midi_parser, guint status);
+
+  xmlNode* (*sysex)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*system_common)(AgsMidiParser *midi_parser, guint status);
+
+  xmlNode* (*meta_event)(AgsMidiParser *midi_parser, guint status);
+  xmlNode* (*sequence_number)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*end_of_track)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*smpte)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*tempo)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*time_signature)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*key_signature)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*sequencer_meta_event)(AgsMidiParser *midi_parser, guint meta_type);
+  xmlNode* (*text_event)(AgsMidiParser *midi_parser, guint meta_type);
+  
+  xmlDoc* (*parse_full)(AgsMidiParser *midi_parser);
+};
+
+GType ags_midi_parser_get_type(void);
+
+gint16 ags_midi_parser_read_gint16(AgsMidiParser *midi_parser);
+gint32 ags_midi_parser_read_gint24(AgsMidiParser *midi_parser);
+gint32 ags_midi_parser_read_gint32(AgsMidiParser *midi_parser);
+long ags_midi_parser_read_varlength(AgsMidiParser *midi_parser);
+gchar* ags_midi_parser_read_text(AgsMidiParser *midi_parser,
+				 gint length);
+
+gdouble ags_midi_parser_ticks_to_sec(AgsMidiParser *midi_parser,
+				     guint ticks, gint division, guint tempo);
+
+int ags_midi_parser_midi_getc(AgsMidiParser *midi_parser);
+void ags_midi_parser_on_error(AgsMidiParser *midi_parser,
+			      GError **error);
+
+xmlDoc* ags_midi_parser_parse_full(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_parse_header(AgsMidiParser *midi_parser);
+xmlNode* ags_midi_parser_parse_track(AgsMidiParser *midi_parser);
+
+xmlNode* ags_midi_parser_channel_message(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_on(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_off(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_key_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_parameter(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_pitch_bend(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_program(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_change_channel_pressure(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_not_defined(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_sysex(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_system_common(AgsMidiParser *midi_parser, guint status);
+
+xmlNode* ags_midi_parser_meta_event(AgsMidiParser *midi_parser, guint status);
+xmlNode* ags_midi_parser_sequence_number(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_end_of_track(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_smpte(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_tempo(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_time_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_key_signature(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_sequencer_meta_event(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_meta_misc(AgsMidiParser *midi_parser, guint meta_type);
+xmlNode* ags_midi_parser_text_event(AgsMidiParser *midi_parser, guint meta_type);
+
+AgsMidiParser* ags_midi_parser_new(FILE *file);
+
+#endif /*__AGS_MIDI_PARSER_H__*/
diff --git a/src/midi2ags/object/ags_marshal.c b/src/midi2ags/object/ags_marshal.c
new file mode 100644
index 0000000..ab8534a
--- /dev/null
+++ b/src/midi2ags/object/ags_marshal.c
@@ -0,0 +1,164 @@
+
+#include	<glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v)  g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v)     g_value_get_schar (v)
+#define g_marshal_value_peek_uchar(v)    g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v)      g_value_get_int (v)
+#define g_marshal_value_peek_uint(v)     g_value_get_uint (v)
+#define g_marshal_value_peek_long(v)     g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v)    g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v)    g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v)   g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v)     g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v)    g_value_get_flags (v)
+#define g_marshal_value_peek_float(v)    g_value_get_float (v)
+#define g_marshal_value_peek_double(v)   g_value_get_double (v)
+#define g_marshal_value_peek_string(v)   (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v)    g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v)    g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v)  g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v)   g_value_get_object (v)
+#define g_marshal_value_peek_variant(v)  g_value_get_variant (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ *          Do not access GValues directly in your code. Instead, use the
+ *          g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v)  (v)->data[0].v_int
+#define g_marshal_value_peek_char(v)     (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v)    (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v)      (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v)     (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v)   (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v)     (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v)    (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v)    (v)->data[0].v_float
+#define g_marshal_value_peek_double(v)   (v)->data[0].v_double
+#define g_marshal_value_peek_string(v)   (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v)    (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v)  (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
+#define g_marshal_value_peek_variant(v)  (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* INT:VOID (ags_marshallers.list:1) */
+void
+g_cclosure_user_marshal_INT__VOID (GClosure     *closure,
+                                   GValue       *return_value G_GNUC_UNUSED,
+                                   guint         n_param_values,
+                                   const GValue *param_values,
+                                   gpointer      invocation_hint G_GNUC_UNUSED,
+                                   gpointer      marshal_data)
+{
+  typedef gint (*GMarshalFunc_INT__VOID) (gpointer     data1,
+                                          gpointer     data2);
+  register GMarshalFunc_INT__VOID callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gint v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 1);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_INT__VOID) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       data2);
+
+  g_value_set_int (return_value, v_return);
+}
+
+/* POINTER:VOID (ags_marshallers.list:2) */
+void
+g_cclosure_user_marshal_POINTER__VOID (GClosure     *closure,
+                                       GValue       *return_value G_GNUC_UNUSED,
+                                       guint         n_param_values,
+                                       const GValue *param_values,
+                                       gpointer      invocation_hint G_GNUC_UNUSED,
+                                       gpointer      marshal_data)
+{
+  typedef gpointer (*GMarshalFunc_POINTER__VOID) (gpointer     data1,
+                                                  gpointer     data2);
+  register GMarshalFunc_POINTER__VOID callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gpointer v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 1);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_POINTER__VOID) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       data2);
+
+  g_value_set_pointer (return_value, v_return);
+}
+
+/* POINTER:UINT (ags_marshallers.list:3) */
+void
+g_cclosure_user_marshal_POINTER__UINT (GClosure     *closure,
+                                       GValue       *return_value G_GNUC_UNUSED,
+                                       guint         n_param_values,
+                                       const GValue *param_values,
+                                       gpointer      invocation_hint G_GNUC_UNUSED,
+                                       gpointer      marshal_data)
+{
+  typedef gpointer (*GMarshalFunc_POINTER__UINT) (gpointer     data1,
+                                                  guint        arg_1,
+                                                  gpointer     data2);
+  register GMarshalFunc_POINTER__UINT callback;
+  register GCClosure *cc = (GCClosure*) closure;
+  register gpointer data1, data2;
+  gpointer v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+      data1 = closure->data;
+      data2 = g_value_peek_pointer (param_values + 0);
+    }
+  else
+    {
+      data1 = g_value_peek_pointer (param_values + 0);
+      data2 = closure->data;
+    }
+  callback = (GMarshalFunc_POINTER__UINT) (marshal_data ? marshal_data : cc->callback);
+
+  v_return = callback (data1,
+                       g_marshal_value_peek_uint (param_values + 1),
+                       data2);
+
+  g_value_set_pointer (return_value, v_return);
+}
+
diff --git a/src/midi2ags/object/ags_marshal.h b/src/midi2ags/object/ags_marshal.h
new file mode 100644
index 0000000..0043dbc
--- /dev/null
+++ b/src/midi2ags/object/ags_marshal.h
@@ -0,0 +1,36 @@
+
+#ifndef __g_cclosure_user_marshal_MARSHAL_H__
+#define __g_cclosure_user_marshal_MARSHAL_H__
+
+#include	<glib-object.h>
+
+G_BEGIN_DECLS
+
+/* INT:VOID (ags_marshallers.list:1) */
+extern void g_cclosure_user_marshal_INT__VOID (GClosure     *closure,
+                                               GValue       *return_value,
+                                               guint         n_param_values,
+                                               const GValue *param_values,
+                                               gpointer      invocation_hint,
+                                               gpointer      marshal_data);
+
+/* POINTER:VOID (ags_marshallers.list:2) */
+extern void g_cclosure_user_marshal_POINTER__VOID (GClosure     *closure,
+                                                   GValue       *return_value,
+                                                   guint         n_param_values,
+                                                   const GValue *param_values,
+                                                   gpointer      invocation_hint,
+                                                   gpointer      marshal_data);
+
+/* POINTER:UINT (ags_marshallers.list:3) */
+extern void g_cclosure_user_marshal_POINTER__UINT (GClosure     *closure,
+                                                   GValue       *return_value,
+                                                   guint         n_param_values,
+                                                   const GValue *param_values,
+                                                   gpointer      invocation_hint,
+                                                   gpointer      marshal_data);
+
+G_END_DECLS
+
+#endif /* __g_cclosure_user_marshal_MARSHAL_H__ */
+

-- 
gsequencer packaging



More information about the pkg-multimedia-commits mailing list