summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Fugal <hans@fugal.net>2006-08-04 02:18:45 +0000
committerHans Fugal <hans@fugal.net>2006-08-04 02:18:45 +0000
commit79986643c0c904f6574bb5323e2233a43a9e622e (patch)
tree859323dbb096ac1658359881e7d11415b6588caa
parentb0b723445816bc968a6a183c6619fccc61e82859 (diff)
r269@gandalf: fugalh | 2006-08-03 20:18:05 -0600
Trunk merge conflicts resolved git-svn-id: svn://localhost/ardour2/branches/undo@756 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--SConstruct323
-rw-r--r--ardour.dox2
-rw-r--r--gtk2_ardour/SConscript20
-rw-r--r--gtk2_ardour/actions.cc2
-rw-r--r--gtk2_ardour/analysis_window.cc47
-rwxr-xr-xgtk2_ardour/ardev_common.sh5
-rw-r--r--gtk2_ardour/ardour.menus4
-rw-r--r--gtk2_ardour/ardour2_ui.rc9
-rw-r--r--gtk2_ardour/ardour_dialog.h3
-rw-r--r--gtk2_ardour/ardour_ui.cc140
-rw-r--r--gtk2_ardour/ardour_ui.h25
-rw-r--r--gtk2_ardour/ardour_ui2.cc70
-rw-r--r--gtk2_ardour/ardour_ui_dialogs.cc4
-rw-r--r--gtk2_ardour/ardour_ui_ed.cc17
-rw-r--r--gtk2_ardour/audio_clock.h6
-rw-r--r--gtk2_ardour/audio_region_editor.cc (renamed from gtk2_ardour/region_editor.cc)9
-rw-r--r--gtk2_ardour/audio_region_editor.h186
-rw-r--r--gtk2_ardour/audio_region_view.cc1127
-rw-r--r--gtk2_ardour/audio_region_view.h (renamed from gtk2_ardour/regionview.h)116
-rw-r--r--gtk2_ardour/audio_regionview.cc (renamed from gtk2_ardour/regionview.cc)17
-rw-r--r--gtk2_ardour/audio_streamview.cc700
-rw-r--r--gtk2_ardour/audio_streamview.h110
-rw-r--r--gtk2_ardour/audio_time_axis.cc1540
-rw-r--r--gtk2_ardour/audio_time_axis.h245
-rw-r--r--gtk2_ardour/automation_time_axis.cc160
-rw-r--r--gtk2_ardour/automation_time_axis.h17
-rw-r--r--gtk2_ardour/canvas-waveview.h6
-rw-r--r--gtk2_ardour/crossfade_edit.cc6
-rw-r--r--gtk2_ardour/crossfade_view.cc6
-rw-r--r--gtk2_ardour/crossfade_view.h4
-rw-r--r--gtk2_ardour/editing_syms.h1
-rw-r--r--gtk2_ardour/editor.cc569
-rw-r--r--gtk2_ardour/editor.h89
-rw-r--r--gtk2_ardour/editor_actions.cc2
-rw-r--r--gtk2_ardour/editor_audio_import.cc34
-rw-r--r--gtk2_ardour/editor_audiotrack.cc2
-rw-r--r--gtk2_ardour/editor_canvas.cc2
-rw-r--r--gtk2_ardour/editor_canvas_events.cc61
-rw-r--r--gtk2_ardour/editor_export_audio.cc36
-rw-r--r--gtk2_ardour/editor_items.h4
-rw-r--r--gtk2_ardour/editor_keyboard.cc16
-rw-r--r--gtk2_ardour/editor_keys.cc8
-rw-r--r--gtk2_ardour/editor_markers.cc6
-rw-r--r--gtk2_ardour/editor_mixer.cc6
-rw-r--r--gtk2_ardour/editor_mouse.cc413
-rw-r--r--gtk2_ardour/editor_ops.cc342
-rw-r--r--gtk2_ardour/editor_route_list.cc42
-rw-r--r--gtk2_ardour/editor_timefx.cc33
-rw-r--r--gtk2_ardour/export_dialog.cc8
-rw-r--r--gtk2_ardour/export_region_dialog.cc10
-rw-r--r--gtk2_ardour/export_region_dialog.h2
-rw-r--r--gtk2_ardour/fft_graph.cc6
-rw-r--r--gtk2_ardour/fft_graph.h2
-rw-r--r--gtk2_ardour/fft_result.cc6
-rw-r--r--gtk2_ardour/gain_automation_time_axis.cc6
-rw-r--r--gtk2_ardour/gain_automation_time_axis.h2
-rw-r--r--gtk2_ardour/gain_meter.cc59
-rw-r--r--gtk2_ardour/gain_meter.h6
-rw-r--r--gtk2_ardour/io_selector.cc84
-rw-r--r--gtk2_ardour/io_selector.h12
-rw-r--r--gtk2_ardour/keyboard.h2
-rw-r--r--gtk2_ardour/main.cc2
-rw-r--r--gtk2_ardour/mixer_strip.cc192
-rw-r--r--gtk2_ardour/mixer_strip.h17
-rw-r--r--gtk2_ardour/mixer_ui.cc41
-rw-r--r--gtk2_ardour/mixer_ui.h7
-rw-r--r--gtk2_ardour/option_editor.cc18
-rw-r--r--gtk2_ardour/option_editor.h18
-rw-r--r--gtk2_ardour/pan_automation_time_axis.cc73
-rw-r--r--gtk2_ardour/pan_automation_time_axis.h39
-rw-r--r--gtk2_ardour/panner_ui.cc106
-rw-r--r--gtk2_ardour/panner_ui.h6
-rw-r--r--gtk2_ardour/pixmaps/tool_audition.xpm19
-rw-r--r--gtk2_ardour/pixmaps/tool_gain.xpm18
-rw-r--r--gtk2_ardour/pixmaps/tool_object.xpm18
-rw-r--r--gtk2_ardour/pixmaps/tool_range.xpm18
-rw-r--r--gtk2_ardour/pixmaps/tool_stretch.xpm18
-rw-r--r--gtk2_ardour/pixmaps/tool_zoom.xpm29
-rw-r--r--gtk2_ardour/pixmaps/zoom_full.xpm30
-rw-r--r--gtk2_ardour/pixmaps/zoom_in.xpm29
-rw-r--r--gtk2_ardour/pixmaps/zoom_out.xpm29
-rw-r--r--gtk2_ardour/playlist_selector.cc14
-rw-r--r--gtk2_ardour/playlist_selector.h2
-rw-r--r--gtk2_ardour/plugin_selector.cc208
-rw-r--r--gtk2_ardour/plugin_selector.h53
-rw-r--r--gtk2_ardour/plugin_ui.cc98
-rw-r--r--gtk2_ardour/plugin_ui.h18
-rw-r--r--gtk2_ardour/po/SConscript2
-rw-r--r--gtk2_ardour/public_editor.h10
-rw-r--r--gtk2_ardour/redirect_automation_line.cc2
-rw-r--r--gtk2_ardour/redirect_automation_time_axis.cc3
-rw-r--r--gtk2_ardour/redirect_automation_time_axis.h2
-rw-r--r--gtk2_ardour/redirect_box.cc229
-rw-r--r--gtk2_ardour/redirect_box.h57
-rw-r--r--gtk2_ardour/redirect_selection.h3
-rw-r--r--gtk2_ardour/region_editor.h165
-rw-r--r--gtk2_ardour/region_gain_line.cc22
-rw-r--r--gtk2_ardour/region_selection.cc74
-rw-r--r--gtk2_ardour/region_selection.h48
-rw-r--r--gtk2_ardour/region_view.cc494
-rw-r--r--gtk2_ardour/region_view.h140
-rw-r--r--gtk2_ardour/route_params_ui.cc125
-rw-r--r--gtk2_ardour/route_params_ui.h20
-rw-r--r--gtk2_ardour/route_redirect_selection.cc55
-rw-r--r--gtk2_ardour/route_redirect_selection.h18
-rw-r--r--gtk2_ardour/route_selection.h4
-rw-r--r--gtk2_ardour/route_time_axis.cc1601
-rw-r--r--gtk2_ardour/route_time_axis.h256
-rw-r--r--gtk2_ardour/route_ui.cc190
-rw-r--r--gtk2_ardour/route_ui.h39
-rw-r--r--gtk2_ardour/selectable.h2
-rw-r--r--gtk2_ardour/selection.cc97
-rw-r--r--gtk2_ardour/selection.h37
-rw-r--r--gtk2_ardour/selection_templates.h32
-rw-r--r--gtk2_ardour/send_ui.cc14
-rw-r--r--gtk2_ardour/send_ui.h6
-rw-r--r--gtk2_ardour/sfdb_ui.cc16
-rw-r--r--gtk2_ardour/sfdb_ui.h1
-rw-r--r--gtk2_ardour/streamview.cc745
-rw-r--r--gtk2_ardour/streamview.h159
-rw-r--r--gtk2_ardour/tape_region_view.cc (renamed from gtk2_ardour/taperegionview.cc)71
-rw-r--r--gtk2_ardour/tape_region_view.h (renamed from gtk2_ardour/taperegionview.h)8
-rw-r--r--gtk2_ardour/time_axis_view.cc5
-rw-r--r--gtk2_ardour/time_axis_view.h4
-rw-r--r--gtk2_ardour/time_axis_view_item.cc8
-rw-r--r--gtk2_ardour/time_axis_view_item.h7
-rw-r--r--gtk2_ardour/utils.cc6
-rw-r--r--gtk2_ardour/visual_time_axis.cc2
-rw-r--r--gtk2_ardour/visual_time_axis.h4
-rw-r--r--libs/appleutility/AUOutputBL.cpp160
-rw-r--r--libs/appleutility/AUOutputBL.h115
-rw-r--r--libs/appleutility/CAAudioChannelLayout.cpp138
-rw-r--r--libs/appleutility/CAAudioChannelLayout.h162
-rw-r--r--libs/appleutility/CAAudioChannelLayoutObject.cpp199
-rw-r--r--libs/appleutility/CAAudioUnit.cpp1202
-rw-r--r--libs/appleutility/CAAudioUnit.h383
-rw-r--r--libs/appleutility/CACFDictionary.cpp478
-rw-r--r--libs/appleutility/CACFDictionary.h141
-rw-r--r--libs/appleutility/CACFNumber.cpp65
-rw-r--r--libs/appleutility/CACFNumber.h102
-rw-r--r--libs/appleutility/CACFString.cpp106
-rw-r--r--libs/appleutility/CACFString.h156
-rw-r--r--libs/appleutility/CAComponent.cpp257
-rw-r--r--libs/appleutility/CAComponent.h120
-rw-r--r--libs/appleutility/CAComponentDescription.cpp123
-rw-r--r--libs/appleutility/CAComponentDescription.h148
-rw-r--r--libs/appleutility/CAConditionalMacros.h74
-rw-r--r--libs/appleutility/CADebugMacros.cpp84
-rw-r--r--libs/appleutility/CADebugMacros.h414
-rw-r--r--libs/appleutility/CAMath.h64
-rw-r--r--libs/appleutility/CAReferenceCounted.h83
-rw-r--r--libs/appleutility/CAStreamBasicDescription.cpp520
-rw-r--r--libs/appleutility/CAStreamBasicDescription.h224
-rw-r--r--libs/appleutility/SConscript23
-rw-r--r--libs/ardour/SConscript10
-rw-r--r--libs/ardour/ardour/ardour.h6
-rw-r--r--libs/ardour/ardour/audio_diskstream.h279
-rw-r--r--libs/ardour/ardour/audio_library.h9
-rw-r--r--libs/ardour/ardour/audio_track.h121
-rw-r--r--libs/ardour/ardour/audio_unit.h111
-rw-r--r--libs/ardour/ardour/audioengine.h8
-rw-r--r--libs/ardour/ardour/audiofilesource.h10
-rw-r--r--libs/ardour/ardour/audioplaylist.h3
-rw-r--r--libs/ardour/ardour/audioregion.h88
-rw-r--r--libs/ardour/ardour/audiosource.h9
-rw-r--r--libs/ardour/ardour/buffer.h106
-rw-r--r--libs/ardour/ardour/configuration.h5
-rw-r--r--libs/ardour/ardour/connection.h2
-rw-r--r--libs/ardour/ardour/control_protocol_manager.h3
-rw-r--r--libs/ardour/ardour/curve.h2
-rw-r--r--libs/ardour/ardour/data_type.h79
-rw-r--r--libs/ardour/ardour/destructive_filesource.h5
-rw-r--r--libs/ardour/ardour/diskstream.h319
-rw-r--r--libs/ardour/ardour/export.h2
-rw-r--r--libs/ardour/ardour/insert.h17
-rw-r--r--libs/ardour/ardour/io.h80
-rw-r--r--libs/ardour/ardour/ladspa_plugin.h19
-rw-r--r--libs/ardour/ardour/location.h8
-rw-r--r--libs/ardour/ardour/logcurve.h2
-rw-r--r--libs/ardour/ardour/named_selection.h2
-rw-r--r--libs/ardour/ardour/panner.h46
-rw-r--r--libs/ardour/ardour/playlist.h31
-rw-r--r--libs/ardour/ardour/plugin.h63
-rw-r--r--libs/ardour/ardour/plugin_manager.h18
-rw-r--r--libs/ardour/ardour/port.h75
-rw-r--r--libs/ardour/ardour/redirect.h5
-rw-r--r--libs/ardour/ardour/region.h106
-rw-r--r--libs/ardour/ardour/route.h81
-rw-r--r--libs/ardour/ardour/route_group.h7
-rw-r--r--libs/ardour/ardour/route_group_specialized.h6
-rw-r--r--libs/ardour/ardour/send.h10
-rw-r--r--libs/ardour/ardour/session.h166
-rw-r--r--libs/ardour/ardour/session_region.h2
-rw-r--r--libs/ardour/ardour/session_route.h33
-rw-r--r--libs/ardour/ardour/sndfilesource.h4
-rw-r--r--libs/ardour/ardour/source.h7
-rw-r--r--libs/ardour/ardour/tempo.h2
-rw-r--r--libs/ardour/ardour/track.h158
-rw-r--r--libs/ardour/ardour/types.h12
-rw-r--r--libs/ardour/ardour/utils.h10
-rw-r--r--libs/ardour/ardour/vst_plugin.h14
-rw-r--r--libs/ardour/audio_diskstream.cc587
-rw-r--r--libs/ardour/audio_library.cc51
-rw-r--r--libs/ardour/audio_playlist.cc40
-rw-r--r--libs/ardour/audio_track.cc429
-rw-r--r--libs/ardour/audio_unit.cc362
-rw-r--r--libs/ardour/audioengine.cc37
-rw-r--r--libs/ardour/audiofilesource.cc46
-rw-r--r--libs/ardour/audioregion.cc61
-rw-r--r--libs/ardour/audiosource.cc2
-rw-r--r--libs/ardour/auditioner.cc41
-rw-r--r--libs/ardour/automation_event.cc2
-rw-r--r--libs/ardour/configuration.cc4
-rw-r--r--libs/ardour/control_protocol_manager.cc5
-rw-r--r--libs/ardour/coreaudiosource.cc33
-rw-r--r--libs/ardour/crossfade.cc17
-rw-r--r--libs/ardour/destructive_filesource.cc62
-rw-r--r--libs/ardour/diskstream.cc401
-rw-r--r--libs/ardour/globals.cc24
-rw-r--r--libs/ardour/insert.cc94
-rw-r--r--libs/ardour/io.cc284
-rw-r--r--libs/ardour/ladspa_plugin.cc119
-rw-r--r--libs/ardour/location.cc8
-rw-r--r--libs/ardour/mix.cc6
-rw-r--r--libs/ardour/panner.cc257
-rw-r--r--libs/ardour/playlist.cc33
-rw-r--r--libs/ardour/plugin.cc218
-rw-r--r--libs/ardour/plugin_manager.cc104
-rw-r--r--libs/ardour/po/el_GR.po82
-rw-r--r--libs/ardour/po/it_IT.po82
-rw-r--r--libs/ardour/po/ru_RU.po82
-rw-r--r--libs/ardour/port.cc18
-rw-r--r--libs/ardour/redirect.cc28
-rw-r--r--libs/ardour/region.cc47
-rw-r--r--libs/ardour/route.cc383
-rw-r--r--libs/ardour/session.cc512
-rw-r--r--libs/ardour/session_butler.cc51
-rw-r--r--libs/ardour/session_export.cc7
-rw-r--r--libs/ardour/session_midi.cc13
-rw-r--r--libs/ardour/session_process.cc57
-rw-r--r--libs/ardour/session_state.cc157
-rw-r--r--libs/ardour/session_time.cc5
-rw-r--r--libs/ardour/session_transport.cc63
-rw-r--r--libs/ardour/sndfilesource.cc48
-rw-r--r--libs/ardour/source.cc5
-rw-r--r--libs/ardour/track.cc219
-rw-r--r--libs/ardour/utils.cc27
-rw-r--r--libs/ardour/vst_plugin.cc41
-rw-r--r--libs/gtkmm2ext/SConscript10
-rw-r--r--libs/gtkmm2ext/barcontroller.cc103
-rw-r--r--libs/gtkmm2ext/binding_proxy.cc89
-rw-r--r--libs/gtkmm2ext/controller.cc92
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/barcontroller.h23
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/bindable_button.h50
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/binding_proxy.h (renamed from libs/ardour/ardour/session_diskstream.h)48
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/pathlist.h (renamed from libs/gtkmm2ext/gtkmm2ext/controller.h)60
-rw-r--r--libs/gtkmm2ext/gtkmm2ext/slider_controller.h42
-rw-r--r--libs/gtkmm2ext/pathlist.cc124
-rw-r--r--libs/gtkmm2ext/popup.cc14
-rw-r--r--libs/gtkmm2ext/slider_controller.cc116
-rw-r--r--libs/libgnomecanvasmm/SConscript9
-rw-r--r--libs/libsndfile/src/sndfile.c15
-rw-r--r--libs/midi++2/SConscript3
-rw-r--r--libs/midi++2/midi++/channel.h2
-rw-r--r--libs/midi++2/midi++/controllable.h92
-rw-r--r--libs/midi++2/midi++/coremidi_midiport.h2
-rw-r--r--libs/midi++2/midi++/factory.h2
-rw-r--r--libs/midi++2/midi++/fd_midiport.h2
-rw-r--r--libs/midi++2/midi++/fifomidi.h2
-rw-r--r--libs/midi++2/midi++/manager.h2
-rw-r--r--libs/midi++2/midi++/mmc.h4
-rw-r--r--libs/midi++2/midi++/nullmidi.h2
-rw-r--r--libs/midi++2/midi++/parser.h2
-rw-r--r--libs/midi++2/midi++/port.h5
-rw-r--r--libs/midi++2/midi++/port_request.h2
-rw-r--r--libs/midi++2/midi++/types.h4
-rw-r--r--libs/midi++2/midiparser.cc2
-rw-r--r--libs/pbd/.cvsignore (renamed from libs/pbd3/.cvsignore)0
-rw-r--r--libs/pbd/AUTHORS (renamed from libs/pbd3/AUTHORS)0
-rw-r--r--libs/pbd/COPYING (renamed from libs/pbd3/COPYING)0
-rw-r--r--libs/pbd/ChangeLog (renamed from libs/pbd3/ChangeLog)0
-rw-r--r--libs/pbd/NEWS (renamed from libs/pbd3/NEWS)0
-rw-r--r--libs/pbd/README (renamed from libs/pbd3/README)0
-rw-r--r--libs/pbd/SConscript75
-rw-r--r--libs/pbd/base_ui.cc (renamed from libs/pbd3/base_ui.cc)0
-rw-r--r--libs/pbd/basename.cc (renamed from libs/pbd3/basename.cc)0
-rw-r--r--libs/pbd/command.cc (renamed from libs/pbd3/command.cc)0
-rw-r--r--libs/pbd/controllable.cc26
-rw-r--r--libs/pbd/convert.cc (renamed from libs/pbd3/convert.cc)0
-rw-r--r--libs/pbd/dmalloc.cc (renamed from libs/pbd3/dmalloc.cc)0
-rw-r--r--libs/pbd/error.cc (renamed from libs/pbd3/error.cc)0
-rw-r--r--libs/pbd/gettext.h (renamed from libs/pbd3/gettext.h)0
-rw-r--r--libs/pbd/i18n.h (renamed from libs/pbd3/i18n.h)0
-rw-r--r--libs/pbd/id.cc63
-rw-r--r--libs/pbd/libpbd.pc.in (renamed from libs/pbd3/libpbd.pc.in)0
-rw-r--r--libs/pbd/libpbd.spec.in (renamed from libs/pbd3/libpbd.spec.in)0
-rw-r--r--libs/pbd/mountpoint.cc (renamed from libs/pbd3/mountpoint.cc)55
-rw-r--r--libs/pbd/path.cc164
-rw-r--r--libs/pbd/pathscanner.cc (renamed from libs/pbd3/pathscanner.cc)0
-rw-r--r--libs/pbd/pbd/.DS_Store (renamed from libs/pbd3/pbd/.DS_Store)bin6148 -> 6148 bytes
-rw-r--r--libs/pbd/pbd/.cvsignore (renamed from libs/pbd3/pbd/.cvsignore)0
-rw-r--r--libs/pbd/pbd/abstract_ui.cc (renamed from libs/pbd3/pbd/abstract_ui.cc)0
-rw-r--r--libs/pbd/pbd/abstract_ui.h (renamed from libs/pbd3/pbd/abstract_ui.h)0
-rw-r--r--libs/pbd/pbd/base_ui.h (renamed from libs/pbd3/pbd/base_ui.h)0
-rw-r--r--libs/pbd/pbd/basename.h (renamed from libs/pbd3/pbd/basename.h)2
-rw-r--r--libs/pbd/pbd/command.h (renamed from libs/pbd3/pbd/command.h)0
-rw-r--r--libs/pbd/pbd/compose.h (renamed from libs/pbd3/pbd/compose.h)0
-rw-r--r--libs/pbd/pbd/controllable.h46
-rw-r--r--libs/pbd/pbd/convert.h (renamed from libs/pbd3/pbd/convert.h)0
-rw-r--r--libs/pbd/pbd/error.h (renamed from libs/pbd3/pbd/error.h)0
-rw-r--r--libs/pbd/pbd/failed_constructor.h (renamed from libs/pbd3/pbd/failed_constructor.h)0
-rw-r--r--libs/pbd/pbd/fastlog.h (renamed from libs/pbd3/pbd/fastlog.h)0
-rw-r--r--libs/pbd/pbd/forkexec.h (renamed from libs/pbd3/pbd/forkexec.h)0
-rw-r--r--libs/pbd/pbd/id.h47
-rw-r--r--libs/pbd/pbd/mathfix.h (renamed from libs/pbd3/pbd/mathfix.h)0
-rw-r--r--libs/pbd/pbd/memento_command.h (renamed from libs/pbd3/pbd/memento_command.h)0
-rw-r--r--libs/pbd/pbd/mountpoint.h (renamed from libs/pbd3/pbd/mountpoint.h)0
-rw-r--r--libs/pbd/pbd/path.h113
-rw-r--r--libs/pbd/pbd/pathscanner.h (renamed from libs/pbd3/pbd/pathscanner.h)0
-rw-r--r--libs/pbd/pbd/pool.h (renamed from libs/pbd3/pbd/pool.h)0
-rw-r--r--libs/pbd/pbd/pthread_utils.h (renamed from libs/pbd3/pbd/pthread_utils.h)0
-rw-r--r--libs/pbd/pbd/rcu.h120
-rw-r--r--libs/pbd/pbd/receiver.h (renamed from libs/pbd3/pbd/receiver.h)0
-rw-r--r--libs/pbd/pbd/restartable_rw.h (renamed from libs/pbd3/pbd/restartable_rw.h)0
-rw-r--r--libs/pbd/pbd/ringbuffer.h (renamed from libs/pbd3/pbd/ringbuffer.h)0
-rw-r--r--libs/pbd/pbd/ringbufferNPT.h (renamed from libs/pbd3/pbd/ringbufferNPT.h)0
-rw-r--r--libs/pbd/pbd/selectable.h (renamed from libs/pbd3/pbd/selectable.h)0
-rw-r--r--libs/pbd/pbd/serializable.h (renamed from libs/pbd3/pbd/serializable.h)0
-rw-r--r--libs/pbd/pbd/stacktrace.h (renamed from libs/pbd3/pbd/stacktrace.h)0
-rw-r--r--libs/pbd/pbd/stateful.h (renamed from libs/ardour/ardour/stateful.h)8
-rw-r--r--libs/pbd/pbd/stl_delete.h (renamed from libs/pbd3/pbd/stl_delete.h)0
-rw-r--r--libs/pbd/pbd/stl_functors.h (renamed from libs/pbd3/pbd/stl_functors.h)0
-rw-r--r--libs/pbd/pbd/strsplit.h (renamed from libs/pbd3/pbd/strsplit.h)0
-rw-r--r--libs/pbd/pbd/textreceiver.h (renamed from libs/pbd3/pbd/textreceiver.h)0
-rw-r--r--libs/pbd/pbd/thrown_error.h (renamed from libs/pbd3/pbd/thrown_error.h)0
-rw-r--r--libs/pbd/pbd/tokenizer.h49
-rw-r--r--libs/pbd/pbd/touchable.h (renamed from libs/pbd3/pbd/touchable.h)0
-rw-r--r--libs/pbd/pbd/transmitter.h (renamed from libs/pbd3/pbd/transmitter.h)0
-rw-r--r--libs/pbd/pbd/undo.h (renamed from libs/pbd3/pbd/undo.h)0
-rw-r--r--libs/pbd/pbd/whitespace.h (renamed from libs/pbd3/pbd/whitespace.h)0
-rw-r--r--libs/pbd/pbd/xml++.h (renamed from libs/pbd3/pbd/xml++.h)16
-rw-r--r--libs/pbd/pool.cc (renamed from libs/pbd3/pool.cc)2
-rw-r--r--libs/pbd/pthread_utils.cc (renamed from libs/pbd3/pthread_utils.cc)0
-rw-r--r--libs/pbd/receiver.cc (renamed from libs/pbd3/receiver.cc)0
-rw-r--r--libs/pbd/stacktrace.cc (renamed from libs/pbd3/stacktrace.cc)0
-rw-r--r--libs/pbd/stateful.cc (renamed from libs/ardour/stateful.cc)13
-rw-r--r--libs/pbd/strsplit.cc (renamed from libs/pbd3/strsplit.cc)0
-rw-r--r--libs/pbd/textreceiver.cc (renamed from libs/pbd3/textreceiver.cc)0
-rw-r--r--libs/pbd/transmitter.cc (renamed from libs/pbd3/transmitter.cc)0
-rw-r--r--libs/pbd/undo.cc (renamed from libs/pbd3/undo.cc)0
-rw-r--r--libs/pbd/whitespace.cc44
-rw-r--r--libs/pbd/xml++.cc420
-rw-r--r--libs/pbd3/SConscript66
-rw-r--r--libs/pbd3/whitespace.cc30
-rw-r--r--libs/pbd3/xml++.cc422
-rw-r--r--libs/soundtouch/STTypes.h2
-rw-r--r--libs/surfaces/control_protocol/SConscript2
-rw-r--r--libs/surfaces/control_protocol/control_protocol.cc51
-rw-r--r--libs/surfaces/control_protocol/control_protocol/control_protocol.h9
-rw-r--r--libs/surfaces/generic_midi/SConscript3
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.cc218
-rw-r--r--libs/surfaces/generic_midi/generic_midi_control_protocol.h44
-rw-r--r--libs/surfaces/generic_midi/interface.cc10
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.cc (renamed from libs/midi++2/midicontrollable.cc)194
-rw-r--r--libs/surfaces/generic_midi/midicontrollable.h97
-rw-r--r--libs/surfaces/tranzport/SConscript2
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.cc16
-rw-r--r--libs/surfaces/tranzport/tranzport_control_protocol.h3
-rw-r--r--tools/.cvsignore3
-rwxr-xr-xtools/config.guess696
-rw-r--r--tools/osx_packaging/ardour2_mac_ui.rc1225
-rw-r--r--vst/SConscript6
372 files changed, 20725 insertions, 10216 deletions
diff --git a/SConstruct b/SConstruct
index 1dd250edfb..e93aad96a8 100644
--- a/SConstruct
+++ b/SConstruct
@@ -31,6 +31,7 @@ opts.AddOptions(
PathOption('DESTDIR', 'Set the intermediate install "prefix"', '/'),
EnumOption('DIST_TARGET', 'Build target for cross compiling packagers', 'auto', allowed_values=('auto', 'i386', 'i686', 'x86_64', 'powerpc', 'tiger', 'panther', 'none' ), ignorecase=2),
BoolOption('DMALLOC', 'Compile and link using the dmalloc library', 0),
+ BoolOption('EXTRA_WARN', 'Compile with -Wextra, -ansi, and -pedantic. Might break compilation. For pedants', 0),
BoolOption('FFT_ANALYSIS', 'Include FFT analysis window', 0),
BoolOption('FPU_OPTIMIZATION', 'Build runtime checked assembler code', 1),
BoolOption('LIBLO', 'Compile with support for liblo library', 1),
@@ -50,18 +51,25 @@ opts.AddOptions(
class LibraryInfo(Environment):
def __init__(self,*args,**kw):
Environment.__init__ (self,*args,**kw)
-
+
def Merge (self,others):
for other in others:
self.Append (LIBS = other.get ('LIBS',[]))
- self.Append (LIBPATH = other.get ('LIBPATH', []))
+ self.Append (LIBPATH = other.get ('LIBPATH', []))
self.Append (CPPPATH = other.get('CPPPATH', []))
self.Append (LINKFLAGS = other.get('LINKFLAGS', []))
self.Replace(LIBPATH = list(Set(self.get('LIBPATH', []))))
self.Replace(CPPPATH = list(Set(self.get('CPPPATH',[]))))
#doing LINKFLAGS breaks -framework
#doing LIBS break link order dependency
-
+
+ def ENV_update(self, src_ENV):
+ for k in src_ENV.keys():
+ if k in self['ENV'].keys() and k in [ 'PATH', 'LD_LIBRARY_PATH',
+ 'LIB', 'INCLUDE' ]:
+ self['ENV'][k]=SCons.Util.AppendPath(self['ENV'][k], src_ENV[k])
+ else:
+ self['ENV'][k]=src_ENV[k]
env = LibraryInfo (options = opts,
CPPPATH = [ '.' ],
@@ -72,68 +80,69 @@ env = LibraryInfo (options = opts,
DISTCHECKDIR = '#ardour-' + version + '/check'
)
+env.ENV_update(os.environ)
#----------------------------------------------------------------------
# Builders
#----------------------------------------------------------------------
# Handy subst-in-file builder
-#
+#
def do_subst_in_file(targetfile, sourcefile, dict):
- """Replace all instances of the keys of dict with their values.
- For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
- then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
- """
- try:
- f = open(sourcefile, 'rb')
- contents = f.read()
- f.close()
- except:
- raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
- for (k,v) in dict.items():
- contents = re.sub(k, v, contents)
- try:
- f = open(targetfile, 'wb')
- f.write(contents)
- f.close()
- except:
- raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
- return 0 # success
-
+ """Replace all instances of the keys of dict with their values.
+ For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
+ then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
+ """
+ try:
+ f = open(sourcefile, 'rb')
+ contents = f.read()
+ f.close()
+ except:
+ raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
+ for (k,v) in dict.items():
+ contents = re.sub(k, v, contents)
+ try:
+ f = open(targetfile, 'wb')
+ f.write(contents)
+ f.close()
+ except:
+ raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
+ return 0 # success
+
def subst_in_file(target, source, env):
- if not env.has_key('SUBST_DICT'):
- raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
- d = dict(env['SUBST_DICT']) # copy it
- for (k,v) in d.items():
- if callable(v):
- d[k] = env.subst(v())
- elif SCons.Util.is_String(v):
- d[k]=env.subst(v)
- else:
- raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
- for (t,s) in zip(target, source):
- return do_subst_in_file(str(t), str(s), d)
-
+ if not env.has_key('SUBST_DICT'):
+ raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
+ d = dict(env['SUBST_DICT']) # copy it
+ for (k,v) in d.items():
+ if callable(v):
+ d[k] = env.subst(v())
+ elif SCons.Util.is_String(v):
+ d[k]=env.subst(v)
+ else:
+ raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
+ for (t,s) in zip(target, source):
+ return do_subst_in_file(str(t), str(s), d)
+
def subst_in_file_string(target, source, env):
- """This is what gets printed on the console."""
- return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
- for (t,s) in zip(target, source)])
-
+ """This is what gets printed on the console."""
+ return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
+ for (t,s) in zip(target, source)])
+
def subst_emitter(target, source, env):
- """Add dependency from substituted SUBST_DICT to target.
- Returns original target, source tuple unchanged.
- """
- d = env['SUBST_DICT'].copy() # copy it
- for (k,v) in d.items():
- if callable(v):
- d[k] = env.subst(v())
- elif SCons.Util.is_String(v):
- d[k]=env.subst(v)
- Depends(target, SCons.Node.Python.Value(d))
- # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
- return target, source
-
+ """Add dependency from substituted SUBST_DICT to target.
+ Returns original target, source tuple unchanged.
+ """
+ d = env['SUBST_DICT'].copy() # copy it
+ for (k,v) in d.items():
+ if callable(v):
+ d[k] = env.subst(v())
+ elif SCons.Util.is_String(v):
+ d[k]=env.subst(v)
+ Depends(target, SCons.Node.Python.Value(d))
+ # Depends(target, source) # this doesn't help the install-sapphire-linux.sh problem
+ return target, source
+
subst_action = Action (subst_in_file, subst_in_file_string)
env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
@@ -141,31 +150,31 @@ env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emit
# internationalization
#
-# po_helper
+# po_builder: builder function to copy po files to the parent directory while updating them
#
-# this is not a builder. we can't list the .po files as a target,
-# because then scons -c will remove them (even Precious doesn't alter
-# this). this function is called whenever a .mo file is being
-# built, and will conditionally update the .po file if necessary.
+# first source: .po file
+# second source: .pot file
#
-def po_helper(po,pot):
+def po_builder(target,source,env):
+ os.spawnvp (os.P_WAIT, 'cp', ['cp', str(source[0]), str(target[0])])
args = [ 'msgmerge',
'--update',
- po,
- pot,
+ str(target[0]),
+ str(source[1])
]
- print 'Updating ' + po
+ print 'Updating ' + str(target[0])
return os.spawnvp (os.P_WAIT, 'msgmerge', args)
+po_bld = Builder (action = po_builder)
+env.Append(BUILDERS = {'PoBuild' : po_bld})
+
# mo_builder: builder function for (binary) message catalogs (.mo)
#
# first source: .po file
-# second source: .pot file
#
def mo_builder(target,source,env):
- po_helper (source[0].get_path(), source[1].get_path())
args = [ 'msgfmt',
'-c',
'-o',
@@ -183,15 +192,15 @@ env.Append(BUILDERS = {'MoBuild' : mo_bld})
#
def pot_builder(target,source,env):
- args = [ 'xgettext',
+ args = [ 'xgettext',
'--keyword=_',
'--keyword=N_',
'--from-code=UTF-8',
- '-o', target[0].get_path(),
+ '-o', target[0].get_path(),
"--default-domain=" + env['PACKAGE'],
'--copyright-holder="Paul Davis"' ]
args += [ src.get_path() for src in source ]
-
+
return os.spawnvp (os.P_WAIT, 'xgettext', args)
pot_bld = Builder (action = pot_builder)
@@ -204,33 +213,33 @@ env.Append(BUILDERS = {'PotBuild' : pot_bld})
def i18n (buildenv, sources, installenv):
domain = buildenv['PACKAGE']
potfile = buildenv['POTFILE']
-
+
installenv.Alias ('potupdate', buildenv.PotBuild (potfile, sources))
-
+
p_oze = [ os.path.basename (po) for po in glob.glob ('po/*.po') ]
languages = [ po.replace ('.po', '') for po in p_oze ]
- m_oze = [ po.replace (".po", ".mo") for po in p_oze ]
- for mo in m_oze[:]:
- po = 'po/' + mo.replace (".mo", ".po")
- installenv.Alias ('install', buildenv.MoBuild (mo, [ po, potfile ]))
-
- for lang in languages[:]:
+ for po_file in p_oze:
+ buildenv.PoBuild(po_file, ['po/'+po_file, potfile])
+ mo_file = po_file.replace (".po", ".mo")
+ installenv.Alias ('install', buildenv.MoBuild (mo_file, po_file))
+
+ for lang in languages:
modir = (os.path.join (install_prefix, 'share/locale/' + lang + '/LC_MESSAGES/'))
moname = domain + '.mo'
installenv.Alias('install', installenv.InstallAs (os.path.join (modir, moname), lang + '.mo'))
#
# A generic builder for version.cc files
-#
+#
# note: requires that DOMAIN, MAJOR, MINOR, MICRO are set in the construction environment
# note: assumes one source files, the header that declares the version variables
-#
+#
def version_builder (target, source, env):
text = "int " + env['DOMAIN'] + "_major_version = " + str (env['MAJOR']) + ";\n"
text += "int " + env['DOMAIN'] + "_minor_version = " + str (env['MINOR']) + ";\n"
text += "int " + env['DOMAIN'] + "_micro_version = " + str (env['MICRO']) + ";\n"
-
+
try:
o = file (target[0].get_path(), 'w')
o.write (text)
@@ -238,14 +247,14 @@ def version_builder (target, source, env):
except IOError:
print "Could not open", target[0].get_path(), " for writing\n"
sys.exit (-1)
-
+
text = "#ifndef __" + env['DOMAIN'] + "_version_h__\n"
text += "#define __" + env['DOMAIN'] + "_version_h__\n"
text += "extern int " + env['DOMAIN'] + "_major_version;\n"
text += "extern int " + env['DOMAIN'] + "_minor_version;\n"
text += "extern int " + env['DOMAIN'] + "_micro_version;\n"
text += "#endif /* __" + env['DOMAIN'] + "_version_h__ */\n"
-
+
try:
o = file (target[1].get_path(), 'w')
o.write (text)
@@ -253,7 +262,7 @@ def version_builder (target, source, env):
except IOError:
print "Could not open", target[1].get_path(), " for writing\n"
sys.exit (-1)
-
+
return None
version_bld = Builder (action = version_builder)
@@ -276,8 +285,8 @@ def versioned_builder(target,source,env):
except IOError:
print "Could not CVS/Entries for reading"
return -1
-
- last_date = ""
+
+ last_date = ""
lines = o.readlines()
for line in lines:
if line[0:12] == '/SConscript/':
@@ -285,20 +294,20 @@ def versioned_builder(target,source,env):
last_date = parts[3]
break
o.close ()
-
+
if last_date == "":
print "No SConscript CVS update info found - versioned executable cannot be built"
return -1
-
+
tag = time.strftime ('%Y%M%d%H%m', time.strptime (last_date))
print "The current build ID is " + tag
-
+
tagged_executable = source[0].get_path() + '-' + tag
-
+
if os.path.exists (tagged_executable):
print "Replacing existing executable with the same build tag."
os.unlink (tagged_executable)
-
+
return os.link (source[0].get_path(), tagged_executable)
verbuild = Builder (action = versioned_builder)
@@ -310,13 +319,13 @@ env.Append (BUILDERS = {'VersionedExecutable' : verbuild})
def distcopy (target, source, env):
treedir = str (target[0])
-
+
try:
os.mkdir (treedir)
except OSError, (errnum, strerror):
if errnum != errno.EEXIST:
print 'mkdir ', treedir, ':', strerror
-
+
cmd = 'tar cf - '
#
# we don't know what characters might be in the file names
@@ -328,7 +337,7 @@ def distcopy (target, source, env):
p = os.popen (cmd)
return p.close ()
-def tarballer (target, source, env):
+def tarballer (target, source, env):
cmd = 'tar -jcf ' + str (target[0]) + ' ' + str(source[0]) + " --exclude '*~'"
print 'running ', cmd, ' ... '
p = os.popen (cmd)
@@ -359,7 +368,7 @@ if env['VST']:
env['VST'] = 0;
else:
print "OK, VST support will be enabled"
-
+
# ----------------------------------------------------------------------
# Construction environment setup
@@ -381,7 +390,7 @@ libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
libraries['samplerate'] = LibraryInfo()
libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
-if env['FFT_ANALYSIS']:
+if env['FFT_ANALYSIS']:
libraries['fftw3f'] = LibraryInfo()
libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
@@ -420,9 +429,8 @@ libraries['ardour_cp'] = LibraryInfo (LIBS='ardour_cp', LIBPATH='#libs/surfaces/
libraries['ardour'] = LibraryInfo (LIBS='ardour', LIBPATH='#libs/ardour', CPPPATH='#libs/ardour')
libraries['midi++2'] = LibraryInfo (LIBS='midi++', LIBPATH='#libs/midi++2', CPPPATH='#libs/midi++2')
-libraries['pbd3'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd3', CPPPATH='#libs/pbd3')
+libraries['pbd'] = LibraryInfo (LIBS='pbd', LIBPATH='#libs/pbd', CPPPATH='#libs/pbd')
libraries['gtkmm2ext'] = LibraryInfo (LIBS='gtkmm2ext', LIBPATH='#libs/gtkmm2ext', CPPPATH='#libs/gtkmm2ext')
-#libraries['cassowary'] = LibraryInfo(LIBS='cassowary', LIBPATH='#libs/cassowary', CPPPATH='#libs/cassowary')
#
# Check for libusb
@@ -434,7 +442,7 @@ if conf.CheckLib ('usb', 'usb_interrupt_write'):
have_libusb = True
else:
have_libusb = False
-
+
libraries['usb'] = conf.Finish ()
#
@@ -443,7 +451,7 @@ libraries['usb'] = conf.Finish ()
libraries['flac'] = LibraryInfo ()
conf = Configure (libraries['flac'])
-conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new')
+conf.CheckLib ('FLAC', 'FLAC__stream_decoder_new', language='CXX')
libraries['flac'] = conf.Finish ()
#
@@ -451,7 +459,7 @@ libraries['flac'] = conf.Finish ()
if env['LIBLO']:
libraries['lo'] = LibraryInfo ()
-
+
conf = Configure (libraries['lo'])
if conf.CheckLib ('lo', 'lo_server_new') == False:
print "liblo does not appear to be installed."
@@ -473,14 +481,14 @@ if conf.CheckLib ('dmallocth', 'dmalloc_shutdown'):
have_libdmalloc = True
else:
have_libdmalloc = False
-
+
libraries['dmalloc'] = conf.Finish ()
#
#
# Audio/MIDI library (needed for MIDI, since audio is all handled via JACK)
-#
+#
conf = Configure(env)
@@ -498,11 +506,11 @@ elif conf.CheckCHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/Co
else:
print "It appears you don't have the required MIDI libraries installed."
sys.exit (1)
-
+
env = conf.Finish()
if env['SYSLIBS']:
-
+
libraries['sigc2'] = LibraryInfo()
libraries['sigc2'].ParseConfig('pkg-config --cflags --libs sigc++-2.0')
libraries['glibmm2'] = LibraryInfo()
@@ -521,7 +529,7 @@ if env['SYSLIBS']:
#
# cannot use system one for the time being
#
-
+
libraries['sndfile'] = LibraryInfo(LIBS='libsndfile',
LIBPATH='#libs/libsndfile',
CPPPATH=['#libs/libsndfile', '#libs/libsndfile/src'])
@@ -531,22 +539,29 @@ if env['SYSLIBS']:
# libraries['flowcanvas'] = LibraryInfo(LIBS='flowcanvas', LIBPATH='#/libs/flowcanvas', CPPPATH='#libs/flowcanvas')
libraries['soundtouch'] = LibraryInfo()
- libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs soundtouch-1.0')
+ libraries['soundtouch'].ParseConfig ('pkg-config --cflags --libs libSoundTouch')
+ libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
+ LIBPATH='#libs/appleutility',
+ CPPPATH='#libs/appleutility')
+
coredirs = [
'templates'
]
-
+
subdirs = [
'libs/libsndfile',
- 'libs/pbd3',
+ 'libs/pbd',
'libs/midi++2',
'libs/ardour'
]
-
+
if env['VST']:
subdirs = ['libs/fst'] + subdirs + ['vst']
+ if env['COREAUDIO']:
+ subdirs = subdirs + ['libs/appleutility']
+
gtk_subdirs = [
# 'libs/flowcanvas',
'libs/gtkmm2ext',
@@ -575,7 +590,7 @@ else:
libraries['libgnomecanvasmm'] = LibraryInfo(LIBS='libgnomecanvasmm',
LIBPATH='#libs/libgnomecanvasmm',
CPPPATH='#libs/libgnomecanvasmm')
-
+
libraries['soundtouch'] = LibraryInfo(LIBS='soundtouch',
LIBPATH='#libs/soundtouch',
CPPPATH=['#libs', '#libs/soundtouch'])
@@ -585,24 +600,29 @@ else:
# libraries['libglademm'] = LibraryInfo(LIBS='libglademm',
# LIBPATH='#libs/libglademm',
# CPPPATH='#libs/libglademm')
+ libraries['appleutility'] = LibraryInfo(LIBS='libappleutility',
+ LIBPATH='#libs/appleutility',
+ CPPPATH='#libs/appleutility')
coredirs = [
'libs/soundtouch',
'templates'
]
-
+
subdirs = [
-# 'libs/cassowary',
'libs/sigc++2',
'libs/libsndfile',
- 'libs/pbd3',
+ 'libs/pbd',
'libs/midi++2',
'libs/ardour'
]
-
+
if env['VST']:
subdirs = ['libs/fst'] + subdirs + ['vst']
+ if env['COREAUDIO']:
+ subdirs = subdirs + ['libs/appleutility']
+
gtk_subdirs = [
'libs/glibmm2',
'libs/gtkmm2/pango',
@@ -627,7 +647,7 @@ if env['SURFACES']:
surface_subdirs += [ 'libs/surfaces/tranzport' ]
if os.access ('libs/surfaces/sony9pin', os.F_OK):
surface_subdirs += [ 'libs/surfaces/sony9pin' ]
-
+
opts.Save('scache.conf', env)
Help(opts.GenerateHelpText(env))
@@ -646,7 +666,7 @@ if os.environ.has_key('CXX'):
if os.environ.has_key('DISTCC_HOSTS'):
env['ENV']['DISTCC_HOSTS'] = os.environ['DISTCC_HOSTS']
env['ENV']['HOME'] = os.environ['HOME']
-
+
final_prefix = '$PREFIX'
install_prefix = '$DESTDIR/$PREFIX'
@@ -670,7 +690,7 @@ if have_cxx[0] != 1:
exit (1)
else:
print "Congratulations, you have a functioning C++ compiler."
-
+
env = conf.Finish()
#
@@ -724,37 +744,37 @@ if config[config_cpu] == 'powerpc' and env['DIST_TARGET'] != 'none':
if config[config_arch] == 'apple':
opt_flags.extend ([ "-mcpu=7450", "-faltivec"])
else:
- opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
+ opt_flags.extend ([ "-mcpu=7400", "-maltivec", "-mabi=altivec"])
else:
opt_flags.extend([ "-mcpu=750", "-mmultiple" ])
opt_flags.extend (["-mhard-float", "-mpowerpc-gfxopt"])
elif ((re.search ("i[0-9]86", config[config_cpu]) != None) or (re.search ("x86_64", config[config_cpu]) != None)) and env['DIST_TARGET'] != 'none':
-
+
build_host_supports_sse = 0
debug_flags.append ("-DARCH_X86")
opt_flags.append ("-DARCH_X86")
-
+
if config[config_kernel] == 'linux' :
-
- if env['DIST_TARGET'] != 'i386':
-
+
+ if env['DIST_TARGET'] != 'i386':
+
flag_line = os.popen ("cat /proc/cpuinfo | grep '^flags'").read()[:-1]
x86_flags = flag_line.split (": ")[1:][0].split (' ')
-
+
if "mmx" in x86_flags:
opt_flags.append ("-mmmx")
if "sse" in x86_flags:
build_host_supports_sse = 1
if "3dnow" in x86_flags:
opt_flags.append ("-m3dnow")
-
+
if config[config_cpu] == "i586":
opt_flags.append ("-march=i586")
elif config[config_cpu] == "i686":
opt_flags.append ("-march=i686")
-
+
if ((env['DIST_TARGET'] == 'i686') or (env['DIST_TARGET'] == 'x86_64')) and build_host_supports_sse:
opt_flags.extend (["-msse", "-mfpmath=sse"])
debug_flags.extend (["-msse", "-mfpmath=sse"])
@@ -783,7 +803,7 @@ env.Append(CONFIG_ARCH=config[config_arch])
#
-# ARCH="..." overrides all
+# ARCH="..." overrides all
#
if env['ARCH'] != '':
@@ -812,6 +832,10 @@ else:
env.Append(CCFLAGS="-Wall")
env.Append(CXXFLAGS="-Woverloaded-virtual")
+if env['EXTRA_WARN']:
+ env.Append(CCFLAGS="-Wextra -pedantic")
+ env.Append(CXXFLAGS="-ansi")
+
if env['LIBLO']:
env.Append(CCFLAGS="-DHAVE_LIBLO")
@@ -822,34 +846,47 @@ if env['LIBLO']:
env.Merge ([ libraries['core'] ])
#
-# i18n support
+# fix scons nitpickiness on APPLE
#
-conf = Configure (env)
+if env['DIST_TARGET'] == 'panther' or env['DIST_TARGET'] == 'tiger':
+ env.Append(CCFLAGS="-I/opt/local/include", LINKFLAGS="-L/opt/local/lib")
+#
+# i18n support
+#
+
+conf = Configure (env)
if env['NLS']:
+ nls_error = 'This system is not configured for internationalized applications. An english-only version will be built:'
print 'Checking for internationalization support ...'
have_gettext = conf.TryAction(Action('xgettext --version'))
if have_gettext[0] != 1:
- print 'This system is not configured for internationalized applications (no xgettext command). An english-only version will be built\n'
+ nls_error += ' No xgettext command.'
env['NLS'] = 0
-
- if conf.CheckCHeader('libintl.h') == None:
- print 'This system is not configured for internationalized applications (no libintl.h). An english-only version will be built\n'
- env['NLS'] = 0
-
- have_intltool = conf.TryAction(Action('intltool-update --version'))
- if have_intltool[0] != 1:
- print 'This system is not configured for internationalized applications (no intltool-update command). An english-only version will be built\n'
+ else:
+ print "Found xgettext"
+
+ have_msgmerge = conf.TryAction(Action('msgmerge --version'))
+ if have_msgmerge[0] != 1:
+ nls_error += ' No msgmerge command.'
env['NLS'] = 0
+ else:
+ print "Found msgmerge"
-
+ if not conf.CheckCHeader('libintl.h'):
+ nls_error += ' No libintl.h.'
+ env['NLS'] = 0
+
+ if env['NLS'] == 0:
+ print nls_error
+ else:
+ print "International version will be built."
env = conf.Finish()
if env['NLS'] == 1:
env.Append(CCFLAGS="-DENABLE_NLS")
-
Export('env install_prefix final_prefix config_prefix final_config_prefix libraries i18n version subst_dict')
#
@@ -903,18 +940,18 @@ env.Distribute (env['DISTTREE'],
glob.glob ('DOCUMENTATION/FAQ*') +
glob.glob ('DOCUMENTATION/README*')
)
-
+
srcdist = env.Tarball(env['TARBALL'], env['DISTTREE'])
env.Alias ('srctar', srcdist)
#
-# don't leave the distree around
+# don't leave the distree around
#
env.AddPreAction (env['DISTTREE'], Action ('rm -rf ' + str (File (env['DISTTREE']))))
env.AddPostAction (srcdist, Action ('rm -rf ' + str (File (env['DISTTREE']))))
#
# the subdirs
-#
+#
for subdir in coredirs:
SConscript (subdir + '/SConscript')
@@ -922,7 +959,7 @@ for subdir in coredirs:
for sublistdir in [ subdirs, gtk_subdirs, surface_subdirs ]:
for subdir in sublistdir:
SConscript (subdir + '/SConscript')
-
+
# cleanup
env.Clean ('scrub', [ 'scache.conf', '.sconf_temp', '.sconsign.dblite', 'config.log'])
diff --git a/ardour.dox b/ardour.dox
index 8bd87d6fa3..a72ecbc588 100644
--- a/ardour.dox
+++ b/ardour.dox
@@ -459,7 +459,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = libs/pbd3 libs/midi++2 libs/ardour libs/gtkmm2ext gtk2_ardour
+INPUT = libs/pbd libs/midi++2 libs/ardour libs/gtkmm2ext gtk2_ardour
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index 65f8dfca73..d004c9c4c6 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -27,7 +27,7 @@ gtkardour.Merge ([
libraries['ardour_cp'],
libraries['gtkmm2ext'],
libraries['midi++2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['gtkmm2'],
libraries['glib2'],
libraries['libgnomecanvas2'],
@@ -57,6 +57,10 @@ if gtkardour['FFT_ANALYSIS']:
gtkardour.Merge ([libraries['fftw3f']])
gtkardour.Append(CCFLAGS='-DFFT_ANALYSIS')
+if gtkardour['COREAUDIO']:
+ gtkardour.Append(CCFLAGS='-DHAVE_COREAUDIO')
+ gtkardour.Merge([libraries['appleutility']])
+
skipped_files=Split("""
connection_editor.cc
""")
@@ -75,6 +79,7 @@ ardour_ui_ed.cc
ardour_ui_mixer.cc
ardour_ui_options.cc
audio_clock.cc
+route_time_axis.cc
audio_time_axis.cc
automation_gain_line.cc
automation_line.cc
@@ -141,8 +146,6 @@ marker.cc
marker_time_axis.cc
marker_time_axis_view.cc
marker_view.cc
-meter_bridge.cc
-meter_bridge_strip.cc
mixer_strip.cc
mixer_ui.cc
new_session_dialog.cc
@@ -159,10 +162,11 @@ public_editor.cc
redirect_automation_line.cc
redirect_automation_time_axis.cc
redirect_box.cc
-region_editor.cc
+audio_region_editor.cc
region_gain_line.cc
region_selection.cc
-regionview.cc
+region_view.cc
+audio_region_view.cc
route_params_ui.cc
route_redirect_selection.cc
route_ui.cc
@@ -170,7 +174,8 @@ selection.cc
sfdb_ui.cc
send_ui.cc
streamview.cc
-taperegionview.cc
+audio_streamview.cc
+tape_region_view.cc
tempo_dialog.cc
time_axis_view.cc
time_axis_view_item.cc
@@ -255,8 +260,7 @@ else:
env.Alias('install', env.InstallAs(os.path.join(install_prefix, 'bin')+'/ardour2', ardoursh))
if env['NLS']:
- Export('gtkardour', 'intl_files')
- SConscript ('po/SConscript')
+ i18n (gtkardour, gtkardour_files+skipped_files+fft_analysis_files, env)
# configuration files
env.Alias('install', env.Install(os.path.join(config_prefix, 'ardour2'), 'ardour2_ui.rc'))
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc
index ee688c3660..2197d4dc00 100644
--- a/gtk2_ardour/actions.cc
+++ b/gtk2_ardour/actions.cc
@@ -19,7 +19,7 @@
*/
#include <vector>
-#include <string.h>
+#include <string>
#include <gtk/gtkaccelmap.h>
#include <gtk/gtkuimanager.h>
diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc
index b8318f45fe..f742afd727 100644
--- a/gtk2_ardour/analysis_window.cc
+++ b/gtk2_ardour/analysis_window.cc
@@ -26,7 +26,7 @@
#include <gtkmm/treeiter.h>
#include <ardour/audioregion.h>
-#include <ardour/playlist.h>
+#include <ardour/audioplaylist.h>
#include <ardour/types.h>
#include "analysis_window.h"
@@ -35,7 +35,7 @@
#include "time_axis_view.h"
#include "public_editor.h"
#include "selection.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "i18n.h"
@@ -45,16 +45,15 @@ using namespace PBD;
AnalysisWindow::AnalysisWindow()
: ArdourDialog(_("analysis window")),
- fft_graph (2048),
-
source_selection_label (_("Signal source")),
source_selection_ranges_rb (_("Selected ranges")),
source_selection_regions_rb (_("Selected regions")),
-
+
display_model_label (_("Display model")),
display_model_composite_separate_rb (_("Composite graphs for each track")),
- display_model_composite_all_tracks_rb (_("Composite graph of all tracks"))
+ display_model_composite_all_tracks_rb (_("Composite graph of all tracks")),
+ fft_graph (2048)
{
track_list_ready = false;
@@ -226,18 +225,23 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
Selection s = PublicEditor::instance().get_selection();
TimeSelection ts = s.time;
- AudioRegionSelection ars = s.audio_regions;
+ RegionSelection ars = s.regions;
for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
- ARDOUR::Playlist *pl = (*i)->playlist();
+ ARDOUR::AudioPlaylist *pl
+ = dynamic_cast<ARDOUR::AudioPlaylist*>((*i)->playlist());
+
+ if (!pl)
+ continue;
+
RouteUI *rui = dynamic_cast<RouteUI *>(*i);
// Busses don't have playlists, so we need to check that we actually are working with a playlist
if (!pl || !rui)
continue;
- FFTResult *res = fft_graph.prepareResult(*&rui->color(), *&rui->route().name());
+ FFTResult *res = fft_graph.prepareResult(rui->color(), rui->route()->name());
// if timeSelection
if (source_selection_ranges_rb.get_active()) {
@@ -275,24 +279,29 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
TimeAxisView *current_axis = (*i);
- for (std::set<AudioRegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
+ for (std::set<RegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
+ // Check that the region is actually audio (so we can analyze it)
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*j);
+ if (!arv)
+ continue;
+
// Check that the region really is selected on _this_ track/solo
- if ( &(*j)->get_time_axis_view() != current_axis)
+ if ( &arv->get_time_axis_view() != current_axis)
continue;
-// cerr << " - " << (*j)->region.name() << ": " << (*j)->region.length() << " samples starting at " << (*j)->region.position() << endl;
+// cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
jack_nframes_t i = 0;
int n;
- while ( i < (*j)->region.length() ) {
+ while ( i < arv->region().length() ) {
// TODO: What about stereo+ channels? composite all to one, I guess
n = fft_graph.windowSize();
- if (i + n >= (*j)->region.length() ) {
- n = (*j)->region.length() - i;
+ if (i + n >= arv->region().length() ) {
+ n = arv->region().length() - i;
}
-
- n = (*j)->region.read_at(buf, mixbuf, gain, work, (*j)->region.position() + i, n);
+
+ n = arv->audio_region().read_at(buf, mixbuf, gain, work, arv->region().position() + i, n);
if ( n < fft_graph.windowSize()) {
for (int j = n; j < fft_graph.windowSize(); j++) {
@@ -313,9 +322,9 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
Gtk::TreeModel::Row newrow = *(tlmodel)->append();
- newrow[tlcols.trackname] = rui->route().name();
+ newrow[tlcols.trackname] = rui->route()->name();
newrow[tlcols.visible] = true;
- newrow[tlcols.color] = *&rui->color();
+ newrow[tlcols.color] = rui->color();
newrow[tlcols.graph] = res;
}
diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh
index 5c68933a96..bf644f3e84 100755
--- a/gtk2_ardour/ardev_common.sh
+++ b/gtk2_ardour/ardev_common.sh
@@ -2,7 +2,10 @@
export ARDOUR_PATH=./glade:./pixmaps:.
-export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd3:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH=../libs/surfaces/control_protocol:../libs/ardour:../libs/midi++2:../libs/pbd:../libs/soundtouch:../libs/gtkmm2ext:../libs/sigc++2:../libs/glibmm2:../libs/gtkmm2/atk:../libs/gtkmm2/pango:../libs/gtkmm2/gdk:../libs/gtkmm2/gtk:../libs/libgnomecanvasmm:../libs/libsndfile:../libs/appleutility:$LD_LIBRARY_PATH
# DYLD_LIBRARY_PATH is for darwin.
export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+
+# LADSPA_PATH for OSX
+export LADSPA_PATH=$LADSPA_PATH:/Library/Audio/Plug-Ins/LADSPA
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index 9293883067..b1064b8e87 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -15,8 +15,10 @@
<separator/>
<menu action='addExistingAudioFiles'>
<menuitem action='addExternalAudioAsRegion'/>
- <menuitem action='addExternalAudioAsTrack'/>
<menuitem action='addExternalAudioToTrack'/>
+ <separator/>
+ <menuitem action='addExternalAudioAsTrack'/>
+ <menuitem action='addExternalAudioAsTapeTrack'/>
</menu>
<separator/>
<menu name='Export' action='Export'>
diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc
index ac4f055df6..5422a63b8b 100644
--- a/gtk2_ardour/ardour2_ui.rc
+++ b/gtk2_ardour/ardour2_ui.rc
@@ -219,6 +219,14 @@ style "mute_button" = "small_button"
fg[PRELIGHT] = { 0, 0, 0 }
}
+
+style "multiline_combo" = "small_button"
+{
+ font_name = "sans 8"
+ xthickness = 0
+ ythickness = 0
+}
+
style "mixer_mute_button" = "mute_button"
{
font_name = "sans 7"
@@ -936,6 +944,7 @@ widget "*TrackRecordEnableButton" style "track_rec_enable_button"
widget "*TrackRecordEnableButton*" style "track_rec_enable_button"
widget "*TrackMuteButton*" style "mute_button"
widget "*TrackLoopButton*" style "track_loop_button"
+widget "*PanAutomationLineSelector*" style "multiline_combo"
widget "*EditorTimeButton*" style "time_button"
widget "*EditorMixerButton*" style "default_buttons_menus"
widget "*SoloButton*" style "solo_button"
diff --git a/gtk2_ardour/ardour_dialog.h b/gtk2_ardour/ardour_dialog.h
index a23dcda9e0..069768c143 100644
--- a/gtk2_ardour/ardour_dialog.h
+++ b/gtk2_ardour/ardour_dialog.h
@@ -26,7 +26,7 @@
namespace ARDOUR {
class Session;
-};
+}
/*
* This virtual parent class is so that each dialog box uses the
@@ -55,3 +55,4 @@ class ArdourDialog : public Gtk::Dialog
};
#endif // __ardour_dialog_h__
+
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index f452ec9c7e..e5367d6280 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -46,6 +46,7 @@
#include <midi++/mmc.h>
#include <ardour/ardour.h>
+#include <ardour/session_route.h>
#include <ardour/port.h>
#include <ardour/audioengine.h>
#include <ardour/playlist.h>
@@ -53,7 +54,6 @@
#include <ardour/audio_diskstream.h>
#include <ardour/audiofilesource.h>
#include <ardour/recent_sessions.h>
-#include <ardour/session_diskstream.h>
#include <ardour/port.h>
#include <ardour/audio_track.h>
@@ -116,16 +116,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
shuttle_units_button (_("% ")),
- punch_in_button (_("punch\nin")),
- punch_out_button (_("punch\nout")),
- auto_return_button (_("auto\nreturn")),
- auto_play_button (_("auto\nplay")),
- auto_input_button (_("auto\ninput")),
- click_button (_("click")),
- auditioning_alert_button (_("AUDITIONING")),
+ punch_in_button (_("Punch In")),
+ punch_out_button (_("Punch Out")),
+ auto_return_button (_("Auto Return")),
+ auto_play_button (_("Autuo Play")),
+ auto_input_button (_("Auto Input")),
+ click_button (_("Click")),
+ auditioning_alert_button (_("AUDITION")),
solo_alert_button (_("SOLO")),
shown_flag (false)
-
{
using namespace Gtk::Menu_Helpers;
@@ -186,8 +185,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
gettimeofday (&last_shuttle_request, 0);
ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
- ARDOUR::AudioDiskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
- ARDOUR::AudioDiskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
+ ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
+ ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
/* handle pending state with a dialog */
@@ -339,15 +338,15 @@ ARDOUR_UI::save_ardour_state ()
Config->add_extra_xml (*node);
Config->save_state();
- XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
- XMLNode& mnode (mixer->get_state());
+ XMLNode enode(static_cast<Stateful*>(editor)->get_state());
+ XMLNode mnode(mixer->get_state());
if (session) {
- session->add_instant_xml(enode, session->path());
- session->add_instant_xml(mnode, session->path());
+ session->add_instant_xml (enode, session->path());
+ session->add_instant_xml (mnode, session->path());
} else {
- Config->add_instant_xml(enode, get_user_ardour_path());
- Config->add_instant_xml(mnode, get_user_ardour_path());
+ Config->add_instant_xml (enode, get_user_ardour_path());
+ Config->add_instant_xml (mnode, get_user_ardour_path());
}
/* keybindings */
@@ -507,11 +506,11 @@ ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
jack_nframes_t rate = engine->frame_rate();
if (fmod (rate, 1000.0) != 0.0) {
- snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
+ snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
(float) rate/1000.0f,
(engine->frames_per_cycle() / (float) rate) * 1000.0f);
} else {
- snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
+ snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
rate/1000,
(engine->frames_per_cycle() / (float) rate) * 1000.0f);
}
@@ -524,7 +523,7 @@ void
ARDOUR_UI::update_cpu_load ()
{
char buf[32];
- snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
+ snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
cpu_load_label.set_text (buf);
}
@@ -543,9 +542,10 @@ ARDOUR_UI::update_buffer_load ()
}
void
-ARDOUR_UI::count_recenabled_diskstreams (AudioDiskstream& ds)
+ARDOUR_UI::count_recenabled_diskstreams (Route& route)
{
- if (ds.record_enabled()) {
+ Track* track = dynamic_cast<Track*>(&route);
+ if (track && track->diskstream().record_enabled()) {
rec_enabled_diskstreams++;
}
}
@@ -561,7 +561,7 @@ ARDOUR_UI::update_disk_space()
char buf[64];
if (frames == max_frames) {
- strcpy (buf, _("space: 24hrs+"));
+ strcpy (buf, _("Disk: 24hrs+"));
} else {
int hrs;
int mins;
@@ -571,7 +571,7 @@ ARDOUR_UI::update_disk_space()
if (session->actively_recording()){
rec_enabled_diskstreams = 0;
- session->foreach_audio_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
+ session->foreach_route (this, &ARDOUR_UI::count_recenabled_diskstreams);
if (rec_enabled_diskstreams) {
frames /= rec_enabled_diskstreams;
@@ -591,7 +591,7 @@ ARDOUR_UI::update_disk_space()
frames -= mins * fr * 60;
secs = frames / fr;
- snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
+ snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
}
disk_space_label.set_text (buf);
@@ -876,7 +876,7 @@ ARDOUR_UI::session_add_midi_track ()
void
ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
{
- Route* route;
+ boost::shared_ptr<Route> route;
if (session == 0) {
warning << _("You cannot add a track without a session already loaded.") << endmsg;
@@ -918,7 +918,7 @@ restart JACK with more ports."));
}
void
-ARDOUR_UI::diskstream_added (AudioDiskstream* ds)
+ARDOUR_UI::diskstream_added (Diskstream* ds)
{
}
@@ -1159,32 +1159,25 @@ ARDOUR_UI::transport_forward (int option)
}
void
-ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
+ARDOUR_UI::toggle_record_enable (uint32_t dstream)
{
if (session == 0) {
return;
}
- AudioDiskstream *ds;
+ boost::shared_ptr<Route> r;
+
+ if ((r = session->route_by_remote_id (dstream)) != 0) {
- if ((ds = session->diskstream_by_id (dstream)) != 0) {
- Port *port = ds->io()->input (0);
- port->request_monitor_input (!port->monitoring_input());
- }
-}
+ Track* t;
-void
-ARDOUR_UI::toggle_record_enable (guint32 dstream)
-{
+ if ((t = dynamic_cast<Track*>(r.get())) != 0) {
+ t->diskstream().set_record_enabled (!t->diskstream().record_enabled());
+ }
+ }
if (session == 0) {
return;
}
-
- AudioDiskstream *ds;
-
- if ((ds = session->diskstream_by_id (dstream)) != 0) {
- ds->set_record_enabled (!ds->record_enabled(), this);
- }
}
void
@@ -1385,63 +1378,6 @@ ARDOUR_UI::stop_blinking ()
}
}
-
-void
-ARDOUR_UI::add_diskstream_to_menu (AudioDiskstream& dstream)
-{
- using namespace Gtk;
- using namespace Menu_Helpers;
-
- if (dstream.hidden()) {
- return;
- }
-
- MenuList& items = diskstream_menu->items();
- items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
-}
-
-void
-ARDOUR_UI::diskstream_selected (gint32 id)
-{
- selected_dstream = id;
- Main::quit ();
-}
-
-gint32
-ARDOUR_UI::select_diskstream (GdkEventButton *ev)
-{
- using namespace Gtk;
- using namespace Menu_Helpers;
-
- if (session == 0) {
- return -1;
- }
-
- diskstream_menu = new Menu();
- diskstream_menu->set_name ("ArdourContextMenu");
- using namespace Gtk;
- using namespace Menu_Helpers;
-
- MenuList& items = diskstream_menu->items();
- items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
-
- session->foreach_audio_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
-
- if (ev) {
- diskstream_menu->popup (ev->button, ev->time);
- } else {
- diskstream_menu->popup (0, 0);
- }
-
- selected_dstream = -1;
-
- Main::run ();
-
- delete diskstream_menu;
-
- return selected_dstream;
-}
-
void
ARDOUR_UI::name_io_setup (AudioEngine& engine,
string& buf,
@@ -2217,11 +2153,11 @@ ARDOUR_UI::halt_on_xrun_message ()
}
void
-ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>* deletion_list)
+ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
{
ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
- for (list<AudioFileSource*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
+ for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
delete *i;
}
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 678342f32b..297c9c3c65 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -79,7 +79,7 @@ class ColorManager;
namespace Gtkmm2ext {
class TearOff;
-};
+}
namespace ARDOUR {
class AudioEngine;
@@ -87,11 +87,11 @@ namespace ARDOUR {
class Port;
class IO;
class ControlProtocolInfo;
-};
+}
namespace ALSA {
class MultiChannelDevice;
-};
+}
#define FRAME_NAME "BaseFrame"
@@ -154,8 +154,6 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void toggle_tempo_window ();
void toggle_editing_space();
- gint32 select_diskstream (GdkEventButton *ev);
-
Gtk::Tooltips& tooltips() { return _tooltips; }
static sigc::signal<void,bool> Blink;
@@ -522,7 +520,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
sigc::connection point_one_second_connection;
sigc::connection point_zero_one_second_connection;
- void diskstream_added (ARDOUR::AudioDiskstream*);
+ void diskstream_added (ARDOUR::Diskstream*);
gint session_menu (GdkEventButton *);
@@ -536,14 +534,8 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void save_template ();
-
void session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode);
- void add_diskstream_to_menu (ARDOUR::AudioDiskstream&);
- void diskstream_selected (gint32);
- Gtk::Menu *diskstream_menu;
- gint32 selected_dstream;
-
void set_transport_sensitivity (bool);
void remove_last_capture ();
@@ -626,11 +618,10 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void test_binding_action (const char *);
void start_keyboard_prefix();
- void toggle_record_enable (guint32);
- void toggle_monitor_enable (guint32);
+ void toggle_record_enable (uint32_t);
uint32_t rec_enabled_diskstreams;
- void count_recenabled_diskstreams (ARDOUR::AudioDiskstream&);
+ void count_recenabled_diskstreams (ARDOUR::Route&);
About* about;
bool shown_flag;
@@ -649,7 +640,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
struct timeval last_peak_grab;
struct timeval last_shuttle_request;
- void delete_sources_in_the_right_thread (list<ARDOUR::AudioFileSource*>*);
+ void delete_sources_in_the_right_thread (list<ARDOUR::Source*>*);
void editor_display_control_changed (Editing::DisplayControl c);
@@ -716,5 +707,5 @@ class ARDOUR_UI : public Gtkmm2ext::UI
void toggle_control_protocol (ARDOUR::ControlProtocolInfo*);
};
-
#endif /* __ardour_gui_h__ */
+
diff --git a/gtk2_ardour/ardour_ui2.cc b/gtk2_ardour/ardour_ui2.cc
index f92201e36c..44287fe61e 100644
--- a/gtk2_ardour/ardour_ui2.cc
+++ b/gtk2_ardour/ardour_ui2.cc
@@ -359,10 +359,10 @@ ARDOUR_UI::setup_transport ()
auditioning_alert_button.set_name ("TransportAuditioningAlert");
auditioning_alert_button.signal_pressed().connect (mem_fun(*this,&ARDOUR_UI::audition_alert_toggle));
- alert_box.pack_start (solo_alert_button);
- alert_box.pack_start (auditioning_alert_button);
+ alert_box.pack_start (solo_alert_button, false, false);
+ alert_box.pack_start (auditioning_alert_button, false, false);
- transport_tearoff_hbox.set_border_width (5);
+ transport_tearoff_hbox.set_border_width (3);
transport_tearoff_hbox.pack_start (goto_start_button, false, false);
transport_tearoff_hbox.pack_start (goto_end_button, false, false);
@@ -398,6 +398,7 @@ ARDOUR_UI::setup_transport ()
mtc_port_changed ();
sync_option_combo.set_active_text (positional_sync_strings.front());
sync_option_combo.signal_changed().connect (mem_fun (*this, &ARDOUR_UI::sync_option_changed));
+ Gtkmm2ext::set_size_request_to_display_given_text (sync_option_combo, "Internal", 22, 10);
shbox->pack_start (*sdframe, false, false);
shbox->pack_start (shuttle_units_button, true, true);
@@ -406,37 +407,52 @@ ARDOUR_UI::setup_transport ()
svbox->pack_start (*sframe, false, false);
svbox->pack_start (*shbox, false, false);
- transport_tearoff_hbox.pack_start (*svbox, false, false, 5);
+ transport_tearoff_hbox.pack_start (*svbox, false, false, 3);
transport_tearoff_hbox.pack_start (auto_loop_button, false, false);
transport_tearoff_hbox.pack_start (play_selection_button, false, false);
transport_tearoff_hbox.pack_start (roll_button, false, false);
transport_tearoff_hbox.pack_start (stop_button, false, false);
- transport_tearoff_hbox.pack_start (rec_button, false, false, 10);
-
- transport_tearoff_hbox.pack_start (primary_clock, false, false, 5);
- transport_tearoff_hbox.pack_start (secondary_clock, false, false, 5);
-
- transport_tearoff_hbox.pack_start (sync_option_combo, false, false);
- transport_tearoff_hbox.pack_start (time_master_button, false, false);
- transport_tearoff_hbox.pack_start (punch_in_button, false, false);
- transport_tearoff_hbox.pack_start (punch_out_button, false, false);
- transport_tearoff_hbox.pack_start (auto_input_button, false, false);
- transport_tearoff_hbox.pack_start (auto_return_button, false, false);
- transport_tearoff_hbox.pack_start (auto_play_button, false, false);
- transport_tearoff_hbox.pack_start (click_button, false, false);
+ transport_tearoff_hbox.pack_start (rec_button, false, false, 6);
+
+ HBox* clock_box = manage (new HBox);
+ clock_box->pack_start (primary_clock, false, false);
+ clock_box->pack_start (secondary_clock, false, false);
+ VBox* time_controls_box = manage (new VBox);
+ time_controls_box->pack_start (sync_option_combo, false, false);
+ time_controls_box->pack_start (time_master_button, false, false);
+ clock_box->pack_start (*time_controls_box, false, false, 1);
+ transport_tearoff_hbox.pack_start (*clock_box, false, false, 0);
+
+ HBox* toggle_box = manage(new HBox);
+
+ VBox* punch_box = manage (new VBox);
+ punch_box->pack_start (punch_in_button, false, false);
+ punch_box->pack_start (punch_out_button, false, false);
+ toggle_box->pack_start (*punch_box, false, false);
+
+ VBox* auto_box = manage (new VBox);
+ auto_box->pack_start (auto_play_button, false, false);
+ auto_box->pack_start (auto_return_button, false, false);
+ toggle_box->pack_start (*auto_box, false, false);
+
+ VBox* io_box = manage (new VBox);
+ io_box->pack_start (auto_input_button, false, false);
+ io_box->pack_start (click_button, false, false);
+ toggle_box->pack_start (*io_box, false, false);
/* desensitize */
set_transport_sensitivity (false);
-// transport_tearoff_hbox.pack_start (preroll_button, false, false);
-// transport_tearoff_hbox.pack_start (preroll_clock, false, false);
+// toggle_box->pack_start (preroll_button, false, false);
+// toggle_box->pack_start (preroll_clock, false, false);
-// transport_tearoff_hbox.pack_start (postroll_button, false, false);
-// transport_tearoff_hbox.pack_start (postroll_clock, false, false);
+// toggle_box->pack_start (postroll_button, false, false);
+// toggle_box->pack_start (postroll_clock, false, false);
- transport_tearoff_hbox.pack_start (alert_box, false, false, 5);
+ transport_tearoff_hbox.pack_start (*toggle_box, false, false, 4);
+ transport_tearoff_hbox.pack_start (alert_box, false, false);
}
void
@@ -820,7 +836,7 @@ ARDOUR_UI::set_shuttle_units (ShuttleUnits u)
shuttle_units_button.set_label("% ");
break;
case Semitones:
- shuttle_units_button.set_label(_("st"));
+ shuttle_units_button.set_label(_("ST"));
break;
}
}
@@ -864,7 +880,7 @@ ARDOUR_UI::update_speed_display ()
{
if (!session) {
if (last_speed_displayed != 0) {
- speed_display_label.set_text (_("stopped"));
+ speed_display_label.set_text (_("stop"));
last_speed_displayed = 0;
}
return;
@@ -877,7 +893,7 @@ ARDOUR_UI::update_speed_display ()
if (x != 0) {
if (shuttle_units == Percentage) {
- snprintf (buf, sizeof (buf), "%.4f", x);
+ snprintf (buf, sizeof (buf), "%.2f", x);
} else {
if (x < 0) {
snprintf (buf, sizeof (buf), "< %.1f", 12.0 * fast_log2 (-x));
@@ -887,7 +903,7 @@ ARDOUR_UI::update_speed_display ()
}
speed_display_label.set_text (buf);
} else {
- speed_display_label.set_text (_("stopped"));
+ speed_display_label.set_text (_("stop"));
}
last_speed_displayed = x;
@@ -904,7 +920,7 @@ ARDOUR_UI::set_transport_sensitivity (bool yn)
void
ARDOUR_UI::editor_realized ()
{
- set_size_request_to_display_given_text (speed_display_box, _("stopped"), 2, 2);
+ set_size_request_to_display_given_text (speed_display_box, _("-0.55"), 2, 2);
/* XXX: this should really be saved in instant.xml or something similar and restored from there */
shuttle_style_button.set_active_text (_("sprung"));
const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc
index 202fa88b59..25f3068a81 100644
--- a/gtk2_ardour/ardour_ui_dialogs.cc
+++ b/gtk2_ardour/ardour_ui_dialogs.cc
@@ -76,8 +76,8 @@ ARDOUR_UI::connect_to_session (Session *s)
rec_button.set_sensitive (true);
shuttle_box.set_sensitive (true);
- if (session->n_audio_diskstreams() == 0) {
- session->AudioDiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
+ if (session->n_diskstreams() == 0) {
+ session->DiskstreamAdded.connect (mem_fun(*this, &ARDOUR_UI::diskstream_added));
}
if (connection_editor) {
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index 1bc2de26d1..238f81dd4f 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -264,31 +264,26 @@ ARDOUR_UI::install_actions ()
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- /* XXX the newline in the displayed names of these action is really wrong, but its because we want the button
- that proxies for these action to be more compact. It would be nice to find a way to override the action
- name appearance on the buttons.
- */
-
- act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("Punch\nin"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in));
+ act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchIn"), _("Punch In"), mem_fun(*this, &ARDOUR_UI::toggle_punch_in));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("Punch\nout"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out));
+ act = ActionManager::register_toggle_action (transport_actions, X_("TogglePunchOut"), _("Punch Out"), mem_fun(*this, &ARDOUR_UI::toggle_punch_out));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
act = ActionManager::register_toggle_action (transport_actions, X_("ToggleClick"), _("Click"), mem_fun(*this, &ARDOUR_UI::toggle_click));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoInput"), _("Auto\ninput"), mem_fun(*this, &ARDOUR_UI::toggle_auto_input));
+ act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoInput"), _("Auto Input"), mem_fun(*this, &ARDOUR_UI::toggle_auto_input));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoPlay"), _("Auto\nplay"), mem_fun(*this, &ARDOUR_UI::toggle_auto_play));
+ act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoPlay"), _("Auto Play"), mem_fun(*this, &ARDOUR_UI::toggle_auto_play));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoReturn"), _("Auto\nreturn"), mem_fun(*this, &ARDOUR_UI::toggle_auto_return));
+ act = ActionManager::register_toggle_action (transport_actions, X_("ToggleAutoReturn"), _("Auto Return"), mem_fun(*this, &ARDOUR_UI::toggle_auto_return));
ActionManager::session_sensitive_actions.push_back (act);
ActionManager::transport_sensitive_actions.push_back (act);
- act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Time\nmaster"), mem_fun(*this, &ARDOUR_UI::toggle_time_master));
+ act = ActionManager::register_toggle_action (transport_actions, X_("ToggleTimeMaster"), _("Master"), mem_fun(*this, &ARDOUR_UI::toggle_time_master));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (common_actions, X_("ToggleRecordEnableTrack1"), _("Toggle Record Enable Track1"), bind (mem_fun(*this, &ARDOUR_UI::toggle_record_enable), 0U));
diff --git a/gtk2_ardour/audio_clock.h b/gtk2_ardour/audio_clock.h
index 14dc6ba673..9ff5f45ddf 100644
--- a/gtk2_ardour/audio_clock.h
+++ b/gtk2_ardour/audio_clock.h
@@ -30,7 +30,7 @@
namespace ARDOUR {
class Session;
-};
+}
class AudioClock : public Gtk::HBox
{
@@ -40,7 +40,7 @@ class AudioClock : public Gtk::HBox
BBT,
MinSec,
Frames,
- Off,
+ Off
};
AudioClock (const string& name, bool editable, bool is_duration = false, bool with_tempo_meter = false);
@@ -87,7 +87,7 @@ class AudioClock : public Gtk::HBox
Bars,
Beats,
Ticks,
- AudioFrames,
+ AudioFrames
};
Gtk::EventBox audio_frames_ebox;
diff --git a/gtk2_ardour/region_editor.cc b/gtk2_ardour/audio_region_editor.cc
index 413ff01753..194f358b42 100644
--- a/gtk2_ardour/region_editor.cc
+++ b/gtk2_ardour/audio_region_editor.cc
@@ -24,8 +24,8 @@
#include <gtkmm2ext/stop_signal.h>
#include <cmath>
-#include "region_editor.h"
-#include "regionview.h"
+#include "audio_region_editor.h"
+#include "audio_region_view.h"
#include "ardour_ui.h"
#include "utils.h"
#include "gui_thread.h"
@@ -37,9 +37,8 @@ using namespace PBD;
using namespace sigc;
using namespace std;
-AudioRegionEditor::AudioRegionEditor (Session&s, AudioRegion& r, AudioRegionView& rv)
- : ArdourDialog ("audio region editor"),
- _session (s),
+AudioRegionEditor::AudioRegionEditor (Session& s, AudioRegion& r, AudioRegionView& rv)
+ : RegionEditor (s),
_region (r),
_region_view (rv),
name_label (_("NAME:")),
diff --git a/gtk2_ardour/audio_region_editor.h b/gtk2_ardour/audio_region_editor.h
new file mode 100644
index 0000000000..38cd920e5e
--- /dev/null
+++ b/gtk2_ardour/audio_region_editor.h
@@ -0,0 +1,186 @@
+/*
+ Copyright (C) 2001 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __gtk_ardour_audio_region_edit_h__
+#define __gtk_ardour_audio_region_edit_h__
+
+#include <map>
+
+#include <gtkmm/label.h>
+#include <gtkmm/entry.h>
+#include <gtkmm/box.h>
+#include <gtkmm/togglebutton.h>
+#include <gtkmm/button.h>
+#include <gtkmm/arrow.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/table.h>
+#include <gtkmm/alignment.h>
+#include <gtkmm/adjustment.h>
+#include <gtkmm/separator.h>
+#include <gtkmm/spinbutton.h>
+
+#include <libgnomecanvas/libgnomecanvas.h>
+#include <sigc++/signal.h>
+
+#include "audio_clock.h"
+#include "ardour_dialog.h"
+#include "region_editor.h"
+
+namespace ARDOUR {
+ class AudioRegion;
+ class Session;
+}
+
+class AudioRegionView;
+
+class AudioRegionEditor : public RegionEditor
+{
+ public:
+ AudioRegionEditor (ARDOUR::Session&, ARDOUR::AudioRegion&, AudioRegionView& rv);
+ ~AudioRegionEditor ();
+
+ private:
+ ARDOUR::AudioRegion& _region;
+ AudioRegionView& _region_view;
+
+ void connect_editor_events ();
+
+ Gtk::Label name_label;
+ Gtk::Entry name_entry;
+ Gtk::HBox name_hbox;
+
+ Gtk::HBox top_row_hbox;
+ Gtk::HBox top_row_button_hbox;
+
+ Gtk::ToggleButton lock_button;
+ Gtk::ToggleButton mute_button;
+ Gtk::ToggleButton opaque_button;
+ Gtk::ToggleButton envelope_active_button;
+ Gtk::ToggleButton envelope_view_button;
+
+ Gtk::Button raise_button;
+ Gtk::Arrow raise_arrow;
+ Gtk::Button lower_button;
+ Gtk::Arrow lower_arrow;
+ Gtk::Frame layer_frame;
+ Gtk::Label layer_value_label;
+ Gtk::Label layer_label;
+ Gtk::HBox layer_hbox;
+
+ Gtk::ToggleButton audition_button;
+
+ Gtk::HBox lower_hbox;
+
+ Gtk::Table time_table;
+
+ Gtk::Label start_label;
+ Gtk::Label end_label;
+ Gtk::Label length_label;
+ Gtk::Alignment start_alignment;
+ Gtk::Alignment end_alignment;
+ Gtk::Alignment length_alignment;
+
+ AudioClock start_clock;
+ AudioClock end_clock;
+ AudioClock length_clock;
+ AudioClock sync_offset_clock;
+
+ Gtk::Table envelope_loop_table;
+ Gtk::Button loop_button;
+ Gtk::Label loop_label;
+ Gtk::Label envelope_label;
+
+ Gtk::Table fade_in_table;
+ Gtk::Label fade_in_label;
+ Gtk::Alignment fade_in_label_align;
+ Gtk::Label fade_in_active_button_label;
+ Gtk::ToggleButton fade_in_active_button;
+ Gtk::Label fade_in_length_label;
+
+ Gtk::Adjustment fade_in_length_adjustment;
+ Gtk::SpinButton fade_in_length_spinner;
+
+ Gtk::Table fade_out_table;
+ Gtk::Label fade_out_label;
+ Gtk::Alignment fade_out_label_align;
+ Gtk::Label fade_out_active_button_label;
+ Gtk::ToggleButton fade_out_active_button;
+ Gtk::Label fade_out_length_label;
+
+ Gtk::Adjustment fade_out_length_adjustment;
+ Gtk::SpinButton fade_out_length_spinner;
+
+ Gtk::HSeparator sep3;
+ Gtk::VSeparator sep1;
+ Gtk::VSeparator sep2;
+
+ void region_changed (ARDOUR::Change);
+ void bounds_changed (ARDOUR::Change);
+ void name_changed ();
+ void opacity_changed ();
+ void mute_changed ();
+ void envelope_active_changed ();
+ void lock_changed ();
+ void layer_changed ();
+
+ void fade_in_length_adjustment_changed ();
+ void fade_out_length_adjustment_changed ();
+ void fade_in_changed ();
+ void fade_out_changed ();
+ void audition_state_changed (bool);
+
+ void activation ();
+
+ void name_entry_changed ();
+ void start_clock_changed ();
+ void end_clock_changed ();
+ void length_clock_changed ();
+
+ gint envelope_active_button_press (GdkEventButton *);
+ gint envelope_active_button_release (GdkEventButton *);
+
+ void audition_button_toggled ();
+ void envelope_view_button_toggled ();
+ void lock_button_clicked ();
+ void mute_button_clicked ();
+ void opaque_button_clicked ();
+ void raise_button_clicked ();
+ void lower_button_clicked ();
+
+ void fade_in_active_toggled ();
+ void fade_out_active_toggled ();
+ void fade_in_active_changed ();
+ void fade_out_active_changed ();
+
+ void fade_in_realized ();
+ void fade_out_realized ();
+
+ void start_editing_fade_in ();
+ void start_editing_fade_out ();
+ void stop_editing_fade_in ();
+ void stop_editing_fade_out ();
+
+ gint bpressed (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)());
+ gint breleased (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)());
+
+ bool spin_arrow_grab;
+};
+
+#endif /* __gtk_ardour_audio_region_edit_h__ */
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
new file mode 100644
index 0000000000..feb8f4fd0b
--- /dev/null
+++ b/gtk2_ardour/audio_region_view.cc
@@ -0,0 +1,1127 @@
+/*
+ Copyright (C) 2001-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#include <cmath>
+#include <cassert>
+#include <algorithm>
+
+#include <gtkmm.h>
+
+#include <gtkmm2ext/gtk_ui.h>
+
+#include <ardour/playlist.h>
+#include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
+
+#include "streamview.h"
+#include "audio_region_view.h"
+#include "audio_time_axis.h"
+#include "simplerect.h"
+#include "simpleline.h"
+#include "waveview.h"
+#include "public_editor.h"
+#include "audio_region_editor.h"
+#include "region_gain_line.h"
+#include "ghostregion.h"
+#include "audio_time_axis.h"
+#include "utils.h"
+#include "rgb_macros.h"
+#include "gui_thread.h"
+
+#include "i18n.h"
+
+using namespace sigc;
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Editing;
+using namespace ArdourCanvas;
+
+static const int32_t sync_mark_width = 9;
+
+AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu,
+ Gdk::Color& basic_color)
+ : RegionView (parent, tv, r, spu, basic_color)
+ , sync_mark(0)
+ , zero_line(0)
+ , fade_in_shape(0)
+ , fade_out_shape(0)
+ , fade_in_handle(0)
+ , fade_out_handle(0)
+ , gain_line(0)
+ , _amplitude_above_axis(1.0)
+ , _flags(0)
+ , fade_color(0)
+{
+}
+
+AudioRegionView::AudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv, AudioRegion& r, double spu,
+ Gdk::Color& basic_color, TimeAxisViewItem::Visibility visibility)
+ : RegionView (parent, tv, r, spu, basic_color, visibility)
+ , sync_mark(0)
+ , zero_line(0)
+ , fade_in_shape(0)
+ , fade_out_shape(0)
+ , fade_in_handle(0)
+ , fade_out_handle(0)
+ , gain_line(0)
+ , _amplitude_above_axis(1.0)
+ , _flags(0)
+ , fade_color(0)
+{
+}
+
+void
+AudioRegionView::init (Gdk::Color& basic_color, bool wfd)
+{
+ // FIXME: Some redundancy here with RegionView::init. Need to figure out
+ // where order is important and where it isn't...
+
+ RegionView::init(basic_color, wfd);
+
+ XMLNode *node;
+
+ _amplitude_above_axis = 1.0;
+ zero_line = 0;
+ _flags = 0;
+
+ if ((node = _region.extra_xml ("GUI")) != 0) {
+ set_flags (node);
+ } else {
+ _flags = WaveformVisible;
+ store_flags ();
+ }
+
+ if (trackview.editor.new_regionviews_display_gain()) {
+ _flags |= EnvelopeVisible;
+ }
+
+ compute_colors (basic_color);
+
+ create_waves ();
+
+ fade_in_shape = new ArdourCanvas::Polygon (*group);
+ fade_in_shape->property_fill_color_rgba() = fade_color;
+ fade_in_shape->set_data ("regionview", this);
+
+ fade_out_shape = new ArdourCanvas::Polygon (*group);
+ fade_out_shape->property_fill_color_rgba() = fade_color;
+ fade_out_shape->set_data ("regionview", this);
+
+
+ {
+ uint32_t r,g,b,a;
+ UINT_TO_RGBA(fill_color,&r,&g,&b,&a);
+
+
+ fade_in_handle = new ArdourCanvas::SimpleRect (*group);
+ fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
+ fade_in_handle->property_outline_pixels() = 0;
+ fade_in_handle->property_y1() = 2.0;
+ fade_in_handle->property_y2() = 7.0;
+
+ fade_in_handle->set_data ("regionview", this);
+
+ fade_out_handle = new ArdourCanvas::SimpleRect (*group);
+ fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
+ fade_out_handle->property_outline_pixels() = 0;
+ fade_out_handle->property_y1() = 2.0;
+ fade_out_handle->property_y2() = 7.0;
+
+ fade_out_handle->set_data ("regionview", this);
+ }
+
+ string foo = _region.name();
+ foo += ':';
+ foo += "gain";
+
+ gain_line = new AudioRegionGainLine (foo, trackview.session(), *this, *group, audio_region().envelope());
+
+ if (!(_flags & EnvelopeVisible)) {
+ gain_line->hide ();
+ } else {
+ gain_line->show ();
+ }
+
+ reset_width_dependent_items ((double) _region.length() / samples_per_unit);
+
+ gain_line->reset ();
+
+ set_height (trackview.height);
+
+ region_muted ();
+ region_sync_changed ();
+ region_resized (BoundsChanged);
+ set_waveview_data_src();
+ region_locked ();
+ envelope_active_changed ();
+ fade_in_active_changed ();
+ fade_out_active_changed ();
+
+ _region.StateChanged.connect (mem_fun(*this, &AudioRegionView::region_changed));
+
+ fade_in_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_event), fade_in_shape, this));
+ fade_in_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_in_handle_event), fade_in_handle, this));
+ fade_out_shape->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_event), fade_out_shape, this));
+ fade_out_handle->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_fade_out_handle_event), fade_out_handle, this));
+
+ set_colors ();
+
+ /* XXX sync mark drag? */
+}
+
+AudioRegionView::~AudioRegionView ()
+{
+ in_destructor = true;
+
+ RegionViewGoingAway (this); /* EMIT_SIGNAL */
+
+ for (vector<GnomeCanvasWaveViewCache *>::iterator cache = wave_caches.begin(); cache != wave_caches.end() ; ++cache) {
+ gnome_canvas_waveview_cache_destroy (*cache);
+ }
+
+ /* all waveviews etc will be destroyed when the group is destroyed */
+
+ if (gain_line) {
+ delete gain_line;
+ }
+}
+
+ARDOUR::AudioRegion&
+AudioRegionView::audio_region() const
+{
+ // "Guaranteed" to succeed...
+ return dynamic_cast<AudioRegion&>(_region);
+}
+
+void
+AudioRegionView::region_changed (Change what_changed)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioRegionView::region_changed), what_changed));
+
+ RegionView::region_changed(what_changed);
+
+ if (what_changed & AudioRegion::ScaleAmplitudeChanged) {
+ region_scale_amplitude_changed ();
+ }
+ if (what_changed & AudioRegion::FadeInChanged) {
+ fade_in_changed ();
+ }
+ if (what_changed & AudioRegion::FadeOutChanged) {
+ fade_out_changed ();
+ }
+ if (what_changed & AudioRegion::FadeInActiveChanged) {
+ fade_in_active_changed ();
+ }
+ if (what_changed & AudioRegion::FadeOutActiveChanged) {
+ fade_out_active_changed ();
+ }
+ if (what_changed & AudioRegion::EnvelopeActiveChanged) {
+ envelope_active_changed ();
+ }
+}
+
+void
+AudioRegionView::fade_in_changed ()
+{
+ reset_fade_in_shape ();
+}
+
+void
+AudioRegionView::fade_out_changed ()
+{
+ reset_fade_out_shape ();
+}
+
+void
+AudioRegionView::set_fade_in_active (bool yn)
+{
+ audio_region().set_fade_in_active (yn);
+}
+
+void
+AudioRegionView::set_fade_out_active (bool yn)
+{
+ audio_region().set_fade_out_active (yn);
+}
+
+void
+AudioRegionView::fade_in_active_changed ()
+{
+ uint32_t r,g,b,a;
+ uint32_t col;
+ UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
+
+ if (audio_region().fade_in_active()) {
+ col = RGBA_TO_UINT(r,g,b,120);
+ fade_in_shape->property_fill_color_rgba() = col;
+ fade_in_shape->property_width_pixels() = 0;
+ fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
+ } else {
+ col = RGBA_TO_UINT(r,g,b,0);
+ fade_in_shape->property_fill_color_rgba() = col;
+ fade_in_shape->property_width_pixels() = 1;
+ fade_in_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255);
+ }
+}
+
+void
+AudioRegionView::fade_out_active_changed ()
+{
+ uint32_t r,g,b,a;
+ uint32_t col;
+ UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
+
+ if (audio_region().fade_out_active()) {
+ col = RGBA_TO_UINT(r,g,b,120);
+ fade_out_shape->property_fill_color_rgba() = col;
+ fade_out_shape->property_width_pixels() = 0;
+ fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,0);
+ } else {
+ col = RGBA_TO_UINT(r,g,b,0);
+ fade_out_shape->property_fill_color_rgba() = col;
+ fade_out_shape->property_width_pixels() = 1;
+ fade_out_shape->property_outline_color_rgba() = RGBA_TO_UINT(r,g,b,255);
+ }
+}
+
+
+void
+AudioRegionView::region_scale_amplitude_changed ()
+{
+ ENSURE_GUI_THREAD (mem_fun(*this, &AudioRegionView::region_scale_amplitude_changed));
+
+ for (uint32_t n = 0; n < waves.size(); ++n) {
+ // force a reload of the cache
+ waves[n]->property_data_src() = &_region;
+ }
+}
+
+void
+AudioRegionView::region_resized (Change what_changed)
+{
+ RegionView::region_resized(what_changed);
+
+ if (what_changed & Change (StartChanged|LengthChanged)) {
+
+ for (uint32_t n = 0; n < waves.size(); ++n) {
+ waves[n]->property_region_start() = _region.start();
+ }
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+
+ for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) {
+ (*w)->property_region_start() = _region.start();
+ }
+ }
+ }
+}
+
+void
+AudioRegionView::reset_width_dependent_items (double pixel_width)
+{
+ RegionView::reset_width_dependent_items(pixel_width);
+ assert(_pixel_width == pixel_width);
+
+ if (zero_line) {
+ zero_line->property_x2() = pixel_width - 1.0;
+ }
+
+ if (fade_in_handle) {
+ if (pixel_width <= 6.0) {
+ fade_in_handle->hide();
+ fade_out_handle->hide();
+ } else {
+ if (_height < 5.0) {
+ fade_in_handle->hide();
+ fade_out_handle->hide();
+ } else {
+ fade_in_handle->show();
+ fade_out_handle->show();
+ }
+ }
+ }
+
+ reset_fade_shapes ();
+}
+
+void
+AudioRegionView::region_muted ()
+{
+ RegionView::region_muted();
+
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ if (_region.muted()) {
+ waves[n]->property_wave_color() = color_map[cMutedWaveForm];
+ } else {
+ waves[n]->property_wave_color() = color_map[cWaveForm];
+ }
+ }
+}
+
+
+void
+AudioRegionView::set_height (gdouble height)
+{
+ uint32_t wcnt = waves.size();
+
+ // FIXME: ick
+ TimeAxisViewItem::set_height (height - 2);
+
+ _height = height;
+
+ for (uint32_t n=0; n < wcnt; ++n) {
+ gdouble ht;
+
+ if ((height) <= NAME_HIGHLIGHT_THRESH) {
+ ht = ((height-2*wcnt) / (double) wcnt);
+ } else {
+ ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
+ }
+
+ gdouble yoff = n * (ht+1);
+
+ waves[n]->property_height() = ht;
+ waves[n]->property_y() = yoff + 2;
+ }
+
+ if (gain_line) {
+ if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) {
+ gain_line->hide ();
+ } else {
+ if (_flags & EnvelopeVisible) {
+ gain_line->show ();
+ }
+ }
+ gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE));
+ }
+
+ manage_zero_line ();
+ reset_fade_shapes ();
+
+ if (name_text) {
+ name_text->raise_to_top();
+ }
+}
+
+void
+AudioRegionView::manage_zero_line ()
+{
+ if (!zero_line) {
+ return;
+ }
+
+ if (_height >= 100) {
+ gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0;
+ zero_line->property_y1() = wave_midpoint;
+ zero_line->property_y2() = wave_midpoint;
+ zero_line->show();
+ } else {
+ zero_line->hide();
+ }
+}
+
+void
+AudioRegionView::reset_fade_shapes ()
+{
+ reset_fade_in_shape ();
+ reset_fade_out_shape ();
+}
+
+void
+AudioRegionView::reset_fade_in_shape ()
+{
+ reset_fade_in_shape_width ((jack_nframes_t) audio_region().fade_in().back()->when);
+}
+
+void
+AudioRegionView::reset_fade_in_shape_width (jack_nframes_t width)
+{
+ if (fade_in_handle == 0) {
+ return;
+ }
+
+ /* smallest size for a fade is 64 frames */
+
+ width = std::max ((jack_nframes_t) 64, width);
+
+ Points* points;
+ double pwidth = width / samples_per_unit;
+ uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
+ double h;
+
+ if (_height < 5) {
+ fade_in_shape->hide();
+ fade_in_handle->hide();
+ return;
+ }
+
+ double handle_center;
+ handle_center = pwidth;
+
+ if (handle_center > 7.0) {
+ handle_center -= 3.0;
+ } else {
+ handle_center = 3.0;
+ }
+
+ fade_in_handle->property_x1() = handle_center - 3.0;
+ fade_in_handle->property_x2() = handle_center + 3.0;
+
+ if (pwidth < 5) {
+ fade_in_shape->hide();
+ return;
+ }
+
+ fade_in_shape->show();
+
+ float curve[npoints];
+ audio_region().fade_in().get_vector (0, audio_region().fade_in().back()->when, curve, npoints);
+
+ points = get_canvas_points ("fade in shape", npoints+3);
+
+ if (_height > NAME_HIGHLIGHT_THRESH) {
+ h = _height - NAME_HIGHLIGHT_SIZE;
+ } else {
+ h = _height;
+ }
+
+ /* points *MUST* be in anti-clockwise order */
+
+ uint32_t pi, pc;
+ double xdelta = pwidth/npoints;
+
+ for (pi = 0, pc = 0; pc < npoints; ++pc) {
+ (*points)[pi].set_x(1 + (pc * xdelta));
+ (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
+ }
+
+ /* fold back */
+
+ (*points)[pi].set_x(pwidth);
+ (*points)[pi++].set_y(2);
+
+ (*points)[pi].set_x(1);
+ (*points)[pi++].set_y(2);
+
+ /* connect the dots ... */
+
+ (*points)[pi] = (*points)[0];
+
+ fade_in_shape->property_points() = *points;
+ delete points;
+}
+
+void
+AudioRegionView::reset_fade_out_shape ()
+{
+ reset_fade_out_shape_width ((jack_nframes_t) audio_region().fade_out().back()->when);
+}
+
+void
+AudioRegionView::reset_fade_out_shape_width (jack_nframes_t width)
+{
+ if (fade_out_handle == 0) {
+ return;
+ }
+
+ /* smallest size for a fade is 64 frames */
+
+ width = std::max ((jack_nframes_t) 64, width);
+
+ Points* points;
+ double pwidth = width / samples_per_unit;
+ uint32_t npoints = std::min (gdk_screen_width(), (int) pwidth);
+ double h;
+
+ if (_height < 5) {
+ fade_out_shape->hide();
+ fade_out_handle->hide();
+ return;
+ }
+
+ double handle_center;
+ handle_center = (_region.length() - width) / samples_per_unit;
+
+ if (handle_center > 7.0) {
+ handle_center -= 3.0;
+ } else {
+ handle_center = 3.0;
+ }
+
+ fade_out_handle->property_x1() = handle_center - 3.0;
+ fade_out_handle->property_x2() = handle_center + 3.0;
+
+ /* don't show shape if its too small */
+
+ if (pwidth < 5) {
+ fade_out_shape->hide();
+ return;
+ }
+
+ fade_out_shape->show();
+
+ float curve[npoints];
+ audio_region().fade_out().get_vector (0, audio_region().fade_out().back()->when, curve, npoints);
+
+ if (_height > NAME_HIGHLIGHT_THRESH) {
+ h = _height - NAME_HIGHLIGHT_SIZE;
+ } else {
+ h = _height;
+ }
+
+ /* points *MUST* be in anti-clockwise order */
+
+ points = get_canvas_points ("fade out shape", npoints+3);
+
+ uint32_t pi, pc;
+ double xdelta = pwidth/npoints;
+
+ for (pi = 0, pc = 0; pc < npoints; ++pc) {
+ (*points)[pi].set_x(_pixel_width - 1 - pwidth + (pc*xdelta));
+ (*points)[pi++].set_y(2 + (h - (curve[pc] * h)));
+ }
+
+ /* fold back */
+
+ (*points)[pi].set_x(_pixel_width);
+ (*points)[pi++].set_y(h);
+
+ (*points)[pi].set_x(_pixel_width);
+ (*points)[pi++].set_y(2);
+
+ /* connect the dots ... */
+
+ (*points)[pi] = (*points)[0];
+
+ fade_out_shape->property_points() = *points;
+ delete points;
+}
+
+void
+AudioRegionView::set_samples_per_unit (gdouble spu)
+{
+ RegionView::set_samples_per_unit (spu);
+
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ waves[n]->property_samples_per_unit() = spu;
+ }
+
+ if (gain_line) {
+ gain_line->reset ();
+ }
+ reset_fade_shapes ();
+}
+
+void
+AudioRegionView::set_amplitude_above_axis (gdouble spp)
+{
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ waves[n]->property_amplitude_above_axis() = spp;
+ }
+}
+
+void
+AudioRegionView::compute_colors (Gdk::Color& basic_color)
+{
+ RegionView::compute_colors(basic_color);
+
+ uint32_t r, g, b, a;
+
+ /* gain color computed in envelope_active_changed() */
+
+ UINT_TO_RGBA (fill_color, &r, &g, &b, &a);
+ fade_color = RGBA_TO_UINT(r,g,b,120);
+}
+
+void
+AudioRegionView::set_colors ()
+{
+ RegionView::set_colors();
+
+ if (gain_line) {
+ gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]);
+ }
+
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ if (_region.muted()) {
+ waves[n]->property_wave_color() = color_map[cMutedWaveForm];
+ } else {
+ waves[n]->property_wave_color() = color_map[cWaveForm];
+ }
+ }
+}
+
+void
+AudioRegionView::show_region_editor ()
+{
+ if (editor == 0) {
+ editor = new AudioRegionEditor (trackview.session(), audio_region(), *this);
+ // GTK2FIX : how to ensure float without realizing
+ // editor->realize ();
+ // trackview.editor.ensure_float (*editor);
+ }
+
+ editor->show_all ();
+ editor->get_window()->raise();
+}
+
+void
+AudioRegionView::set_waveform_visible (bool yn)
+{
+ if (((_flags & WaveformVisible) != yn)) {
+ if (yn) {
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ waves[n]->show();
+ }
+ _flags |= WaveformVisible;
+ } else {
+ for (uint32_t n=0; n < waves.size(); ++n) {
+ waves[n]->hide();
+ }
+ _flags &= ~WaveformVisible;
+ }
+ store_flags ();
+ }
+}
+
+void
+AudioRegionView::temporarily_hide_envelope ()
+{
+ if (gain_line) {
+ gain_line->hide ();
+ }
+}
+
+void
+AudioRegionView::unhide_envelope ()
+{
+ if (gain_line && (_flags & EnvelopeVisible)) {
+ gain_line->show ();
+ }
+}
+
+void
+AudioRegionView::set_envelope_visible (bool yn)
+{
+ if (gain_line && ((_flags & EnvelopeVisible) != yn)) {
+ if (yn) {
+ gain_line->show ();
+ _flags |= EnvelopeVisible;
+ } else {
+ gain_line->hide ();
+ _flags &= ~EnvelopeVisible;
+ }
+ store_flags ();
+ }
+}
+
+void
+AudioRegionView::create_waves ()
+{
+ bool create_zero_line = true;
+
+ RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
+
+ if (!atv.get_diskstream()) {
+ return;
+ }
+
+ uint32_t nchans = atv.get_diskstream()->n_channels();
+
+ /* in tmp_waves, set up null pointers for each channel so the vector is allocated */
+ for (uint32_t n = 0; n < nchans; ++n) {
+ tmp_waves.push_back (0);
+ }
+
+ for (uint32_t n = 0; n < nchans; ++n) {
+
+ if (n >= audio_region().n_channels()) {
+ break;
+ }
+
+ wave_caches.push_back (WaveView::create_cache ());
+
+ if (wait_for_data) {
+ if (audio_region().source(n).peaks_ready (bind (mem_fun(*this, &AudioRegionView::peaks_ready_handler), n), data_ready_connection)) {
+ create_one_wave (n, true);
+ } else {
+ create_zero_line = false;
+ }
+ } else {
+ create_one_wave (n, true);
+ }
+ }
+
+ if (create_zero_line) {
+ zero_line = new ArdourCanvas::SimpleLine (*group);
+ zero_line->property_x1() = (gdouble) 1.0;
+ zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0;
+ zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
+ manage_zero_line ();
+ }
+}
+
+void
+AudioRegionView::create_one_wave (uint32_t which, bool direct)
+{
+ RouteTimeAxisView& atv (*(dynamic_cast<RouteTimeAxisView*>(&trackview))); // ick
+ uint32_t nchans = atv.get_diskstream()->n_channels();
+ uint32_t n;
+ uint32_t nwaves = std::min (nchans, audio_region().n_channels());
+ gdouble ht;
+
+ if (trackview.height < NAME_HIGHLIGHT_SIZE) {
+ ht = ((trackview.height) / (double) nchans);
+ } else {
+ ht = ((trackview.height - NAME_HIGHLIGHT_SIZE) / (double) nchans);
+ }
+
+ gdouble yoff = which * ht;
+
+ WaveView *wave = new WaveView(*group);
+
+ wave->property_data_src() = (gpointer) &_region;
+ wave->property_cache() = wave_caches[which];
+ wave->property_cache_updater() = true;
+ wave->property_channel() = which;
+ wave->property_length_function() = (gpointer) region_length_from_c;
+ wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c;
+ wave->property_peak_function() = (gpointer) region_read_peaks_from_c;
+ wave->property_x() = 0.0;
+ wave->property_y() = yoff;
+ wave->property_height() = (double) ht;
+ wave->property_samples_per_unit() = samples_per_unit;
+ wave->property_amplitude_above_axis() = _amplitude_above_axis;
+ wave->property_wave_color() = _region.muted() ? color_map[cMutedWaveForm] : color_map[cWaveForm];
+ wave->property_region_start() = _region.start();
+
+ if (!(_flags & WaveformVisible)) {
+ wave->hide();
+ }
+
+ /* note: calling this function is serialized by the lock
+ held in the peak building thread that signals that
+ peaks are ready for use *or* by the fact that it is
+ called one by one from the GUI thread.
+ */
+
+ if (which < nchans) {
+ tmp_waves[which] = wave;
+ } else {
+ /* n-channel track, >n-channel source */
+ }
+
+ /* see if we're all ready */
+
+ for (n = 0; n < nchans; ++n) {
+ if (tmp_waves[n] == 0) {
+ break;
+ }
+ }
+
+ if (n == nwaves && waves.empty()) {
+ /* all waves are ready */
+ tmp_waves.resize(nwaves);
+
+ waves = tmp_waves;
+ tmp_waves.clear ();
+
+ if (!zero_line) {
+ zero_line = new ArdourCanvas::SimpleLine (*group);
+ zero_line->property_x1() = (gdouble) 1.0;
+ zero_line->property_x2() = (gdouble) (_region.length() / samples_per_unit) - 1.0;
+ zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
+ manage_zero_line ();
+ }
+ }
+}
+
+void
+AudioRegionView::peaks_ready_handler (uint32_t which)
+{
+ Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun(*this, &AudioRegionView::create_one_wave), which, false));
+
+ if (!waves.empty()) {
+ /* all waves created, don't hook into peaks ready anymore */
+ data_ready_connection.disconnect ();
+ }
+}
+
+void
+AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
+{
+ if (gain_line == 0) {
+ return;
+ }
+
+ double x, y;
+
+ /* don't create points that can't be seen */
+
+ set_envelope_visible (true);
+
+ x = ev->button.x;
+ y = ev->button.y;
+
+ item->w2i (x, y);
+
+ jack_nframes_t fx = trackview.editor.pixel_to_frame (x);
+
+ if (fx > _region.length()) {
+ return;
+ }
+
+ /* compute vertical fractional position */
+
+ y = 1.0 - (y / (trackview.height - NAME_HIGHLIGHT_SIZE));
+
+ /* map using gain line */
+
+ gain_line->view_to_model_y (y);
+
+ trackview.session().begin_reversible_command (_("add gain control point"));
+ trackview.session().add_undo (audio_region().envelope().get_memento());
+
+
+ if (!audio_region().envelope_active()) {
+ trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) );
+ audio_region().set_envelope_active(true);
+ trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) );
+ }
+
+ audio_region().envelope().add (fx, y);
+
+ trackview.session().add_redo_no_execute (audio_region().envelope().get_memento());
+ trackview.session().commit_reversible_command ();
+}
+
+void
+AudioRegionView::remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
+{
+ ControlPoint *cp = reinterpret_cast<ControlPoint *> (item->get_data ("control_point"));
+ audio_region().envelope().erase (cp->model);
+}
+
+void
+AudioRegionView::store_flags()
+{
+ XMLNode *node = new XMLNode ("GUI");
+
+ node->add_property ("waveform-visible", (_flags & WaveformVisible) ? "yes" : "no");
+ node->add_property ("envelope-visible", (_flags & EnvelopeVisible) ? "yes" : "no");
+
+ _region.add_extra_xml (*node);
+}
+
+void
+AudioRegionView::set_flags (XMLNode* node)
+{
+ XMLProperty *prop;
+
+ if ((prop = node->property ("waveform-visible")) != 0) {
+ if (prop->value() == "yes") {
+ _flags |= WaveformVisible;
+ }
+ }
+
+ if ((prop = node->property ("envelope-visible")) != 0) {
+ if (prop->value() == "yes") {
+ _flags |= EnvelopeVisible;
+ }
+ }
+}
+
+void
+AudioRegionView::set_waveform_shape (WaveformShape shape)
+{
+ bool yn;
+
+ /* this slightly odd approach is to leave the door open to
+ other "shapes" such as spectral displays, etc.
+ */
+
+ switch (shape) {
+ case Rectified:
+ yn = true;
+ break;
+
+ default:
+ yn = false;
+ break;
+ }
+
+ if (yn != (bool) (_flags & WaveformRectified)) {
+ for (vector<WaveView *>::iterator wave = waves.begin(); wave != waves.end() ; ++wave) {
+ (*wave)->property_rectified() = yn;
+ }
+
+ if (zero_line) {
+ if (yn) {
+ zero_line->hide();
+ } else {
+ zero_line->show();
+ }
+ }
+
+ if (yn) {
+ _flags |= WaveformRectified;
+ } else {
+ _flags &= ~WaveformRectified;
+ }
+ }
+}
+
+GhostRegion*
+AudioRegionView::add_ghost (AutomationTimeAxisView& atv)
+{
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&trackview);
+ assert(rtv);
+
+ double unit_position = _region.position () / samples_per_unit;
+ GhostRegion* ghost = new GhostRegion (atv, unit_position);
+ uint32_t nchans;
+
+ nchans = rtv->get_diskstream()->n_channels();
+
+ for (uint32_t n = 0; n < nchans; ++n) {
+
+ if (n >= audio_region().n_channels()) {
+ break;
+ }
+
+ WaveView *wave = new WaveView(*ghost->group);
+
+ wave->property_data_src() = &_region;
+ wave->property_cache() = wave_caches[n];
+ wave->property_cache_updater() = false;
+ wave->property_channel() = n;
+ wave->property_length_function() = (gpointer)region_length_from_c;
+ wave->property_sourcefile_length_function() = (gpointer) sourcefile_length_from_c;
+ wave->property_peak_function() = (gpointer) region_read_peaks_from_c;
+ wave->property_x() = 0.0;
+ wave->property_samples_per_unit() = samples_per_unit;
+ wave->property_amplitude_above_axis() = _amplitude_above_axis;
+ wave->property_wave_color() = color_map[cGhostTrackWave];
+ wave->property_region_start() = _region.start();
+
+ ghost->waves.push_back(wave);
+ }
+
+ ghost->set_height ();
+ ghost->set_duration (_region.length() / samples_per_unit);
+ ghosts.push_back (ghost);
+
+ ghost->GoingAway.connect (mem_fun(*this, &AudioRegionView::remove_ghost));
+
+ return ghost;
+}
+
+void
+AudioRegionView::entered ()
+{
+ if (gain_line && _flags & EnvelopeVisible) {
+ gain_line->show_all_control_points ();
+ }
+
+ uint32_t r,g,b,a;
+ UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
+ a=255;
+
+ if (fade_in_handle) {
+ fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
+ fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
+ }
+}
+
+void
+AudioRegionView::exited ()
+{
+ if (gain_line) {
+ gain_line->hide_all_but_selected_control_points ();
+ }
+
+ uint32_t r,g,b,a;
+ UINT_TO_RGBA(fade_color,&r,&g,&b,&a);
+ a=0;
+
+ if (fade_in_handle) {
+ fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
+ fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,a);
+ }
+}
+
+void
+AudioRegionView::envelope_active_changed ()
+{
+ if (gain_line) {
+ gain_line->set_line_color (audio_region().envelope_active() ? color_map[cGainLine] : color_map[cGainLineInactive]);
+ }
+}
+
+void
+AudioRegionView::set_waveview_data_src()
+{
+
+ double unit_length= _region.length() / samples_per_unit;
+
+ for (uint32_t n = 0; n < waves.size(); ++n) {
+ // TODO: something else to let it know the channel
+ waves[n]->property_data_src() = &_region;
+ }
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+
+ (*i)->set_duration (unit_length);
+
+ for (vector<WaveView*>::iterator w = (*i)->waves.begin(); w != (*i)->waves.end(); ++w) {
+ (*w)->property_data_src() = &_region;
+ }
+ }
+
+}
+
+void
+AudioRegionView::color_handler (ColorID id, uint32_t val)
+{
+ switch (id) {
+ case cMutedWaveForm:
+ case cWaveForm:
+ set_colors ();
+ break;
+
+ case cGainLineInactive:
+ case cGainLine:
+ envelope_active_changed();
+ break;
+
+ case cZeroLine:
+ if (zero_line) {
+ zero_line->property_color_rgba() = (guint) color_map[cZeroLine];
+ }
+ break;
+
+ case cGhostTrackWave:
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/gtk2_ardour/regionview.h b/gtk2_ardour/audio_region_view.h
index f49b46aea4..ec3ea6c4c5 100644
--- a/gtk2_ardour/regionview.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2001-2004 Paul Davis
+ Copyright (C) 2001-2006 Paul Davis
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
@@ -14,12 +14,10 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
*/
-#ifndef __gtk_ardour_region_view_h__
-#define __gtk_ardour_region_view_h__
+#ifndef __gtk_ardour_audio_region_view_h__
+#define __gtk_ardour_audio_region_view_h__
#include <vector>
@@ -28,6 +26,8 @@
#include <sigc++/signal.h>
#include <ardour/region.h>
+#include "region_view.h"
+#include "route_time_axis.h"
#include "time_axis_view_item.h"
#include "automation_line.h"
#include "enums.h"
@@ -46,51 +46,38 @@ class AudioRegionEditor;
class GhostRegion;
class AutomationTimeAxisView;
-class AudioRegionView : public TimeAxisViewItem
+class AudioRegionView : public RegionView
{
public:
AudioRegionView (ArdourCanvas::Group *,
- AudioTimeAxisView&,
+ RouteTimeAxisView&,
ARDOUR::AudioRegion&,
double initial_samples_per_unit,
Gdk::Color& basic_color);
~AudioRegionView ();
- virtual void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves);
+ virtual void init (Gdk::Color& base_color, bool wait_for_data = false);
+
+ ARDOUR::AudioRegion& audio_region() const;
- ARDOUR::AudioRegion& region; // ok, let 'em have it
- bool is_valid() const { return valid; }
- void set_valid (bool yn) { valid = yn; }
-
void set_height (double);
void set_samples_per_unit (double);
- bool set_duration (jack_nframes_t, void*);
void set_amplitude_above_axis (gdouble spp);
- void move (double xdelta, double ydelta);
-
- void raise ();
- void raise_to_top ();
- void lower ();
- void lower_to_bottom ();
-
- bool set_position(jack_nframes_t pos, void* src, double* delta = 0);
-
- void temporarily_hide_envelope (); // dangerous
- void unhide_envelope (); // dangerous
+ void temporarily_hide_envelope (); ///< Dangerous!
+ void unhide_envelope (); ///< Dangerous!
void set_envelope_visible (bool);
void set_waveform_visible (bool yn);
void set_waveform_shape (WaveformShape);
bool waveform_rectified() const { return _flags & WaveformRectified; }
- bool waveform_visible() const { return _flags & WaveformVisible; }
- bool envelope_visible() const { return _flags & EnvelopeVisible; }
+ bool waveform_visible() const { return _flags & WaveformVisible; }
+ bool envelope_visible() const { return _flags & EnvelopeVisible; }
void show_region_editor ();
- void hide_region_editor();
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
@@ -100,19 +87,13 @@ class AudioRegionView : public TimeAxisViewItem
void region_changed (ARDOUR::Change);
void envelope_active_changed ();
- static sigc::signal<void,AudioRegionView*> AudioRegionViewGoingAway;
- sigc::signal<void> GoingAway;
-
GhostRegion* add_ghost (AutomationTimeAxisView&);
- void remove_ghost (GhostRegion*);
void reset_fade_in_shape_width (jack_nframes_t);
void reset_fade_out_shape_width (jack_nframes_t);
void set_fade_in_active (bool);
void set_fade_out_active (bool);
- uint32_t get_fill_color ();
-
virtual void entered ();
virtual void exited ();
@@ -124,44 +105,18 @@ class AudioRegionView : public TimeAxisViewItem
*/
AudioRegionView (ArdourCanvas::Group *,
- AudioTimeAxisView&,
- ARDOUR::AudioRegion&,
- double initial_samples_per_unit,
- Gdk::Color& basic_color,
- TimeAxisViewItem::Visibility);
+ RouteTimeAxisView&,
+ ARDOUR::AudioRegion&,
+ double samples_per_unit,
+ Gdk::Color& basic_color,
+ TimeAxisViewItem::Visibility);
enum Flags {
EnvelopeVisible = 0x1,
WaveformVisible = 0x4,
WaveformRectified = 0x8
};
-
- vector<ArdourCanvas::WaveView *> waves; /* waveviews */
- vector<ArdourCanvas::WaveView *> tmp_waves; /* see ::create_waves()*/
- ArdourCanvas::Polygon* sync_mark; /* polgyon for sync position */
- ArdourCanvas::Text* no_wave_msg; /* text */
- ArdourCanvas::SimpleLine* zero_line; /* simpleline */
- ArdourCanvas::Polygon* fade_in_shape; /* polygon */
- ArdourCanvas::Polygon* fade_out_shape; /* polygon */
- ArdourCanvas::SimpleRect* fade_in_handle; /* simplerect */
- ArdourCanvas::SimpleRect* fade_out_handle; /* simplerect */
-
- AudioRegionGainLine* gain_line;
- AudioRegionEditor *editor;
-
- vector<ControlPoint *> control_points;
- double _amplitude_above_axis;
- double current_visible_sync_position;
-
- uint32_t _flags;
- uint32_t fade_color;
- bool valid; /* see StreamView::redisplay_diskstream() */
- double _pixel_width;
- double _height;
- bool in_destructor;
- bool wait_for_waves;
- sigc::connection peaks_ready_connection;
-
+
void reset_fade_shapes ();
void reset_fade_in_shape ();
void reset_fade_out_shape ();
@@ -173,34 +128,37 @@ class AudioRegionView : public TimeAxisViewItem
void region_resized (ARDOUR::Change);
void region_moved (void *);
void region_muted ();
- void region_locked ();
- void region_opacity ();
- void region_layered ();
- void region_renamed ();
- void region_sync_changed ();
void region_scale_amplitude_changed ();
- static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*);
- void lock_toggle ();
-
void create_waves ();
void create_one_wave (uint32_t, bool);
void manage_zero_line ();
void peaks_ready_handler (uint32_t);
- void reset_name (gdouble width);
void set_flags (XMLNode *);
void store_flags ();
void set_colors ();
void compute_colors (Gdk::Color&);
- virtual void set_frame_color ();
void reset_width_dependent_items (double pixel_width);
void set_waveview_data_src();
+
+ void color_handler (ColorID, uint32_t);
vector<GnomeCanvasWaveViewCache*> wave_caches;
- vector<GhostRegion*> ghosts;
-
- void color_handler (ColorID, uint32_t);
+ vector<ArdourCanvas::WaveView *> waves;
+ vector<ArdourCanvas::WaveView *> tmp_waves; ///< see ::create_waves()
+ ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
+ ArdourCanvas::SimpleLine* zero_line;
+ ArdourCanvas::Polygon* fade_in_shape;
+ ArdourCanvas::Polygon* fade_out_shape;
+ ArdourCanvas::SimpleRect* fade_in_handle;
+ ArdourCanvas::SimpleRect* fade_out_handle;
+ AudioRegionGainLine* gain_line;
+
+ double _amplitude_above_axis;
+
+ uint32_t _flags;
+ uint32_t fade_color;
};
-#endif /* __gtk_ardour_region_view_h__ */
+#endif /* __gtk_ardour_audio_region_view_h__ */
diff --git a/gtk2_ardour/regionview.cc b/gtk2_ardour/audio_regionview.cc
index dcc71a03c4..e2d20c0cc0 100644
--- a/gtk2_ardour/regionview.cc
+++ b/gtk2_ardour/audio_regionview.cc
@@ -15,7 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
+ $Id: regionview.cc 678 2006-07-11 15:45:19Z paul $
*/
#include <cmath>
@@ -29,10 +29,9 @@
#include <ardour/audioregion.h>
#include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
-#include <pbd/memento_command.h>
#include "streamview.h"
-#include "regionview.h"
+#include "region_view.h"
#include "audio_time_axis.h"
#include "simplerect.h"
#include "simpleline.h"
@@ -519,7 +518,7 @@ AudioRegionView::set_height (gdouble height)
for (uint32_t n=0; n < wcnt; ++n) {
gdouble ht;
- if ((height) < NAME_HIGHLIGHT_THRESH) {
+ if ((height) <= NAME_HIGHLIGHT_THRESH) {
ht = ((height-2*wcnt) / (double) wcnt);
} else {
ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
@@ -1145,20 +1144,18 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
gain_line->view_to_model_y (y);
trackview.session().begin_reversible_command (_("add gain control point"));
- XMLNode &before = region.envelope().get_state();
+ trackview.session().add_undo (region.envelope().get_memento());
if (!region.envelope_active()) {
- XMLNode &before = region.get_state();
+ trackview.session().add_undo( bind( mem_fun(region, &AudioRegion::set_envelope_active), false) );
region.set_envelope_active(true);
- XMLNode &after = region.get_state();
- trackview.session().add_command(new MementoCommand<AudioRegion>(region, before, after));
+ trackview.session().add_redo( bind( mem_fun(region, &AudioRegion::set_envelope_active), true) );
}
region.envelope().add (fx, y);
- XMLNode &after = region.envelope().get_state();
- trackview.session().add_command(new MementoCommand<Curve>(region.envelope(), before, after));
+ trackview.session().add_redo_no_execute (region.envelope().get_memento());
trackview.session().commit_reversible_command ();
}
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
new file mode 100644
index 0000000000..82349947c6
--- /dev/null
+++ b/gtk2_ardour/audio_streamview.cc
@@ -0,0 +1,700 @@
+/*
+ Copyright (C) 2001, 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <cmath>
+#include <cassert>
+
+#include <gtkmm.h>
+
+#include <gtkmm2ext/gtk_ui.h>
+
+#include <ardour/audioplaylist.h>
+#include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
+#include <ardour/audio_track.h>
+#include <ardour/playlist_templates.h>
+#include <ardour/source.h>
+
+#include "audio_streamview.h"
+#include "audio_region_view.h"
+#include "tape_region_view.h"
+#include "audio_time_axis.h"
+#include "canvas-waveview.h"
+#include "canvas-simplerect.h"
+#include "region_selection.h"
+#include "selection.h"
+#include "public_editor.h"
+#include "ardour_ui.h"
+#include "crossfade_view.h"
+#include "rgb_macros.h"
+#include "gui_thread.h"
+#include "utils.h"
+#include "color.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Editing;
+
+AudioStreamView::AudioStreamView (AudioTimeAxisView& tv)
+ : StreamView (tv)
+{
+ crossfades_visible = true;
+
+ if (tv.is_audio_track())
+ stream_base_color = color_map[cAudioTrackBase];
+ else
+ stream_base_color = color_map[cAudioBusBase];
+
+ canvas_rect->property_fill_color_rgba() = stream_base_color;
+ canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline];
+
+ _amplitude_above_axis = 1.0;
+
+ use_rec_regions = tv.editor.show_waveforms_recording ();
+ last_rec_peak_frame = 0;
+}
+
+AudioStreamView::~AudioStreamView ()
+{
+}
+
+int
+AudioStreamView::set_height (gdouble h)
+{
+ /* limit the values to something sane-ish */
+ if (h < 10.0 || h > 1000.0) {
+ return -1;
+ }
+
+ StreamView::set_height(h);
+
+ for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ (*i)->set_height (h);
+ }
+
+ return 0;
+}
+
+int
+AudioStreamView::set_samples_per_unit (gdouble spp)
+{
+ StreamView::set_samples_per_unit(spp);
+
+ for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
+ (*xi)->set_samples_per_unit (spp);
+ }
+
+ return 0;
+}
+
+int
+AudioStreamView::set_amplitude_above_axis (gdouble app)
+{
+ RegionViewList::iterator i;
+
+ if (app < 1.0) {
+ return -1;
+ }
+
+ _amplitude_above_axis = app;
+
+ for (i = region_views.begin(); i != region_views.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->set_amplitude_above_axis (app);
+ }
+
+ return 0;
+}
+
+void
+AudioStreamView::add_region_view_internal (Region *r, bool wait_for_waves)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
+
+ AudioRegion* region = dynamic_cast<AudioRegion*> (r);
+
+ if (region == 0) {
+ return;
+ }
+
+ AudioRegionView *region_view;
+ list<RegionView *>::iterator i;
+
+ for (i = region_views.begin(); i != region_views.end(); ++i) {
+ if (&(*i)->region() == r) {
+
+ /* great. we already have a AudioRegionView for this Region. use it again. */
+
+ (*i)->set_valid (true);
+ return;
+ }
+ }
+
+ switch (_trackview.audio_track()->mode()) {
+ case Normal:
+ region_view = new AudioRegionView (canvas_group, _trackview, *region,
+ _samples_per_unit, region_color);
+ break;
+ case Destructive:
+ region_view = new TapeAudioRegionView (canvas_group, _trackview, *region,
+ _samples_per_unit, region_color);
+ break;
+ }
+
+ region_view->init (region_color, wait_for_waves);
+ region_view->set_amplitude_above_axis(_amplitude_above_axis);
+ region_views.push_front (region_view);
+
+ /* follow global waveform setting */
+
+ region_view->set_waveform_visible(_trackview.editor.show_waveforms());
+
+ /* catch regionview going away */
+
+ region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_region_view));
+
+ RegionViewAdded (region_view);
+}
+
+void
+AudioStreamView::remove_region_view (Region *r)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_region_view), r));
+
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
+ list<CrossfadeView*>::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ AudioRegion* ar = dynamic_cast<AudioRegion*>(r);
+ if (ar && (*i)->crossfade.involves (*ar)) {
+ delete *i;
+ crossfade_views.erase (i);
+ }
+
+ i = tmp;
+ }
+
+ StreamView::remove_region_view(r);
+}
+
+void
+AudioStreamView::undisplay_diskstream ()
+{
+ StreamView::undisplay_diskstream();
+
+ for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ delete *i;
+ }
+
+ crossfade_views.clear ();
+}
+
+void
+AudioStreamView::playlist_modified ()
+{
+ ENSURE_GUI_THREAD (mem_fun (*this, &AudioStreamView::playlist_modified));
+
+ StreamView::playlist_modified();
+
+ /* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked
+ correctly.
+ */
+
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ (*i)->get_canvas_group()->raise_to_top();
+ }
+}
+
+void
+AudioStreamView::playlist_changed (Diskstream *ds)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::playlist_changed), ds));
+
+ StreamView::playlist_changed(ds);
+
+ AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(ds->playlist());
+ if (apl)
+ playlist_connections.push_back (apl->NewCrossfade.connect (mem_fun (*this, &AudioStreamView::add_crossfade)));
+}
+
+void
+AudioStreamView::add_crossfade (Crossfade *crossfade)
+{
+ AudioRegionView* lview = 0;
+ AudioRegionView* rview = 0;
+
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_crossfade), crossfade));
+
+ /* first see if we already have a CrossfadeView for this Crossfade */
+
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ if (&(*i)->crossfade == crossfade) {
+ if (!crossfades_visible) {
+ (*i)->hide();
+ } else {
+ (*i)->show ();
+ }
+ (*i)->set_valid (true);
+ return;
+ }
+ }
+
+ /* create a new one */
+
+ for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
+
+ if (!lview && arv && &(arv->region()) == &crossfade->out()) {
+ lview = arv;
+ }
+ if (!rview && arv && &(arv->region()) == &crossfade->in()) {
+ rview = arv;
+ }
+ }
+
+ CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
+ _trackview,
+ *crossfade,
+ _samples_per_unit,
+ region_color,
+ *lview, *rview);
+
+ crossfade->Invalidated.connect (mem_fun (*this, &AudioStreamView::remove_crossfade));
+ crossfade_views.push_back (cv);
+
+ if (!crossfades_visible) {
+ cv->hide ();
+ }
+}
+
+void
+AudioStreamView::remove_crossfade (Crossfade *xfade)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::remove_crossfade), xfade));
+
+ for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ if (&(*i)->crossfade == xfade) {
+ delete *i;
+ crossfade_views.erase (i);
+ break;
+ }
+ }
+}
+
+void
+AudioStreamView::redisplay_diskstream ()
+{
+ list<RegionView *>::iterator i, tmp;
+ list<CrossfadeView*>::iterator xi, tmpx;
+
+
+ for (i = region_views.begin(); i != region_views.end(); ++i) {
+ (*i)->set_valid (false);
+ }
+
+ for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
+ (*xi)->set_valid (false);
+ if ((*xi)->visible()) {
+ (*xi)->show ();
+ }
+ }
+
+ if (_trackview.is_audio_track()) {
+ _trackview.get_diskstream()->playlist()->foreach_region (static_cast<StreamView*>(this), &StreamView::add_region_view);
+ AudioPlaylist* apl = dynamic_cast<AudioPlaylist*>(_trackview.get_diskstream()->playlist());
+ if (apl)
+ apl->foreach_crossfade (this, &AudioStreamView::add_crossfade);
+ }
+
+ for (i = region_views.begin(); i != region_views.end(); ) {
+ tmp = i;
+ tmp++;
+
+ if (!(*i)->is_valid()) {
+ delete *i;
+ region_views.erase (i);
+ }
+
+ i = tmp;
+ }
+
+ for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
+ tmpx = xi;
+ tmpx++;
+
+ if (!(*xi)->valid()) {
+ delete *xi;
+ crossfade_views.erase (xi);
+ }
+
+ xi = tmpx;
+ }
+
+ /* now fix layering */
+
+ playlist_modified ();
+}
+
+void
+AudioStreamView::set_show_waveforms (bool yn)
+{
+ for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->set_waveform_visible (yn);
+ }
+}
+
+void
+AudioStreamView::set_waveform_shape (WaveformShape shape)
+{
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->set_waveform_shape (shape);
+ }
+}
+
+void
+AudioStreamView::setup_rec_box ()
+{
+ // cerr << _trackview.name() << " streamview SRB\n";
+
+ if (_trackview.session().transport_rolling()) {
+
+ // cerr << "\trolling\n";
+
+ if (!rec_active &&
+ _trackview.session().record_status() == Session::Recording &&
+ _trackview.get_diskstream()->record_enabled()) {
+
+ if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
+
+ /* add a new region, but don't bother if they set use_rec_regions mid-record */
+
+ AudioRegion::SourceList sources;
+
+ for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
+ (*prc).disconnect();
+ }
+ peak_ready_connections.clear();
+
+ // FIXME
+ AudioDiskstream* ads = dynamic_cast<AudioDiskstream*>(_trackview.get_diskstream());
+ assert(ads);
+
+ for (uint32_t n=0; n < ads->n_channels(); ++n) {
+ AudioSource *src = (AudioSource *) ads->write_source (n);
+ if (src) {
+ sources.push_back (src);
+ peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), src)));
+ }
+ }
+
+ // handle multi
+
+ jack_nframes_t start = 0;
+ if (rec_regions.size() > 0) {
+ start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1);
+ }
+
+ AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false);
+ region->set_position (_trackview.session().transport_frame(), this);
+ rec_regions.push_back (region);
+ /* catch it if it goes away */
+ region->GoingAway.connect (mem_fun (*this, &AudioStreamView::remove_rec_region));
+
+ /* we add the region later */
+ }
+
+ /* start a new rec box */
+
+ AudioTrack* at;
+
+ at = _trackview.audio_track(); /* we know what it is already */
+ AudioDiskstream& ds = at->audio_diskstream();
+ jack_nframes_t frame_pos = ds.current_capture_start ();
+ gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
+ gdouble xend;
+ uint32_t fill_color;
+
+ switch (_trackview.audio_track()->mode()) {
+ case Normal:
+ xend = xstart;
+ fill_color = color_map[cRecordingRectFill];
+ break;
+
+ case Destructive:
+ xend = xstart + 2;
+ fill_color = color_map[cRecordingRectFill];
+ /* make the recording rect translucent to allow
+ the user to see the peak data coming in, etc.
+ */
+ fill_color = UINT_RGBA_CHANGE_A (fill_color, 120);
+ break;
+ }
+
+ ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
+ rec_rect->property_x1() = xstart;
+ rec_rect->property_y1() = 1.0;
+ rec_rect->property_x2() = xend;
+ rec_rect->property_y2() = (double) _trackview.height - 1;
+ rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline];
+ rec_rect->property_fill_color_rgba() = fill_color;
+
+ RecBoxInfo recbox;
+ recbox.rectangle = rec_rect;
+ recbox.start = _trackview.session().transport_frame();
+ recbox.length = 0;
+
+ rec_rects.push_back (recbox);
+
+ screen_update_connection.disconnect();
+ screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &AudioStreamView::update_rec_box));
+ rec_updating = true;
+ rec_active = true;
+
+ } else if (rec_active &&
+ (_trackview.session().record_status() != Session::Recording ||
+ !_trackview.get_diskstream()->record_enabled())) {
+
+ screen_update_connection.disconnect();
+ rec_active = false;
+ rec_updating = false;
+
+ }
+
+ } else {
+
+ // cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
+
+ if (!rec_rects.empty() || !rec_regions.empty()) {
+
+ /* disconnect rapid update */
+ screen_update_connection.disconnect();
+
+ for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
+ (*prc).disconnect();
+ }
+ peak_ready_connections.clear();
+
+ rec_updating = false;
+ rec_active = false;
+ last_rec_peak_frame = 0;
+
+ /* remove temp regions */
+ for (list<Region*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); )
+ {
+ list<Region*>::iterator tmp;
+
+ tmp = iter;
+ ++tmp;
+
+ /* this will trigger the remove_region_view */
+ delete *iter;
+
+ iter = tmp;
+ }
+
+ rec_regions.clear();
+
+ // cerr << "\tclear " << rec_rects.size() << " rec rects\n";
+
+
+ /* transport stopped, clear boxes */
+ for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) {
+ RecBoxInfo &rect = (*iter);
+ delete rect.rectangle;
+ }
+
+ rec_rects.clear();
+
+ }
+ }
+}
+
+void
+AudioStreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
+{
+ for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ ((*i)->*pmf) ();
+ }
+}
+
+void
+AudioStreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
+{
+ // this is called from the peak building thread
+
+ ENSURE_GUI_THREAD(bind (mem_fun (*this, &AudioStreamView::rec_peak_range_ready), start, cnt, src));
+
+ if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
+ last_rec_peak_frame = start + cnt;
+ }
+
+ rec_peak_ready_map[src] = true;
+
+ if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) {
+ this->update_rec_regions ();
+ rec_peak_ready_map.clear();
+ }
+}
+
+void
+AudioStreamView::update_rec_regions ()
+{
+ if (use_rec_regions) {
+
+ uint32_t n = 0;
+
+ for (list<Region*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
+
+ list<Region*>::iterator tmp;
+
+ tmp = iter;
+ ++tmp;
+
+ if (!canvas_item_visible (rec_rects[n].rectangle)) {
+ /* rect already hidden, this region is done */
+ iter = tmp;
+ continue;
+ }
+
+ // FIXME
+ AudioRegion * region = dynamic_cast<AudioRegion*>(*iter);
+ assert(region);
+
+ jack_nframes_t origlen = region->length();
+
+ if (region == rec_regions.back() && rec_active) {
+
+ if (last_rec_peak_frame > region->start()) {
+
+ jack_nframes_t nlen = last_rec_peak_frame - region->start();
+
+ if (nlen != region->length()) {
+
+ region->freeze ();
+ region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
+ region->set_length (nlen, this);
+ region->thaw ("updated");
+
+ if (origlen == 1) {
+ /* our special initial length */
+ add_region_view_internal (region, false);
+ }
+
+ /* also update rect */
+ ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle;
+ gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length());
+ rect->property_x2() = xend;
+ }
+ }
+
+ } else {
+
+ jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
+
+ if (nlen != region->length()) {
+
+ if (region->source(0).length() >= region->start() + nlen) {
+
+ region->freeze ();
+ region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
+ region->set_length (nlen, this);
+ region->thaw ("updated");
+
+ if (origlen == 1) {
+ /* our special initial length */
+ add_region_view_internal (region, false);
+ }
+
+ /* also hide rect */
+ ArdourCanvas::Item * rect = rec_rects[n].rectangle;
+ rect->hide();
+
+ }
+ }
+ }
+
+ iter = tmp;
+ }
+ }
+}
+
+void
+AudioStreamView::show_all_xfades ()
+{
+ foreach_crossfadeview (&CrossfadeView::show);
+ crossfades_visible = true;
+}
+
+void
+AudioStreamView::hide_all_xfades ()
+{
+ foreach_crossfadeview (&CrossfadeView::hide);
+ crossfades_visible = false;
+}
+
+void
+AudioStreamView::hide_xfades_involving (AudioRegionView& rv)
+{
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ if ((*i)->crossfade.involves (rv.audio_region())) {
+ (*i)->fake_hide ();
+ }
+ }
+}
+
+void
+AudioStreamView::reveal_xfades_involving (AudioRegionView& rv)
+{
+ for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ if ((*i)->crossfade.involves (rv.audio_region()) && (*i)->visible()) {
+ (*i)->show ();
+ }
+ }
+}
+
+void
+AudioStreamView::color_handler (ColorID id, uint32_t val)
+{
+ switch (id) {
+ case cAudioTrackBase:
+ if (_trackview.is_track()) {
+ canvas_rect->property_fill_color_rgba() = val;
+ }
+ break;
+ case cAudioBusBase:
+ if (!_trackview.is_track()) {
+ canvas_rect->property_fill_color_rgba() = val;
+ }
+ break;
+ case cAudioTrackOutline:
+ canvas_rect->property_outline_color_rgba() = val;
+ break;
+
+ default:
+ break;
+ }
+}
+
diff --git a/gtk2_ardour/audio_streamview.h b/gtk2_ardour/audio_streamview.h
new file mode 100644
index 0000000000..05ce8125f6
--- /dev/null
+++ b/gtk2_ardour/audio_streamview.h
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2001, 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_audio_streamview_h__
+#define __ardour_audio_streamview_h__
+
+#include <list>
+#include <map>
+#include <cmath>
+
+#include <ardour/location.h>
+#include "enums.h"
+#include "simplerect.h"
+#include "color.h"
+#include "streamview.h"
+
+namespace Gdk {
+ class Color;
+}
+
+namespace ARDOUR {
+ class Route;
+ class Diskstream;
+ class Crossfade;
+ class PeakData;
+ class AudioRegion;
+ class Source;
+}
+
+class PublicEditor;
+class Selectable;
+class AudioTimeAxisView;
+class AudioRegionView;
+class RegionSelection;
+class CrossfadeView;
+class Selection;
+
+class AudioStreamView : public StreamView
+{
+ public:
+ AudioStreamView (AudioTimeAxisView&);
+ ~AudioStreamView ();
+
+ void set_waveform_shape (WaveformShape);
+
+ int set_height (gdouble h);
+ int set_samples_per_unit (gdouble spp);
+
+ int set_amplitude_above_axis (gdouble app);
+ gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
+
+ void set_show_waveforms (bool yn);
+ void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; }
+
+ void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
+
+ void show_all_xfades ();
+ void hide_all_xfades ();
+ void hide_xfades_involving (AudioRegionView&);
+ void reveal_xfades_involving (AudioRegionView&);
+
+ private:
+ void setup_rec_box ();
+ void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src);
+ void update_rec_regions ();
+
+ void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves);
+ void remove_region_view (ARDOUR::Region* );
+ void remove_audio_region_view (ARDOUR::AudioRegion* );
+ void remove_audio_rec_region (ARDOUR::AudioRegion*);
+
+ void undisplay_diskstream ();
+ void redisplay_diskstream ();
+ void playlist_modified ();
+ void playlist_changed (ARDOUR::Diskstream *ds);
+
+ void add_crossfade (ARDOUR::Crossfade*);
+ void remove_crossfade (ARDOUR::Crossfade*);
+
+ void color_handler (ColorID id, uint32_t val);
+
+
+ double _amplitude_above_axis;
+
+ typedef list<CrossfadeView*> CrossfadeViewList;
+ CrossfadeViewList crossfade_views;
+ bool crossfades_visible;
+
+ list<sigc::connection> peak_ready_connections;
+ jack_nframes_t last_rec_peak_frame;
+ map<ARDOUR::Source*, bool> rec_peak_ready_map;
+
+};
+
+#endif /* __ardour_audio_streamview_h__ */
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index 857adff6b9..9ae94d1fe0 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <cmath>
+#include <cassert>
#include <algorithm>
#include <string>
@@ -32,16 +33,15 @@
#include <pbd/whitespace.h>
#include <pbd/memento_command.h>
-#include <gtkmm2ext/bindable_button.h>
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/selector.h>
#include <gtkmm2ext/stop_signal.h>
+#include <gtkmm2ext/bindable_button.h>
#include <gtkmm2ext/utils.h>
#include <ardour/audioplaylist.h>
#include <ardour/audio_diskstream.h>
#include <ardour/insert.h>
-#include <ardour/ladspa_plugin.h>
#include <ardour/location.h>
#include <ardour/panner.h>
#include <ardour/playlist.h>
@@ -53,27 +53,20 @@
#include "audio_time_axis.h"
#include "automation_gain_line.h"
#include "automation_pan_line.h"
-#include "automation_time_axis.h"
#include "canvas_impl.h"
#include "crossfade_view.h"
#include "enums.h"
#include "gain_automation_time_axis.h"
-#include "gui_thread.h"
#include "keyboard.h"
#include "pan_automation_time_axis.h"
#include "playlist_selector.h"
#include "plugin_selector.h"
#include "plugin_ui.h"
-#include "point_selection.h"
#include "prompter.h"
#include "public_editor.h"
-#include "redirect_automation_line.h"
-#include "redirect_automation_time_axis.h"
-#include "regionview.h"
-#include "rgb_macros.h"
-#include "selection.h"
+#include "audio_region_view.h"
#include "simplerect.h"
-#include "streamview.h"
+#include "audio_streamview.h"
#include "utils.h"
#include <ardour/audio_track.h>
@@ -82,202 +75,76 @@
using namespace ARDOUR;
using namespace PBD;
-using namespace LADSPA;
using namespace Gtk;
using namespace Editing;
-AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, Route& rt, Canvas& canvas)
- : AxisView(sess),
- RouteUI(rt, sess, _("m"), _("s"), _("r")), // mute, solo, and record
- TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas),
- parent_canvas (canvas),
- button_table (3, 3),
- edit_group_button (_("g")), // group
- playlist_button (_("p")),
- size_button (_("h")), // height
- automation_button (_("a")),
- visual_button (_("v"))
-
+AudioTimeAxisView::AudioTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
+ : AxisView(sess)
+ , RouteTimeAxisView(ed, sess, rt, canvas)
{
- _has_state = true;
+ // Make sure things are sane...
+ assert(!is_track() || is_audio_track());
+
subplugin_menu.set_name ("ArdourContextMenu");
- playlist_menu = 0;
- playlist_action_menu = 0;
- automation_action_menu = 0;
gain_track = 0;
pan_track = 0;
- view = 0;
- timestretch_rect = 0;
waveform_item = 0;
pan_automation_item = 0;
gain_automation_item = 0;
- no_redraw = false;
- view = new StreamView (*this);
+ _view = new AudioStreamView (*this);
add_gain_automation_child ();
add_pan_automation_child ();
ignore_toggle = false;
- rec_enable_button->set_active (false);
mute_button->set_active (false);
solo_button->set_active (false);
- rec_enable_button->set_name ("TrackRecordEnableButton");
- mute_button->set_name ("TrackMuteButton");
- solo_button->set_name ("SoloButton");
- edit_group_button.set_name ("TrackGroupButton");
- playlist_button.set_name ("TrackPlaylistButton");
- automation_button.set_name ("TrackAutomationButton");
- size_button.set_name ("TrackSizeButton");
- visual_button.set_name ("TrackVisualButton");
- hide_button.set_name ("TrackRemoveButton");
-
- hide_button.add (*(manage (new Image (get_xpm("small_x.xpm")))));
-
- solo_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- mute_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- playlist_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- automation_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- size_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- visual_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
- hide_button.signal_button_press_event().connect (mem_fun (*this, &AudioTimeAxisView::select_me), false);
-
- solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false);
- solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false);
- mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false);
- mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false);
- rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
- edit_group_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::edit_click), false);
- playlist_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::playlist_click));
- automation_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::automation_click));
- size_button.signal_button_release_event().connect (mem_fun(*this, &AudioTimeAxisView::size_click), false);
- visual_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::visual_click));
- hide_button.signal_clicked().connect (mem_fun(*this, &AudioTimeAxisView::hide_click));
-
- if (is_audio_track()) {
- controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
- }
- controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
- controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0);
-
- controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
-
- ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record"));
- ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo"));
- ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute"));
- ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group"));
- ARDOUR_UI::instance()->tooltips().set_tip(size_button,_("Display Height"));
- ARDOUR_UI::instance()->tooltips().set_tip(playlist_button,_("Playlist"));
- ARDOUR_UI::instance()->tooltips().set_tip(automation_button, _("Automation"));
- ARDOUR_UI::instance()->tooltips().set_tip(visual_button, _("Visual options"));
- ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("Hide this track"));
-
- label_view ();
-
- controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
-
- if (is_audio_track() && audio_track()->mode() == ARDOUR::Normal) {
- controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- }
-
- /* remove focus from the buttons */
-
- automation_button.unset_flags (Gtk::CAN_FOCUS);
- solo_button->unset_flags (Gtk::CAN_FOCUS);
- mute_button->unset_flags (Gtk::CAN_FOCUS);
- edit_group_button.unset_flags (Gtk::CAN_FOCUS);
- size_button.unset_flags (Gtk::CAN_FOCUS);
- playlist_button.unset_flags (Gtk::CAN_FOCUS);
- hide_button.unset_flags (Gtk::CAN_FOCUS);
- visual_button.unset_flags (Gtk::CAN_FOCUS);
+ if (is_audio_track())
+ controls_ebox.set_name ("AudioTimeAxisViewControlsBaseUnselected");
+ else // bus
+ controls_ebox.set_name ("AudioBusControlsBaseUnselected");
/* map current state of the route */
- update_diskstream_display ();
- solo_changed(0);
- mute_changed(0);
redirects_changed (0);
reset_redirect_automation_curves ();
- y_position = -1;
ensure_xml_node ();
set_state (*xml_node);
- _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
- _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
- _route.redirects_changed.connect (mem_fun(*this, &AudioTimeAxisView::redirects_changed));
- _route.name_changed.connect (mem_fun(*this, &AudioTimeAxisView::route_name_changed));
- _route.solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
- _route.panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
+ _route->panner().Changed.connect (mem_fun(*this, &AudioTimeAxisView::update_pans));
if (is_audio_track()) {
- /* track */
-
- audio_track()->FreezeChange.connect (mem_fun(*this, &AudioTimeAxisView::map_frozen));
-
- audio_track()->diskstream_changed.connect (mem_fun(*this, &AudioTimeAxisView::diskstream_changed));
- get_diskstream()->speed_changed.connect (mem_fun(*this, &AudioTimeAxisView::speed_changed));
-
controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
controls_base_selected_name = "AudioTrackControlsBaseSelected";
controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
/* ask for notifications of any new RegionViews */
+ _view->RegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added));
+ _view->attach ();
- view->AudioRegionViewAdded.connect (mem_fun(*this, &AudioTimeAxisView::region_view_added));
-
- view->attach ();
-
- /* pick up the correct freeze state */
-
- map_frozen ();
+ } else { /* bus */
- } else {
-
- /* bus */
-
- controls_ebox.set_name ("BusControlsBaseUnselected");
- controls_base_selected_name = "BusControlsBaseSelected";
- controls_base_unselected_name = "BusControlsBaseUnselected";
+ controls_ebox.set_name ("AudioBusControlsBaseUnselected");
+ controls_base_selected_name = "AudioBusControlsBaseSelected";
+ controls_base_unselected_name = "AudioBusControlsBaseUnselected";
}
-
- editor.ZoomChanged.connect (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit));
- ColorChanged.connect (mem_fun (*this, &AudioTimeAxisView::color_handler));
}
AudioTimeAxisView::~AudioTimeAxisView ()
{
- GoingAway (); /* EMIT_SIGNAL */
-
- if (playlist_menu) {
- delete playlist_menu;
- playlist_menu = 0;
- }
-
- if (playlist_action_menu) {
- delete playlist_action_menu;
- playlist_action_menu = 0;
- }
-
- vector_delete (&redirect_automation_curves);
-
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
- delete *i;
- }
+}
- if (view) {
- delete view;
- view = 0;
- }
+AudioStreamView*
+AudioTimeAxisView::audio_view()
+{
+ return dynamic_cast<AudioStreamView*>(_view);
}
guint32
@@ -299,233 +166,6 @@ AudioTimeAxisView::hide ()
}
void
-AudioTimeAxisView::set_playlist (AudioPlaylist *newplaylist)
-{
- AudioPlaylist *pl;
-
- modified_connection.disconnect ();
- state_changed_connection.disconnect ();
-
- if ((pl = dynamic_cast<AudioPlaylist*> (playlist())) != 0) {
- state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed));
- modified_connection = pl->Modified.connect (mem_fun(*this, &AudioTimeAxisView::playlist_modified));
- }
-}
-
-void
-AudioTimeAxisView::playlist_modified ()
-{
-}
-
-gint
-AudioTimeAxisView::edit_click (GdkEventButton *ev)
-{
- if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
- _route.set_edit_group (0, this);
- return FALSE;
- }
-
- using namespace Menu_Helpers;
-
- MenuList& items = edit_group_menu.items ();
- RadioMenuItem::Group group;
-
- items.clear ();
- items.push_back (RadioMenuElem (group, _("No group"),
- bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0)));
-
- if (_route.edit_group() == 0) {
- static_cast<RadioMenuItem*>(&items.back())->set_active ();
- }
-
- _session.foreach_edit_group (bind (mem_fun (*this, &AudioTimeAxisView::add_edit_group_menu_item), &group));
- edit_group_menu.popup (ev->button, ev->time);
-
- return FALSE;
-}
-
-void
-AudioTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Group* group)
-{
- using namespace Menu_Helpers;
-
- MenuList &items = edit_group_menu.items();
-
- cerr << "adding edit group called " << eg->name() << endl;
-
- items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &AudioTimeAxisView::set_edit_group_from_menu), eg)));
- if (_route.edit_group() == eg) {
- static_cast<RadioMenuItem*>(&items.back())->set_active ();
- }
-}
-
-void
-AudioTimeAxisView::set_edit_group_from_menu (RouteGroup *eg)
-
-{
- _route.set_edit_group (eg, this);
-}
-
-void
-AudioTimeAxisView::playlist_state_changed (Change ignored)
-{
- // ENSURE_GUI_THREAD (bind (mem_fun(*this, &AudioTimeAxisView::playlist_state_changed), ignored));
- // why are we here ?
-}
-
-void
-AudioTimeAxisView::playlist_changed ()
-
-{
- label_view ();
-
- if (is_audio_track()) {
- set_playlist (get_diskstream()->playlist());
- }
-}
-
-void
-AudioTimeAxisView::label_view ()
-{
- string x = _route.name();
-
- if (x != name_entry.get_text()) {
- name_entry.set_text (x);
- }
-
- ARDOUR_UI::instance()->tooltips().set_tip (name_entry, x);
-}
-
-void
-AudioTimeAxisView::route_name_changed (void *src)
-{
- editor.route_name_changed (this);
- label_view ();
-}
-
-void
-AudioTimeAxisView::take_name_changed (void *src)
-
-{
- if (src != this) {
- label_view ();
- }
-}
-
-void
-AudioTimeAxisView::playlist_click ()
-{
- // always build a new action menu
-
- if (playlist_action_menu == 0) {
- playlist_action_menu = new Menu;
- playlist_action_menu->set_name ("ArdourContextMenu");
- }
-
- build_playlist_menu(playlist_action_menu);
-
- playlist_action_menu->popup (1, 0);
-}
-
-void
-AudioTimeAxisView::automation_click ()
-{
- if (automation_action_menu == 0) {
- /* this seems odd, but the automation action
- menu is built as part of the display menu.
- */
- build_display_menu ();
- }
- automation_action_menu->popup (1, 0);
-}
-
-void
-AudioTimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end)
-{
- double x1;
- double x2;
- double y2;
-
- TimeAxisView::show_timestretch (start, end);
-
- hide_timestretch ();
-
-#if 0
- if (ts.empty()) {
- return;
- }
-
-
- /* check that the time selection was made in our route, or our edit group.
- remember that edit_group() == 0 implies the route is *not* in a edit group.
- */
-
- if (!(ts.track == this || (ts.group != 0 && ts.group == _route.edit_group()))) {
- /* this doesn't apply to us */
- return;
- }
-
- /* ignore it if our edit group is not active */
-
- if ((ts.track != this) && _route.edit_group() && !_route.edit_group()->is_active()) {
- return;
- }
-#endif
-
- if (timestretch_rect == 0) {
- timestretch_rect = new SimpleRect (*canvas_display);
- timestretch_rect->property_x1() = 0.0;
- timestretch_rect->property_y1() = 0.0;
- timestretch_rect->property_x2() = 0.0;
- timestretch_rect->property_y2() = 0.0;
- timestretch_rect->property_fill_color_rgba() = color_map[cTimeStretchFill];
- timestretch_rect->property_outline_color_rgba() = color_map[cTimeStretchOutline];
- }
-
- timestretch_rect->show ();
- timestretch_rect->raise_to_top ();
-
- x1 = start / editor.get_current_zoom();
- x2 = (end - 1) / editor.get_current_zoom();
- y2 = height - 2;
-
- timestretch_rect->property_x1() = x1;
- timestretch_rect->property_y1() = 1.0;
- timestretch_rect->property_x2() = x2;
- timestretch_rect->property_y2() = y2;
-}
-
-void
-AudioTimeAxisView::hide_timestretch ()
-{
- TimeAxisView::hide_timestretch ();
-
- if (timestretch_rect) {
- timestretch_rect->hide ();
- }
-}
-
-void
-AudioTimeAxisView::show_selection (TimeSelection& ts)
-{
-
-#if 0
- /* ignore it if our edit group is not active or if the selection was started
- in some other track or edit group (remember that edit_group() == 0 means
- that the track is not in an edit group).
- */
-
- if (((ts.track != this && !is_child (ts.track)) && _route.edit_group() && !_route.edit_group()->is_active()) ||
- (!(ts.track == this || is_child (ts.track) || (ts.group != 0 && ts.group == _route.edit_group())))) {
- hide_selection ();
- return;
- }
-#endif
-
- TimeAxisView::show_selection (ts);
-}
-
-void
AudioTimeAxisView::set_state (const XMLNode& node)
{
const XMLProperty *prop;
@@ -578,153 +218,14 @@ AudioTimeAxisView::set_state (const XMLNode& node)
}
void
-AudioTimeAxisView::set_height (TrackHeight h)
-{
- bool height_changed = (height == 0) || (h != height_style);
-
- TimeAxisView::set_height (h);
-
- ensure_xml_node ();
-
- view->set_height ((double) height);
-
- switch (height_style) {
- case Largest:
- xml_node->add_property ("track_height", "largest");
- show_name_entry ();
- hide_name_label ();
- controls_table.show_all();
- break;
- case Large:
- xml_node->add_property ("track_height", "large");
- show_name_entry ();
- hide_name_label ();
- controls_table.show_all();
- break;
- case Larger:
- xml_node->add_property ("track_height", "larger");
- show_name_entry ();
- hide_name_label ();
- controls_table.show_all();
- break;
- case Normal:
- xml_node->add_property ("track_height", "normal");
- show_name_entry ();
- hide_name_label ();
- controls_table.show_all();
- break;
- case Smaller:
- xml_node->add_property ("track_height", "smaller");
- controls_table.show_all ();
- show_name_entry ();
- hide_name_label ();
- edit_group_button.hide ();
- hide_button.hide ();
- visual_button.hide ();
- size_button.hide ();
- automation_button.hide ();
- playlist_button.hide ();
- break;
- case Small:
- xml_node->add_property ("track_height", "small");
- controls_table.hide_all ();
- controls_table.show ();
- hide_name_entry ();
- show_name_label ();
- name_label.set_text (_route.name());
- break;
- }
-
- if (height_changed) {
- /* only emit the signal if the height really changed */
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
- }
-}
-
-void
-AudioTimeAxisView::select_track_color ()
-{
- if (RouteUI::choose_color ()) {
-
- if (view) {
- view->apply_color (_color, StreamView::RegionColor);
- }
- }
-}
-
-void
-AudioTimeAxisView::reset_redirect_automation_curves ()
-{
- for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) {
- (*i)->reset();
- }
-}
-
-void
-AudioTimeAxisView::reset_samples_per_unit ()
-{
- set_samples_per_unit (editor.get_current_zoom());
-}
-
-void
-AudioTimeAxisView::set_samples_per_unit (double spu)
-{
- double speed = 1.0;
-
- if (get_diskstream() != 0) {
- speed = get_diskstream()->speed();
- }
-
- if (view) {
- view->set_samples_per_unit (spu * speed);
- }
-
- TimeAxisView::set_samples_per_unit (spu * speed);
-}
-
-void
-AudioTimeAxisView::build_display_menu ()
+AudioTimeAxisView::build_automation_action_menu ()
{
using namespace Menu_Helpers;
- /* get the size menu ready */
-
- build_size_menu ();
-
- /* prepare it */
-
- TimeAxisView::build_display_menu ();
-
- /* now fill it with our stuff */
-
- MenuList& items = display_menu->items();
- display_menu->set_name ("ArdourContextMenu");
-
- items.push_back (MenuElem (_("Height"), *size_menu));
- items.push_back (MenuElem (_("Color"), mem_fun(*this, &AudioTimeAxisView::select_track_color)));
-
-
- items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades)));
- items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades)));
- items.push_back (SeparatorElem());
-
- build_remote_control_menu ();
- items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
+ RouteTimeAxisView::build_automation_action_menu ();
- automation_action_menu = manage (new Menu);
MenuList& automation_items = automation_action_menu->items();
- automation_action_menu->set_name ("ArdourContextMenu");
- automation_items.push_back (MenuElem (_("Show all automation"),
- mem_fun(*this, &AudioTimeAxisView::show_all_automation)));
-
- automation_items.push_back (MenuElem (_("Show existing automation"),
- mem_fun(*this, &AudioTimeAxisView::show_existing_automation)));
-
- automation_items.push_back (MenuElem (_("Hide all automation"),
- mem_fun(*this, &AudioTimeAxisView::hide_all_automation)));
-
automation_items.push_back (SeparatorElem());
automation_items.push_back (CheckMenuElem (_("Fader"),
@@ -736,11 +237,21 @@ AudioTimeAxisView::build_display_menu ()
mem_fun(*this, &AudioTimeAxisView::toggle_pan_track)));
pan_automation_item = static_cast<CheckMenuItem*> (&automation_items.back());
pan_automation_item->set_active(show_pan_automation);
+
+}
+
+void
+AudioTimeAxisView::append_extra_display_menu_items ()
+{
+ using namespace Menu_Helpers;
- automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu));
+ MenuList& items = display_menu->items();
- items.push_back (MenuElem (_("Automation"), *automation_action_menu));
+ // crossfade stuff
+ items.push_back (MenuElem (_("Hide all crossfades"), mem_fun(*this, &AudioTimeAxisView::hide_all_xfades)));
+ items.push_back (MenuElem (_("Show all crossfades"), mem_fun(*this, &AudioTimeAxisView::show_all_xfades)));
+ // waveform menu
Menu *waveform_menu = manage(new Menu);
MenuList& waveform_items = waveform_menu->items();
waveform_menu->set_name ("ArdourContextMenu");
@@ -760,401 +271,55 @@ AudioTimeAxisView::build_display_menu ()
rectified_item = static_cast<RadioMenuItem *> (&waveform_items.back());
items.push_back (MenuElem (_("Waveform"), *waveform_menu));
-
- if (is_audio_track()) {
-
- Menu* alignment_menu = manage (new Menu);
- MenuList& alignment_items = alignment_menu->items();
- alignment_menu->set_name ("ArdourContextMenu");
-
- RadioMenuItem::Group align_group;
-
- alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), ExistingMaterial)));
- align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
- if (get_diskstream()->alignment_style() == ExistingMaterial) {
- align_existing_item->set_active();
- }
- alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"), bind (mem_fun(*this, &AudioTimeAxisView::set_align_style), CaptureTime)));
- align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
- if (get_diskstream()->alignment_style() == CaptureTime) {
- align_capture_item->set_active();
- }
-
- items.push_back (MenuElem (_("Alignment"), *alignment_menu));
-
- get_diskstream()->AlignmentStyleChanged.connect (mem_fun(*this, &AudioTimeAxisView::align_style_changed));
- }
-
- items.push_back (SeparatorElem());
- items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active)));
- route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
- route_active_menu_item->set_active (_route.active());
-
- items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
-
-}
-
-void
-AudioTimeAxisView::align_style_changed ()
-{
- switch (get_diskstream()->alignment_style()) {
- case ExistingMaterial:
- if (!align_existing_item->get_active()) {
- align_existing_item->set_active();
- }
- break;
- case CaptureTime:
- if (!align_capture_item->get_active()) {
- align_capture_item->set_active();
- }
- break;
- }
-}
-
-void
-AudioTimeAxisView::set_align_style (AlignStyle style)
-{
- get_diskstream()->set_align_style (style);
-}
-
-void
-AudioTimeAxisView::rename_current_playlist ()
-{
- ArdourPrompter prompter (true);
- string name;
-
- AudioPlaylist *pl;
- AudioDiskstream *ds;
-
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
- return;
- }
-
- prompter.set_prompt (_("Name for playlist"));
- prompter.set_initial_text (pl->name());
- prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
- prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
-
- switch (prompter.run ()) {
- case Gtk::RESPONSE_ACCEPT:
- prompter.get_result (name);
- if (name.length()) {
- pl->set_name (name);
- }
- break;
-
- default:
- break;
- }
-}
-
-void
-AudioTimeAxisView::use_copy_playlist (bool prompt)
-{
- AudioPlaylist *pl;
- AudioDiskstream *ds;
- string name;
-
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
- return;
- }
-
- name = Playlist::bump_name (pl->name(), _session);
-
- if (prompt) {
-
- ArdourPrompter prompter (true);
-
- prompter.set_prompt (_("Name for Playlist"));
- prompter.set_initial_text (name);
- prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
- prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
- prompter.show_all ();
-
- switch (prompter.run ()) {
- case Gtk::RESPONSE_ACCEPT:
- prompter.get_result (name);
- break;
-
- default:
- return;
- }
- }
-
- if (name.length()) {
- ds->use_copy_playlist ();
- pl = ds->playlist();
- pl->set_name (name);
- }
-}
-
-void
-AudioTimeAxisView::use_new_playlist (bool prompt)
-{
- AudioPlaylist *pl;
- AudioDiskstream *ds;
- string name;
-
- if (((ds = get_diskstream()) == 0) || ds->destructive() || ((pl = ds->playlist()) == 0)) {
- return;
- }
-
- name = Playlist::bump_name (pl->name(), _session);
-
- if (prompt) {
-
- ArdourPrompter prompter (true);
-
- prompter.set_prompt (_("Name for Playlist"));
- prompter.set_initial_text (name);
- prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
- prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
-
- switch (prompter.run ()) {
- case Gtk::RESPONSE_ACCEPT:
- prompter.get_result (name);
- break;
-
- default:
- return;
- }
- }
-
- if (name.length()) {
- ds->use_new_playlist ();
- pl = ds->playlist();
- pl->set_name (name);
- }
-}
-
-void
-AudioTimeAxisView::clear_playlist ()
-{
- AudioPlaylist *pl;
- AudioDiskstream *ds;
-
- if ((ds = get_diskstream()) != 0) {
- if ((pl = ds->playlist()) != 0) {
- editor.clear_playlist (*pl);
- }
- }
}
void
AudioTimeAxisView::toggle_waveforms ()
{
- if (view && waveform_item && !ignore_toggle) {
- view->set_show_waveforms (waveform_item->get_active());
+ AudioStreamView* asv = audio_view();
+ assert(asv);
+
+ if (asv && waveform_item && !ignore_toggle) {
+ asv->set_show_waveforms (waveform_item->get_active());
}
}
void
AudioTimeAxisView::set_show_waveforms (bool yn)
{
+ AudioStreamView* asv = audio_view();
+ assert(asv);
+
if (waveform_item) {
waveform_item->set_active (yn);
} else {
- view->set_show_waveforms (yn);
+ asv->set_show_waveforms (yn);
}
}
void
AudioTimeAxisView::set_show_waveforms_recording (bool yn)
{
- if (view) {
- view->set_show_waveforms_recording (yn);
- }
-}
+ AudioStreamView* asv = audio_view();
-void
-AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
-{
- if (view) {
- view->set_waveform_shape (shape);
+ if (asv) {
+ asv->set_show_waveforms_recording (yn);
}
}
void
-AudioTimeAxisView::speed_changed ()
-{
- Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::reset_samples_per_unit));
-}
-
-void
-AudioTimeAxisView::diskstream_changed (void *src)
-{
- Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AudioTimeAxisView::update_diskstream_display));
-}
-
-void
-AudioTimeAxisView::update_diskstream_display ()
+AudioTimeAxisView::set_waveform_shape (WaveformShape shape)
{
- AudioDiskstream *ds;
+ AudioStreamView* asv = audio_view();
- if ((ds = get_diskstream()) != 0) {
- set_playlist (ds->playlist ());
+ if (asv) {
+ asv->set_waveform_shape (shape);
}
map_frozen ();
}
void
-AudioTimeAxisView::selection_click (GdkEventButton* ev)
-{
- PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route.edit_group());
-
- switch (Keyboard::selection_type (ev->state)) {
- case Selection::Toggle:
- /* XXX this is not right */
- editor.get_selection().add (*tracks);
- break;
-
- case Selection::Set:
- editor.get_selection().set (*tracks);
- break;
-
- case Selection::Extend:
- /* not defined yet */
- break;
- }
-
- delete tracks;
-}
-
-void
-AudioTimeAxisView::set_selected_regionviews (AudioRegionSelection& regions)
-{
- if (view) {
- view->set_selected_regionviews (regions);
- }
-}
-
-void
-AudioTimeAxisView::set_selected_points (PointSelection& points)
-{
- for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- (*i)->set_selected_points (points);
- }
-}
-
-void
-AudioTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results)
-{
- double speed = 1.0;
-
- if (get_diskstream() != 0) {
- speed = get_diskstream()->speed();
- }
-
- jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed);
- jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed);
-
- if (view && ((top < 0.0 && bot < 0.0)) || touched (top, bot)) {
- view->get_selectables (start_adjusted, end_adjusted, results);
- }
-
- /* pick up visible automation tracks */
-
- for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results);
- }
- }
-}
-
-void
-AudioTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
-{
- if (view) {
- view->get_inverted_selectables (sel, results);
- }
-
- for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->get_inverted_selectables (sel, results);
- }
- }
-
- return;
-}
-
-RouteGroup*
-AudioTimeAxisView::edit_group() const
-{
- return _route.edit_group();
-}
-
-string
-AudioTimeAxisView::name() const
-{
- return _route.name();
-}
-
-Playlist *
-AudioTimeAxisView::playlist () const
-{
- AudioDiskstream *ds;
-
- if ((ds = get_diskstream()) != 0) {
- return ds->playlist();
- } else {
- return 0;
- }
-}
-
-void
-AudioTimeAxisView::name_entry_changed ()
-{
- string x;
-
- x = name_entry.get_text ();
-
- if (x == _route.name()) {
- return;
- }
-
- if (x.length() == 0) {
- name_entry.set_text (_route.name());
- return;
- }
-
- strip_whitespace_edges(x);
-
- if (_session.route_name_unique (x)) {
- _route.set_name (x, this);
- } else {
- ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
- name_entry.set_text (_route.name());
- }
-}
-
-void
-AudioTimeAxisView::visual_click ()
-{
- popup_display_menu (0);
-}
-
-void
-AudioTimeAxisView::hide_click ()
-{
- editor.hide_track_in_display (*this);
-}
-
-Region*
-AudioTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
-{
- AudioDiskstream *stream;
- AudioPlaylist *playlist;
-
- if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
- return playlist->find_next_region (pos, point, dir);
- }
-
- return 0;
-}
-
-void
AudioTimeAxisView::add_gain_automation_child ()
{
XMLProperty* prop;
@@ -1166,13 +331,13 @@ AudioTimeAxisView::add_gain_automation_child ()
*this,
parent_canvas,
_("gain"),
- _route.gain_automation_curve());
+ _route->gain_automation_curve());
line = new AutomationGainLine ("automation gain",
_session,
*gain_track,
*gain_track->canvas_display,
- _route.gain_automation_curve());
+ _route->gain_automation_curve());
line->set_line_color (color_map[cAutomationLine]);
@@ -1241,11 +406,11 @@ AudioTimeAxisView::update_pans ()
/* we don't draw lines for "greater than stereo" panning.
*/
- if (_route.n_outputs() > 2) {
+ if (_route->n_outputs() > 2) {
return;
}
- for (p = _route.panner().begin(); p != _route.panner().end(); ++p) {
+ for (p = _route->panner().begin(); p != _route->panner().end(); ++p) {
AutomationLine* line;
@@ -1253,7 +418,7 @@ AudioTimeAxisView::update_pans ()
*pan_track->canvas_display,
(*p)->automation());
- if (p == _route.panner().begin()) {
+ if (p == _route->panner().begin()) {
/* first line is a nice orange */
line->set_line_color (color_map[cLeftPanAutomationLine]);
} else {
@@ -1285,7 +450,7 @@ AudioTimeAxisView::toggle_gain_track ()
/* now trigger a redisplay */
if (!no_redraw) {
- _route.gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed (X_("track_height"), (void *) 0); /* EMIT_SIGNAL */
}
}
}
@@ -1299,7 +464,7 @@ AudioTimeAxisView::gain_hidden ()
gain_automation_item->set_active (false);
}
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
@@ -1321,7 +486,7 @@ AudioTimeAxisView::toggle_pan_track ()
/* now trigger a redisplay */
if (!no_redraw) {
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
}
}
@@ -1335,322 +500,7 @@ AudioTimeAxisView::pan_hidden ()
pan_automation_item->set_active (false);
}
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-}
-
-AudioTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
-{
- for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
- delete *i;
- }
-}
-
-
-AudioTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
-{
- parent.remove_ran (this);
-
- if (view) {
- delete view;
- }
-}
-
-void
-AudioTimeAxisView::remove_ran (RedirectAutomationNode* ran)
-{
- if (ran->view) {
- remove_child (ran->view);
- }
-}
-
-AudioTimeAxisView::RedirectAutomationNode*
-AudioTimeAxisView::find_redirect_automation_node (Redirect *redirect, uint32_t what)
-{
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
-
- if ((*i)->redirect == redirect) {
-
- for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
- if ((*ii)->what == what) {
- return *ii;
- }
- }
- }
- }
-
- return 0;
-}
-
-static string
-legalize_for_xml_node (string str)
-{
- string::size_type pos;
- string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
- string legal;
-
- legal = str;
- pos = 0;
-
- while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
- legal.replace (pos, 1, "_");
- pos += 1;
- }
-
- return legal;
-}
-
-
-void
-AudioTimeAxisView::add_redirect_automation_curve (Redirect *redirect, uint32_t what)
-{
- RedirectAutomationLine* ral;
- string name;
- RedirectAutomationNode* ran;
-
- if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
- fatal << _("programming error: ")
- << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
- redirect->name(), what)
- << endmsg;
- /*NOTREACHED*/
- return;
- }
-
- if (ran->view) {
- return;
- }
-
- name = redirect->describe_parameter (what);
-
- /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
-
- char state_name[256];
- snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
-
- ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
-
- ral = new RedirectAutomationLine (name,
- *redirect, what, _session, *ran->view,
- *ran->view->canvas_display, redirect->automation_list (what));
-
- ral->set_line_color (color_map[cRedirectAutomationLine]);
- ral->queue_reset ();
-
- ran->view->add_line (*ral);
-
- ran->view->Hiding.connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_automation_track_hidden), ran, redirect));
-
- if (!ran->view->marked_for_display()) {
- ran->view->hide ();
- } else {
- ran->menu_item->set_active (true);
- }
-
- add_child (ran->view);
-
- view->foreach_regionview (bind (mem_fun(*this, &AudioTimeAxisView::add_ghost_to_redirect), ran->view));
-
- redirect->mark_automation_visible (what, true);
-}
-
-void
-AudioTimeAxisView::redirect_automation_track_hidden (AudioTimeAxisView::RedirectAutomationNode* ran, Redirect* r)
-{
- if (!_hidden) {
- ran->menu_item->set_active (false);
- }
-
- r->mark_automation_visible (ran->what, false);
-
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-}
-
-void
-AudioTimeAxisView::add_existing_redirect_automation_curves (Redirect *redirect)
-{
- set<uint32_t> s;
- RedirectAutomationLine *ral;
-
- redirect->what_has_visible_automation (s);
-
- for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
-
- if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
- ral->queue_reset ();
- } else {
- add_redirect_automation_curve (redirect, (*i));
- }
- }
-}
-
-void
-AudioTimeAxisView::add_redirect_to_subplugin_menu (Redirect* r)
-{
- using namespace Menu_Helpers;
- RedirectAutomationInfo *rai;
- list<RedirectAutomationInfo*>::iterator x;
-
- const std::set<uint32_t>& automatable = r->what_can_be_automated ();
- std::set<uint32_t> has_visible_automation;
-
- r->what_has_visible_automation(has_visible_automation);
-
- if (automatable.empty()) {
- return;
- }
-
- for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
- if ((*x)->redirect == r) {
- break;
- }
- }
-
- if (x == redirect_automation.end()) {
-
- rai = new RedirectAutomationInfo (r);
- redirect_automation.push_back (rai);
-
- } else {
-
- rai = *x;
-
- }
-
- /* any older menu was deleted at the top of redirects_changed()
- when we cleared the subplugin menu.
- */
-
- rai->menu = manage (new Menu);
- MenuList& items = rai->menu->items();
- rai->menu->set_name ("ArdourContextMenu");
-
- items.clear ();
-
- for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
-
- RedirectAutomationNode* ran;
- CheckMenuItem* mitem;
-
- string name = r->describe_parameter (*i);
-
- items.push_back (CheckMenuElem (name));
- mitem = dynamic_cast<CheckMenuItem*> (&items.back());
-
- if (has_visible_automation.find((*i)) != has_visible_automation.end()) {
- mitem->set_active(true);
- }
-
- if ((ran = find_redirect_automation_node (r, *i)) == 0) {
-
- /* new item */
-
- ran = new RedirectAutomationNode (*i, mitem, *this);
-
- rai->lines.push_back (ran);
-
- } else {
-
- ran->menu_item = mitem;
-
- }
-
- mitem->signal_toggled().connect (bind (mem_fun(*this, &AudioTimeAxisView::redirect_menu_item_toggled), rai, ran));
- }
-
- /* add the menu for this redirect, because the subplugin
- menu is always cleared at the top of redirects_changed().
- this is the result of some poor design in gtkmm and/or
- GTK+.
- */
-
- subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
- rai->valid = true;
-}
-
-void
-AudioTimeAxisView::redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo* rai,
- AudioTimeAxisView::RedirectAutomationNode* ran)
-{
- bool showit = ran->menu_item->get_active();
- bool redraw = false;
-
- if (ran->view == 0 && showit) {
- add_redirect_automation_curve (rai->redirect, ran->what);
- redraw = true;
- }
-
- if (showit != ran->view->marked_for_display()) {
-
- if (showit) {
- ran->view->set_marked_for_display (true);
- ran->view->canvas_display->show();
- } else {
- rai->redirect->mark_automation_visible (ran->what, true);
- ran->view->set_marked_for_display (false);
- ran->view->hide ();
- }
-
- redraw = true;
-
- }
-
- if (redraw && !no_redraw) {
-
- /* now trigger a redisplay */
-
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-
- }
-}
-
-void
-AudioTimeAxisView::redirects_changed (void *src)
-{
- using namespace Menu_Helpers;
-
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
- (*i)->valid = false;
- }
-
- subplugin_menu.items().clear ();
-
- _route.foreach_redirect (this, &AudioTimeAxisView::add_redirect_to_subplugin_menu);
- _route.foreach_redirect (this, &AudioTimeAxisView::add_existing_redirect_automation_curves);
-
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
-
- list<RedirectAutomationInfo*>::iterator tmp;
-
- tmp = i;
- ++tmp;
-
- if (!(*i)->valid) {
-
- delete *i;
- redirect_automation.erase (i);
-
- }
-
- i = tmp;
- }
-
- /* change in visibility was possible */
-
- _route.gui_changed ("track_height", this);
-}
-
-RedirectAutomationLine *
-AudioTimeAxisView::find_redirect_automation_curve (Redirect *redirect, uint32_t what)
-{
- RedirectAutomationNode* ran;
-
- if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
- if (ran->view) {
- return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
- }
- }
-
- return 0;
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
@@ -1661,19 +511,11 @@ AudioTimeAxisView::show_all_automation ()
pan_automation_item->set_active (true);
gain_automation_item->set_active (true);
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
- for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
- if ((*ii)->view == 0) {
- add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
- }
-
- (*ii)->menu_item->set_active (true);
- }
- }
+ RouteTimeAxisView::show_all_automation ();
no_redraw = false;
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
@@ -1684,17 +526,11 @@ AudioTimeAxisView::show_existing_automation ()
pan_automation_item->set_active (true);
gain_automation_item->set_active (true);
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
- for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
- if ((*ii)->view != 0) {
- (*ii)->menu_item->set_active (true);
- }
- }
- }
+ RouteTimeAxisView::show_existing_automation ();
no_redraw = false;
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
@@ -1705,236 +541,61 @@ AudioTimeAxisView::hide_all_automation ()
pan_automation_item->set_active (false);
gain_automation_item->set_active (false);
- for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
- for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
- (*ii)->menu_item->set_active (false);
- }
- }
+ RouteTimeAxisView::hide_all_automation();
no_redraw = false;
- _route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
-}
-
-bool
-AudioTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
-{
- Playlist* what_we_got;
- AudioDiskstream* ds = get_diskstream();
- Playlist* playlist;
- bool ret = false;
-
- if (ds == 0) {
- /* route is a bus, not a track */
- return false;
- }
-
- playlist = ds->playlist();
-
-
- TimeSelection time (selection.time);
- float speed = ds->speed();
- if (speed != 1.0f) {
- for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) {
- (*i).start = session_frame_to_track_frame((*i).start, speed);
- (*i).end = session_frame_to_track_frame((*i).end, speed);
- }
- }
-
- XMLNode &before = playlist->get_state();
- switch (op) {
- case Cut:
- if ((what_we_got = playlist->cut (time)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
- XMLNode &after = playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*playlist, before, after));
- ret = true;
- }
- break;
- case Copy:
- if ((what_we_got = playlist->copy (time)) != 0) {
- editor.get_cut_buffer().add (what_we_got);
- }
- break;
-
- case Clear:
- if ((what_we_got = playlist->cut (time)) != 0) {
- XMLNode &after = playlist->get_state();
- _session.add_command(new MementoCommand<Playlist>(*playlist, before, after));
- what_we_got->unref ();
- ret = true;
- }
- break;
- }
-
- return ret;
-}
-
-bool
-AudioTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth)
-{
- if (!is_audio_track()) {
- return false;
- }
-
- Playlist* playlist = get_diskstream()->playlist();
- PlaylistSelection::iterator p;
-
- for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
-
- if (p == selection.playlists.end()) {
- return false;
- }
-
- if (get_diskstream()->speed() != 1.0f)
- pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
-
- XMLNode &before = playlist->get_state();
- playlist->paste (**p, pos, times);
- _session.add_command(new MementoCommand<Playlist>(*playlist, before,
- playlist->get_state()));
-
- return true;
-}
-
-void
-AudioTimeAxisView::region_view_added (AudioRegionView* arv)
-{
- for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- AutomationTimeAxisView* atv;
-
- if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
- arv->add_ghost (*atv);
- }
- }
-}
-
-void
-AudioTimeAxisView::add_ghost_to_redirect (AudioRegionView* arv, AutomationTimeAxisView* atv)
-{
- arv->add_ghost (*atv);
-}
-
-list<TimeAxisView*>
-AudioTimeAxisView::get_child_list()
-{
-
- list<TimeAxisView*>redirect_children;
-
- for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- if (!(*i)->hidden()) {
- redirect_children.push_back(*i);
- }
- }
- return redirect_children;
-}
-
-
-void
-AudioTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
-{
- using namespace Menu_Helpers;
-
- if (!menu || !is_audio_track()) {
- return;
- }
-
- MenuList& playlist_items = menu->items();
- menu->set_name ("ArdourContextMenu");
- playlist_items.clear();
-
- if (playlist_menu) {
- delete playlist_menu;
- }
- playlist_menu = new Menu;
- playlist_menu->set_name ("ArdourContextMenu");
-
- playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
- playlist_items.push_back (SeparatorElem());
-
- playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &AudioTimeAxisView::rename_current_playlist)));
- playlist_items.push_back (SeparatorElem());
-
- playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists)));
- playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists)));
- playlist_items.push_back (SeparatorElem());
- playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
- playlist_items.push_back (SeparatorElem());
- playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &AudioTimeAxisView::show_playlist_selector)));
-
-}
-
-void
-AudioTimeAxisView::show_playlist_selector ()
-{
- editor.playlist_selector().show_for (this);
-}
-
-
-void
-AudioTimeAxisView::map_frozen ()
-{
- if (!is_audio_track()) {
- return;
- }
-
- ENSURE_GUI_THREAD (mem_fun(*this, &AudioTimeAxisView::map_frozen));
-
-
- switch (audio_track()->freeze_state()) {
- case AudioTrack::Frozen:
- playlist_button.set_sensitive (false);
- rec_enable_button->set_sensitive (false);
- break;
- default:
- playlist_button.set_sensitive (true);
- rec_enable_button->set_sensitive (true);
- break;
- }
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
void
AudioTimeAxisView::show_all_xfades ()
{
- if (view) {
- view->show_all_xfades ();
+ AudioStreamView* asv = audio_view();
+
+ if (asv) {
+ asv->show_all_xfades ();
}
}
void
AudioTimeAxisView::hide_all_xfades ()
{
- if (view) {
- view->hide_all_xfades ();
+ AudioStreamView* asv = audio_view();
+
+ if (asv) {
+ asv->hide_all_xfades ();
}
}
void
AudioTimeAxisView::hide_dependent_views (TimeAxisViewItem& tavi)
{
+ AudioStreamView* asv = audio_view();
AudioRegionView* rv;
- if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
- view->hide_xfades_involving (*rv);
+ if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
+ asv->hide_xfades_involving (*rv);
}
}
void
AudioTimeAxisView::reveal_dependent_views (TimeAxisViewItem& tavi)
{
+ AudioStreamView* asv = audio_view();
AudioRegionView* rv;
- if (view && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
- view->reveal_xfades_involving (*rv);
+ if (asv && (rv = dynamic_cast<AudioRegionView*>(&tavi)) != 0) {
+ asv->reveal_xfades_involving (*rv);
}
}
void
AudioTimeAxisView::route_active_changed ()
{
- RouteUI::route_active_changed ();
+ RouteTimeAxisView::route_active_changed ();
if (is_audio_track()) {
- if (_route.active()) {
+ if (_route->active()) {
controls_ebox.set_name ("AudioTrackControlsBaseUnselected");
controls_base_selected_name = "AudioTrackControlsBaseSelected";
controls_base_unselected_name = "AudioTrackControlsBaseUnselected";
@@ -1944,7 +605,7 @@ AudioTimeAxisView::route_active_changed ()
controls_base_unselected_name = "AudioTrackControlsBaseInactiveUnselected";
}
} else {
- if (_route.active()) {
+ if (_route->active()) {
controls_ebox.set_name ("BusControlsBaseUnselected");
controls_base_selected_name = "BusControlsBaseSelected";
controls_base_unselected_name = "BusControlsBaseUnselected";
@@ -1962,24 +623,3 @@ AudioTimeAxisView::get_child_xml_node (const string & childname)
return RouteUI::get_child_xml_node (childname);
}
-void
-AudioTimeAxisView::color_handler (ColorID id, uint32_t val)
-{
- switch (id) {
- case cTimeStretchOutline:
- timestretch_rect->property_outline_color_rgba() = val;
- break;
- case cTimeStretchFill:
- timestretch_rect->property_fill_color_rgba() = val;
- break;
- default:
- break;
- }
-}
-
-bool
-AudioTimeAxisView::select_me (GdkEventButton* ev)
-{
- editor.get_selection().add (this);
- return false;
-}
diff --git a/gtk2_ardour/audio_time_axis.h b/gtk2_ardour/audio_time_axis.h
index b319d0ea99..2162771285 100644
--- a/gtk2_ardour/audio_time_axis.h
+++ b/gtk2_ardour/audio_time_axis.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -18,8 +18,8 @@
$Id$
*/
-#ifndef __ardour_trackview_h__
-#define __ardour_trackview_h__
+#ifndef __ardour_audio_time_axis_h__
+#define __ardour_audio_time_axis_h__
#include <gtkmm/table.h>
#include <gtkmm/button.h>
@@ -33,19 +33,14 @@
#include <list>
#include <ardour/types.h>
-#include <ardour/region.h>
#include "ardour_dialog.h"
#include "route_ui.h"
#include "enums.h"
-#include "time_axis_view.h"
+#include "route_time_axis.h"
#include "canvas.h"
#include "color.h"
-namespace ALSA {
- class MultiChannelDevice;
-}
-
namespace ARDOUR {
class Session;
class AudioDiskstream;
@@ -56,247 +51,58 @@ namespace ARDOUR {
class AudioPlaylist;
}
-namespace LADSPA {
- class Manager;
- class Plugin;
-}
-
class PublicEditor;
class AudioThing;
-class StreamView;
+class AudioStreamView;
class Selection;
class Selectable;
+class RegionView;
class AudioRegionView;
class AutomationLine;
class AutomationGainLine;
class AutomationPanLine;
-class RedirectAutomationLine;
class TimeSelection;
class AutomationTimeAxisView;
-class AudioTimeAxisView : public RouteUI, public TimeAxisView
+class AudioTimeAxisView : public RouteTimeAxisView
{
public:
- AudioTimeAxisView (PublicEditor&, ARDOUR::Session&, ARDOUR::Route&, ArdourCanvas::Canvas& canvas);
+ AudioTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
virtual ~AudioTimeAxisView ();
+
+ AudioStreamView* audio_view();
- void show_selection (TimeSelection&);
- void automation_control_point_changed (ARDOUR::AutomationType);
-
- void set_samples_per_unit (double);
- void set_height (TimeAxisView::TrackHeight);
void set_show_waveforms (bool yn);
void set_show_waveforms_recording (bool yn);
- void show_timestretch (jack_nframes_t start, jack_nframes_t end);
- void hide_timestretch ();
- void selection_click (GdkEventButton*);
- void set_selected_regionviews (AudioRegionSelection&);
- void set_selected_points (PointSelection&);
- void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&);
- void get_inverted_selectables (Selection&, list<Selectable*>&);
void show_all_xfades ();
void hide_all_xfades ();
void hide_dependent_views (TimeAxisViewItem&);
void reveal_dependent_views (TimeAxisViewItem&);
- ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
-
- string name() const;
-
- ARDOUR::RouteGroup* edit_group() const;
-
- void build_playlist_menu (Gtk::Menu *);
- ARDOUR::Playlist* playlist() const;
-
- /* overridden from parent to store display state */
+ /* Overridden from parent to store display state */
guint32 show_at (double y, int& nth, Gtk::VBox *parent);
void hide ();
- /* need accessors/mutators */
-
- StreamView *view;
-
- /* editing operations */
-
- bool cut_copy_clear (Selection&, Editing::CutCopyOp);
- bool paste (jack_nframes_t, float times, Selection&, size_t nth);
-
- list<TimeAxisView*>get_child_list();
-
void set_state (const XMLNode&);
XMLNode* get_child_xml_node (const string & childname);
- /* the editor calls these when mapping an operation across multiple tracks */
-
- void use_new_playlist (bool prompt);
- void use_copy_playlist (bool prompt);
- void clear_playlist ();
-
private:
- friend class StreamView;
+ friend class AudioStreamView;
friend class AudioRegionView;
-
- ArdourCanvas::Canvas& parent_canvas;
-
- bool no_redraw;
-
- AutomationTimeAxisView *gain_track;
- AutomationTimeAxisView *pan_track;
-
- void update_automation_view (ARDOUR::AutomationType);
- void reset_redirect_automation_curves ();
-
- Gtk::HBox other_button_hbox;
-
- Gtk::Table button_table;
-
- Gtk::Button redirect_button;
- Gtk::Button edit_group_button;
- Gtk::Button playlist_button;
- Gtk::Button size_button;
- Gtk::Button automation_button;
- Gtk::Button hide_button;
- Gtk::Button visual_button;
-
- void route_active_changed ();
-
- void diskstream_changed (void *src);
- void update_diskstream_display ();
- gint edit_click (GdkEventButton *);
-
- // variables to get the context menu
- // automation buttons correctly initialized
- bool show_gain_automation;
- bool show_pan_automation;
-
- void build_redirect_window ();
- void redirect_click ();
- void redirect_add ();
- void redirect_remove ();
- void redirect_edit ();
- void redirect_relist ();
- void redirect_row_selected (gint row, gint col, GdkEvent *ev);
- void add_to_redirect_display (ARDOUR::Redirect *);
- void redirects_changed (void *);
-
- sigc::connection modified_connection;
- sigc::connection state_changed_connection;
-
- void take_name_changed (void *);
- void route_name_changed (void *);
- void name_entry_changed ();
-
- void on_area_realize ();
-
- virtual void label_view ();
-
- Gtk::Menu edit_group_menu;
-
- void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*);
- void set_edit_group_from_menu (ARDOUR::RouteGroup *);
-
- void reset_samples_per_unit ();
+ void route_active_changed ();
- void select_track_color();
+ void build_automation_action_menu ();
+ void append_extra_display_menu_items ();
- virtual void build_display_menu ();
-
- Gtk::CheckMenuItem* waveform_item;
- Gtk::RadioMenuItem* traditional_item;
- Gtk::RadioMenuItem* rectified_item;
-
- Gtk::RadioMenuItem* align_existing_item;
- Gtk::RadioMenuItem* align_capture_item;
-
- void align_style_changed ();
- void set_align_style (ARDOUR::AlignStyle);
-
void toggle_show_waveforms ();
-
void set_waveform_shape (WaveformShape);
void toggle_waveforms ();
- Gtk::Menu *playlist_menu;
- Gtk::Menu *playlist_action_menu;
- Gtk::MenuItem *playlist_item;
-
- /* playlist */
-
- void set_playlist (ARDOUR::AudioPlaylist *);
- void playlist_click ();
- void show_playlist_selector ();
-
- void playlist_changed ();
- void playlist_state_changed (ARDOUR::Change);
- void playlist_modified ();
-
- void add_playlist_to_playlist_menu (ARDOUR::Playlist*);
- void rename_current_playlist ();
-
- /* automation stuff */
-
- Gtk::Menu* automation_action_menu;
- Gtk::CheckMenuItem* gain_automation_item;
- Gtk::CheckMenuItem* pan_automation_item;
-
- void automation_click ();
- void clear_automation ();
- void hide_all_automation ();
void show_all_automation ();
void show_existing_automation ();
+ void hide_all_automation ();
- struct RedirectAutomationNode {
- uint32_t what;
- Gtk::CheckMenuItem* menu_item;
- AutomationTimeAxisView* view;
- AudioTimeAxisView& parent;
-
- RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, AudioTimeAxisView& p)
- : what (w), menu_item (mitem), view (0), parent (p) {}
-
- ~RedirectAutomationNode ();
- };
-
- struct RedirectAutomationInfo {
- ARDOUR::Redirect* redirect;
- bool valid;
- Gtk::Menu* menu;
- vector<RedirectAutomationNode*> lines;
-
- RedirectAutomationInfo (ARDOUR::Redirect* r)
- : redirect (r), valid (true) {}
-
- ~RedirectAutomationInfo ();
- };
-
- list<RedirectAutomationInfo*> redirect_automation;
- RedirectAutomationNode* find_redirect_automation_node (ARDOUR::Redirect *redirect, uint32_t what);
-
- Gtk::Menu subplugin_menu;
- void add_redirect_to_subplugin_menu (ARDOUR::Redirect *);
-
- void remove_ran (RedirectAutomationNode* ran);
-
- void redirect_menu_item_toggled (AudioTimeAxisView::RedirectAutomationInfo*,
- AudioTimeAxisView::RedirectAutomationNode*);
- void redirect_automation_track_hidden (RedirectAutomationNode*, ARDOUR::Redirect*);
-
- vector<RedirectAutomationLine*> redirect_automation_curves;
- RedirectAutomationLine *find_redirect_automation_curve (ARDOUR::Redirect*,uint32_t);
- void add_redirect_automation_curve (ARDOUR::Redirect*, uint32_t);
- void add_existing_redirect_automation_curves (ARDOUR::Redirect*);
-
- ArdourCanvas::SimpleRect *timestretch_rect;
-
- void timestretch (jack_nframes_t start, jack_nframes_t end);
-
- void visual_click ();
- void hide_click ();
- gint when_displayed (GdkEventAny*);
-
- void speed_changed ();
-
void add_gain_automation_child ();
void add_pan_automation_child ();
void add_parameter_automation_child ();
@@ -309,14 +115,19 @@ class AudioTimeAxisView : public RouteUI, public TimeAxisView
void update_pans ();
- void region_view_added (AudioRegionView*);
- void add_ghost_to_redirect (AudioRegionView*, AutomationTimeAxisView*);
-
- void map_frozen ();
+ AutomationTimeAxisView* gain_track;
+ AutomationTimeAxisView* pan_track;
- void color_handler (ColorID, uint32_t);
- bool select_me (GdkEventButton*);
+ // Set from XML so context menu automation buttons can be correctly initialized
+ bool show_gain_automation;
+ bool show_pan_automation;
+
+ Gtk::CheckMenuItem* waveform_item;
+ Gtk::RadioMenuItem* traditional_item;
+ Gtk::RadioMenuItem* rectified_item;
+ Gtk::CheckMenuItem* gain_automation_item;
+ Gtk::CheckMenuItem* pan_automation_item;
};
-#endif /* __ardour_trackview_h__ */
+#endif /* __ardour_audio_time_axis_h__ */
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index 080a440bc9..6e2a93889f 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -21,7 +21,7 @@ using namespace PBD;
using namespace Gtk;
using namespace Editing;
-AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& rent,
+AutomationTimeAxisView::AutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e, TimeAxisView& rent,
ArdourCanvas::Canvas& canvas, const string & nom,
const string & state_name, const string & nomparent)
@@ -41,6 +41,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit
auto_write_item = 0;
auto_play_item = 0;
ignore_state_request = false;
+ first_call_to_set_height = true;
// base_rect = gnome_canvas_item_new (GNOME_CANVAS_GROUP(canvas_display),
// gnome_canvas_simplerect_get_type(),
@@ -73,6 +74,8 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit
clear_button.set_name ("TrackVisualButton");
hide_button.set_name ("TrackRemoveButton");
+ controls_table.set_no_show_all();
+
ARDOUR_UI::instance()->tooltips().set_tip(height_button, _("track height"));
ARDOUR_UI::instance()->tooltips().set_tip(auto_button, _("automation state"));
ARDOUR_UI::instance()->tooltips().set_tip(clear_button, _("clear track"));
@@ -116,6 +119,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit
plugname = new Label (pname);
plugname->set_name (X_("TrackPlugName"));
plugname->set_alignment (1.0, 0.5);
+ plugname->show();
name_label.set_name (X_("TrackParameterName"));
controls_table.remove (name_hbox);
controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
@@ -139,9 +143,9 @@ AutomationTimeAxisView::AutomationTimeAxisView (Session& s, Route& r, PublicEdit
controls_table.attach (hide_button, 0, 1, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
controls_table.attach (height_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.attach (auto_button, 6, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.attach (clear_button, 6, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
-
+ controls_table.attach (auto_button, 5, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ controls_table.attach (clear_button, 5, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+
controls_table.show_all ();
height_button.signal_clicked().connect (mem_fun(*this, &AutomationTimeAxisView::height_clicked));
@@ -282,11 +286,11 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
uint32_t h = height_to_pixels (ht);
bool changed = (height != (uint32_t) h);
+ bool changed_between_small_and_normal = ( (ht == Small || ht == Smaller) ^ (height_style == Small || height_style == Smaller) );
+
TimeAxisView* state_parent = get_parent_with_state ();
XMLNode* xml_node = state_parent->get_child_xml_node (_state_name);
- controls_table.show_all ();
-
TimeAxisView::set_height (ht);
base_rect->property_y2() = h;
@@ -298,119 +302,91 @@ AutomationTimeAxisView::set_height (TrackHeight ht)
(*i)->set_height ();
}
- switch (height) {
+
+ switch (ht) {
case Largest:
xml_node->add_property ("track_height", "largest");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- plugname_packed = true;
- controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- } else {
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- }
- controls_table.show_all ();
- hide_name_entry ();
- show_name_label ();
break;
case Large:
xml_node->add_property ("track_height", "large");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- plugname_packed = true;
- } else {
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- }
- controls_table.show_all ();
- hide_name_entry ();
- show_name_label ();
break;
case Larger:
xml_node->add_property ("track_height", "larger");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- plugname_packed = true;
- } else {
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- }
- controls_table.show_all ();
- hide_name_entry ();
- show_name_label ();
break;
case Normal:
xml_node->add_property ("track_height", "normal");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- plugname_packed = true;
- controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- } else {
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- }
- controls_table.show_all ();
- hide_name_entry ();
- show_name_label ();
break;
case Smaller:
xml_node->add_property ("track_height", "smaller");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- }
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.hide_all ();
- hide_name_entry ();
- show_name_label ();
- name_hbox.show_all ();
- controls_table.show ();
break;
case Small:
xml_node->add_property ("track_height", "small");
- controls_table.remove (name_hbox);
- if (plugname) {
- if (plugname_packed) {
- controls_table.remove (*plugname);
- plugname_packed = false;
- }
- }
- controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
- controls_table.hide_all ();
- hide_name_entry ();
- show_name_label ();
- name_hbox.show_all ();
- controls_table.show ();
break;
}
+ if (changed_between_small_and_normal || first_call_to_set_height) {
+ first_call_to_set_height = false;
+ switch (ht) {
+ case Largest:
+ case Large:
+ case Larger:
+ case Normal:
+
+ controls_table.remove (name_hbox);
+
+ if (plugname) {
+ if (plugname_packed) {
+ controls_table.remove (*plugname);
+ plugname_packed = false;
+ }
+ controls_table.attach (*plugname, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ plugname_packed = true;
+ controls_table.attach (name_hbox, 1, 5, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ } else {
+ controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ }
+ hide_name_entry ();
+ show_name_label ();
+ name_hbox.show_all ();
+
+ auto_button.show();
+ height_button.show();
+ clear_button.show();
+ hide_button.show_all();
+ break;
+
+ case Smaller:
+ case Small:
+
+ controls_table.remove (name_hbox);
+ if (plugname) {
+ if (plugname_packed) {
+ controls_table.remove (*plugname);
+ plugname_packed = false;
+ }
+ }
+ controls_table.attach (name_hbox, 1, 5, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ controls_table.hide_all ();
+ hide_name_entry ();
+ show_name_label ();
+ name_hbox.show_all ();
+
+ auto_button.hide();
+ height_button.hide();
+ clear_button.hide();
+ hide_button.hide();
+ break;
+ }
+ }
+
if (changed) {
/* only emit the signal if the height really changed */
- route.gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
}
}
diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h
index deb08b41f0..0cd9acc034 100644
--- a/gtk2_ardour/automation_time_axis.h
+++ b/gtk2_ardour/automation_time_axis.h
@@ -4,6 +4,9 @@
#include <vector>
#include <list>
#include <string>
+
+#include <boost/shared_ptr.hpp>
+
#include <ardour/types.h>
#include "canvas.h"
@@ -21,7 +24,7 @@ namespace ARDOUR {
class PublicEditor;
class TimeSelection;
-class AudioRegionSelection;
+class RegionSelection;
class PointSelection;
class AutomationLine;
class GhostRegion;
@@ -31,7 +34,7 @@ class Selectable;
class AutomationTimeAxisView : public TimeAxisView {
public:
AutomationTimeAxisView (ARDOUR::Session&,
- ARDOUR::Route&,
+ boost::shared_ptr<ARDOUR::Route>,
PublicEditor&,
TimeAxisView& parent,
ArdourCanvas::Canvas& canvas,
@@ -41,14 +44,14 @@ class AutomationTimeAxisView : public TimeAxisView {
~AutomationTimeAxisView();
- void set_height (TimeAxisView::TrackHeight);
+ virtual void set_height (TimeAxisView::TrackHeight);
void set_samples_per_unit (double);
std::string name() const { return _name; }
virtual void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double) = 0;
- void clear_lines ();
- void add_line (AutomationLine&);
+ virtual void clear_lines ();
+ virtual void add_line (AutomationLine&);
vector<AutomationLine*> lines;
@@ -75,12 +78,14 @@ class AutomationTimeAxisView : public TimeAxisView {
XMLNode* get_state_node ();
protected:
- ARDOUR::Route& route;
+ boost::shared_ptr<ARDOUR::Route> route;
ArdourCanvas::SimpleRect* base_rect;
string _name;
string _state_name;
bool in_destructor;
+ bool first_call_to_set_height;
+
Gtk::Button hide_button;
Gtk::Button height_button;
Gtk::Button clear_button;
diff --git a/gtk2_ardour/canvas-waveview.h b/gtk2_ardour/canvas-waveview.h
index 97ac91f622..75281f69eb 100644
--- a/gtk2_ardour/canvas-waveview.h
+++ b/gtk2_ardour/canvas-waveview.h
@@ -80,10 +80,10 @@ struct _GnomeCanvasWaveView
void (*gain_curve_function)(void *arg, double start, double end, float* vector, guint32 veclen);
void *gain_src;
- /* x-axis: samples per canvas unit. */
+ /** x-axis: samples per canvas unit. */
double samples_per_unit;
- /* y-axis: amplitude_above_axis.
+ /** y-axis: amplitude_above_axis.
*
* the default is that an (scaled, normalized -1.0 ... +1.0) amplitude of 1.0
* corresponds to the top of the area assigned to the waveview.
@@ -92,8 +92,8 @@ struct _GnomeCanvasWaveView
* smaller values will decrease the vertical scale, moving peaks/troughs toward
* the middle of the area assigned to the waveview.
*/
-
double amplitude_above_axis;
+
double x;
double y;
double height;
diff --git a/gtk2_ardour/crossfade_edit.cc b/gtk2_ardour/crossfade_edit.cc
index 5b587594de..b2967dc4a9 100644
--- a/gtk2_ardour/crossfade_edit.cc
+++ b/gtk2_ardour/crossfade_edit.cc
@@ -1077,7 +1077,7 @@ CrossfadeEditor::peaks_ready (AudioRegion* r, WhichFade which)
void
CrossfadeEditor::audition_both ()
{
- AudioPlaylist& pl (session.the_auditioner().prepare_playlist());
+ AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
jack_nframes_t preroll;
jack_nframes_t postroll;
jack_nframes_t length;
@@ -1140,7 +1140,7 @@ CrossfadeEditor::audition_left_dry ()
void
CrossfadeEditor::audition_left ()
{
- AudioPlaylist& pl (session.the_auditioner().prepare_playlist());
+ AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
AudioRegion* left = new AudioRegion (xfade.out(), xfade.out().length() - xfade.length(), xfade.length(), "xfade left",
0, Region::DefaultFlags, false);
@@ -1172,7 +1172,7 @@ CrossfadeEditor::audition_right_dry ()
void
CrossfadeEditor::audition_right ()
{
- AudioPlaylist& pl (session.the_auditioner().prepare_playlist());
+ AudioPlaylist& pl (session.the_auditioner()->prepare_playlist());
AudioRegion* left = new AudioRegion (xfade.out(), xfade.out().length() - xfade.length(), xfade.length(), "xfade out",
0, Region::DefaultFlags, false);
diff --git a/gtk2_ardour/crossfade_view.cc b/gtk2_ardour/crossfade_view.cc
index 350698ec48..087af25e73 100644
--- a/gtk2_ardour/crossfade_view.cc
+++ b/gtk2_ardour/crossfade_view.cc
@@ -29,7 +29,7 @@
#include "rgb_macros.h"
#include "audio_time_axis.h"
#include "public_editor.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "utils.h"
#include "canvas_impl.h"
@@ -43,7 +43,7 @@ using namespace Canvas;
sigc::signal<void,CrossfadeView*> CrossfadeView::GoingAway;
CrossfadeView::CrossfadeView (ArdourCanvas::Group *parent,
- AudioTimeAxisView &tv,
+ RouteTimeAxisView &tv,
Crossfade& xf,
double spu,
Gdk::Color& basic_color,
@@ -227,7 +227,7 @@ CrossfadeView::set_valid (bool yn)
AudioRegionView&
CrossfadeView::upper_regionview () const
{
- if (left_view.region.layer() > right_view.region.layer()) {
+ if (left_view.region().layer() > right_view.region().layer()) {
return left_view;
} else {
return right_view;
diff --git a/gtk2_ardour/crossfade_view.h b/gtk2_ardour/crossfade_view.h
index 403edfe297..adbd74b420 100644
--- a/gtk2_ardour/crossfade_view.h
+++ b/gtk2_ardour/crossfade_view.h
@@ -28,13 +28,13 @@
#include "time_axis_view_item.h"
-class AudioTimeAxisView;
+class RouteTimeAxisView;
class AudioRegionView;
struct CrossfadeView : public TimeAxisViewItem
{
CrossfadeView (ArdourCanvas::Group*,
- AudioTimeAxisView&,
+ RouteTimeAxisView&,
ARDOUR::Crossfade&,
double initial_samples_per_unit,
Gdk::Color& basic_color,
diff --git a/gtk2_ardour/editing_syms.h b/gtk2_ardour/editing_syms.h
index cf36550fb4..654ddc8852 100644
--- a/gtk2_ardour/editing_syms.h
+++ b/gtk2_ardour/editing_syms.h
@@ -56,4 +56,5 @@ DISPLAYCONTROL(ShowWaveformsRecording)
IMPORTMODE(ImportAsRegion)
IMPORTMODE(ImportAsTrack)
+IMPORTMODE(ImportAsTapeTrack)
IMPORTMODE(ImportToTrack)
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 6472974093..513251085c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -57,10 +57,10 @@
#include "keyboard.h"
#include "marker.h"
#include "playlist_selector.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "rgb_macros.h"
#include "selection.h"
-#include "streamview.h"
+#include "audio_streamview.h"
#include "time_axis_view.h"
#include "utils.h"
#include "crossfade_view.h"
@@ -102,8 +102,8 @@ static const int32_t slide_index = 0;
static const int32_t splice_index = 1;
static const gchar *edit_mode_strings[] = {
- N_("Slide"),
- N_("Splice"),
+ N_("Slide Edit"),
+ N_("Splice Edit"),
0
};
@@ -132,17 +132,17 @@ static const gchar *snap_type_strings[] = {
};
static const gchar *snap_mode_strings[] = {
- N_("Normal"),
- N_("Magnetic"),
+ N_("Normal Snap"),
+ N_("Magnetic Snap"),
0
};
static const gchar *zoom_focus_strings[] = {
- N_("Left"),
- N_("Right"),
- N_("Center"),
- N_("Playhead"),
- N_("Edit Cursor"),
+ N_("Focus Left"),
+ N_("Focus Right"),
+ N_("Focus Center"),
+ N_("Focus Play"),
+ N_("Focus Edit"),
0
};
@@ -205,37 +205,20 @@ Editor::Editor (AudioEngine& eng)
/* tool bar related */
- selection_start_clock (X_("SelectionStartClock"), true),
- selection_end_clock (X_("SelectionEndClock"), true),
edit_cursor_clock (X_("EditCursorClock"), true),
zoom_range_clock (X_("ZoomRangeClock"), true, true),
toolbar_selection_clock_table (2,3),
- mouse_mode_button_table (2, 3),
-
- mouse_select_button (_("range")),
- mouse_move_button (_("object")),
- mouse_gain_button (_("gain")),
- mouse_zoom_button (_("zoom")),
- mouse_timefx_button (_("timefx")),
- mouse_audition_button (_("listen")),
-
automation_mode_button (_("mode")),
global_automation_button (_("automation")),
- edit_mode_label (_("Edit Mode")),
- snap_type_label (_("Snap To")),
- snap_mode_label(_("Snap Mode")),
- zoom_focus_label (_("Zoom Focus")),
-
/* <CMT Additions> */
image_socket_listener(0),
/* </CMT Additions> */
/* nudge */
- nudge_label (_("Nudge")),
nudge_clock (X_("NudgeClock"), true, true)
{
@@ -346,6 +329,7 @@ Editor::Editor (AudioEngine& eng)
reset_hscrollbar_stepping ();
zoom_focus = ZoomFocusLeft;
+ set_zoom_focus (ZoomFocusLeft);
zoom_range_clock.ValueChanged.connect (mem_fun(*this, &Editor::zoom_adjustment_changed));
initialize_rulers ();
@@ -466,36 +450,7 @@ Editor::Editor (AudioEngine& eng)
edit_packer.attach (edit_hscrollbar, 2, 3, 2, 3, FILL|EXPAND, FILL, 0, 0);
- zoom_in_button.set_name ("EditorTimeButton");
- zoom_out_button.set_name ("EditorTimeButton");
- ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom in"));
- ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom out"));
-
- zoom_out_full_button.set_name ("EditorTimeButton");
- ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to session"));
-
- zoom_in_button.add (*(manage (new Image (Stock::ZOOM_IN, ICON_SIZE_BUTTON))));
- zoom_out_button.add (*(manage (new Image (Stock::ZOOM_OUT, ICON_SIZE_BUTTON))));
- zoom_out_full_button.add (*(manage (new Image (Stock::ZOOM_FIT, ICON_SIZE_BUTTON))));
-
- zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
- zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
- zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
-
- zoom_indicator_box.pack_start (zoom_out_button, false, false);
- zoom_indicator_box.pack_start (zoom_in_button, false, false);
- zoom_indicator_box.pack_start (zoom_range_clock, false, false);
- zoom_indicator_box.pack_start (zoom_out_full_button, false, false);
-
- zoom_indicator_label.set_text (_("Zoom Span"));
- zoom_indicator_label.set_name ("ToolBarLabel");
-
- zoom_indicator_vbox.set_spacing (3);
- zoom_indicator_vbox.set_border_width (3);
- zoom_indicator_vbox.pack_start (zoom_indicator_label, false, false);
- zoom_indicator_vbox.pack_start (zoom_indicator_box, false, false);
-
- bottom_hbox.set_border_width (3);
+ bottom_hbox.set_border_width (2);
bottom_hbox.set_spacing (3);
route_display_model = ListStore::create(route_display_columns);
@@ -718,15 +673,15 @@ Editor::Editor (AudioEngine& eng)
_playlist_selector = new PlaylistSelector();
_playlist_selector->signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
- AudioRegionView::AudioRegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_audio_regionview));
+ RegionView::RegionViewGoingAway.connect (mem_fun(*this, &Editor::catch_vanishing_regionview));
/* nudge stuff */
nudge_forward_button.add (*(manage (new Image (get_xpm("right_arrow.xpm")))));
nudge_backward_button.add (*(manage (new Image (get_xpm("left_arrow.xpm")))));
- ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge region/selection forwards"));
- ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge region/selection backwards"));
+ ARDOUR_UI::instance()->tooltips().set_tip (nudge_forward_button, _("Nudge Region/Selection Forwards"));
+ ARDOUR_UI::instance()->tooltips().set_tip (nudge_backward_button, _("Nudge Region/Selection Backwards"));
nudge_forward_button.set_name ("TransportButton");
nudge_backward_button.set_name ("TransportButton");
@@ -776,7 +731,7 @@ Editor::add_toplevel_controls (Container& cont)
}
void
-Editor::catch_vanishing_audio_regionview (AudioRegionView *rv)
+Editor::catch_vanishing_regionview (RegionView *rv)
{
/* note: the selection will take care of the vanishing
audioregionview by itself.
@@ -792,7 +747,7 @@ Editor::catch_vanishing_audio_regionview (AudioRegionView *rv)
}
void
-Editor::set_entered_regionview (AudioRegionView* rv)
+Editor::set_entered_regionview (RegionView* rv)
{
if (rv == entered_regionview) {
return;
@@ -914,7 +869,7 @@ Editor::set_frames_per_unit (double fpu)
void
Editor::instant_save ()
{
- if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
+ if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
return;
}
@@ -1222,7 +1177,7 @@ Editor::connect_to_session (Session *t)
session_connections.push_back (session->TransportStateChange.connect (mem_fun(*this, &Editor::map_transport_state)));
session_connections.push_back (session->PositionChanged.connect (mem_fun(*this, &Editor::map_position_change)));
- session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route_p)));
+ session_connections.push_back (session->RouteAdded.connect (mem_fun(*this, &Editor::handle_new_route)));
session_connections.push_back (session->AudioRegionAdded.connect (mem_fun(*this, &Editor::handle_new_audio_region)));
session_connections.push_back (session->AudioRegionRemoved.connect (mem_fun(*this, &Editor::handle_audio_region_removed)));
session_connections.push_back (session->DurationChanged.connect (mem_fun(*this, &Editor::handle_new_duration)));
@@ -1243,8 +1198,6 @@ Editor::connect_to_session (Session *t)
edit_groups_changed ();
edit_cursor_clock.set_session (session);
- selection_start_clock.set_session (session);
- selection_end_clock.set_session (session);
zoom_range_clock.set_session (session);
_playlist_selector->set_session (session);
nudge_clock.set_session (session);
@@ -1377,7 +1330,7 @@ Editor::connect_to_session (Session *t)
AudioTimeAxisView *atv;
if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
- if (atv->route().master()) {
+ if (atv->route()->master()) {
route_list_display.get_selection()->unselect (i);
}
}
@@ -1448,7 +1401,7 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
switch (item_type) {
case FadeInItem:
case FadeInHandleItem:
- if (arv->region.fade_in_active()) {
+ if (arv->audio_region().fade_in_active()) {
items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), false)));
} else {
items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), true)));
@@ -1456,16 +1409,16 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
- items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
- items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
- items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
- items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
+ items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Linear)));
+ items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogB)));
+ items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Fast)));
+ items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::LogA)));
+ items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_in_shape), AudioRegion::Slow)));
break;
case FadeOutItem:
case FadeOutHandleItem:
- if (arv->region.fade_out_active()) {
+ if (arv->audio_region().fade_out_active()) {
items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), false)));
} else {
items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), true)));
@@ -1473,11 +1426,11 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
- items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
- items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
- items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
- items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->region, &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
+ items.push_back (MenuElem (_("Linear"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Linear)));
+ items.push_back (MenuElem (_("Slowest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Fast)));
+ items.push_back (MenuElem (_("Slow"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogB)));
+ items.push_back (MenuElem (_("Fast"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::LogA)));
+ items.push_back (MenuElem (_("Fastest"), bind (mem_fun (arv->audio_region(), &AudioRegion::set_fade_out_shape), AudioRegion::Slow)));
break;
default:
@@ -1499,8 +1452,8 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
switch (item_type) {
case RegionItem:
- case AudioRegionViewName:
- case AudioRegionViewNameHighlight:
+ case RegionViewName:
+ case RegionViewNameHighlight:
if (with_selection) {
build_menu_function = &Editor::build_track_selection_context_menu;
} else {
@@ -1540,25 +1493,26 @@ Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type,
switch (item_type) {
case RegionItem:
- case AudioRegionViewName:
- case AudioRegionViewNameHighlight:
+ case RegionViewName:
+ case RegionViewNameHighlight:
if (!with_selection) {
if (region_edit_menu_split_item) {
- if (clicked_regionview && clicked_regionview->region.covers (edit_cursor->current_frame)) {
+ if (clicked_regionview && clicked_regionview->region().covers (edit_cursor->current_frame)) {
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, true);
} else {
ActionManager::set_sensitive (ActionManager::edit_cursor_in_region_sensitive_actions, false);
}
}
+ /*
if (region_edit_menu_split_multichannel_item) {
- if (clicked_regionview && clicked_regionview->region.n_channels() > 1) {
+ if (clicked_regionview && clicked_regionview->region().n_channels() > 1) {
// GTK2FIX find the action, change its sensitivity
// region_edit_menu_split_multichannel_item->set_sensitive (true);
} else {
// GTK2FIX see above
// region_edit_menu_split_multichannel_item->set_sensitive (false);
}
- }
+ }*/
}
break;
@@ -1638,13 +1592,13 @@ Editor::build_track_region_context_menu (jack_nframes_t frame)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
if (atv) {
- AudioDiskstream* ds;
+ Diskstream* ds;
Playlist* pl;
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
Playlist::RegionList* regions = pl->regions_at ((jack_nframes_t) floor ( (double)frame * ds->speed()));
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (atv->view, (*i), edit_items);
+ add_region_context_items (atv->audio_view(), (*i), edit_items);
}
delete regions;
}
@@ -1665,7 +1619,7 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (clicked_trackview);
if (atv) {
- AudioDiskstream* ds;
+ Diskstream* ds;
Playlist* pl;
AudioPlaylist* apl;
@@ -1679,11 +1633,11 @@ Editor::build_track_crossfade_context_menu (jack_nframes_t frame)
bool many = xfades.size() > 1;
for (AudioPlaylist::Crossfades::iterator i = xfades.begin(); i != xfades.end(); ++i) {
- add_crossfade_context_items (atv->view, (*i), edit_items, many);
+ add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
}
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
- add_region_context_items (atv->view, (*i), edit_items);
+ add_region_context_items (atv->audio_view(), (*i), edit_items);
}
delete regions;
@@ -1749,7 +1703,7 @@ Editor::build_track_selection_context_menu (jack_nframes_t ignored)
}
void
-Editor::add_crossfade_context_items (StreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many)
+Editor::add_crossfade_context_items (AudioStreamView* view, Crossfade* xfade, Menu_Helpers::MenuList& edit_items, bool many)
{
using namespace Menu_Helpers;
Menu *xfade_menu = manage (new Menu);
@@ -1806,7 +1760,7 @@ Editor::xfade_edit_right_region ()
}
void
-Editor::add_region_context_items (StreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items)
+Editor::add_region_context_items (AudioStreamView* sv, Region* region, Menu_Helpers::MenuList& edit_items)
{
using namespace Menu_Helpers;
Menu *region_menu = manage (new Menu);
@@ -2185,7 +2139,6 @@ Editor::set_state (const XMLNode& node)
yoff = atoi(geometry->property("y_off")->value());
}
- set_geometry_hints (vpacker, g, Gdk::HINT_BASE_SIZE);
set_default_size (g.base_width, g.base_height);
move (x, y);
@@ -2297,7 +2250,7 @@ Editor::get_state ()
char buf[32];
if (is_realized()) {
- Glib::RefPtr<Gdk::Window> win = get_window();
+ Glib::RefPtr<Gdk::Window> win = get_window();
int x, y, xoff, yoff, width, height;
win->get_root_origin(x, y);
@@ -2586,30 +2539,56 @@ void
Editor::setup_toolbar ()
{
string pixmap_path;
+
+ const guint32 FUDGE = 18; // Combo's are stupid - they steal space from the entry for the button
+
+
+ /* Mode Buttons (tool selection) */
+
vector<ToggleButton *> mouse_mode_buttons;
+ mouse_move_button.add (*(manage (new Image (get_xpm("tool_object.xpm")))));
+ mouse_move_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_move_button);
+ mouse_select_button.add (*(manage (new Image (get_xpm("tool_range.xpm")))));
+ mouse_select_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_select_button);
+ mouse_gain_button.add (*(manage (new Image (get_xpm("tool_gain.xpm")))));
+ mouse_gain_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_gain_button);
+ mouse_zoom_button.add (*(manage (new Image (get_xpm("tool_zoom.xpm")))));
+ mouse_zoom_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_zoom_button);
+ mouse_timefx_button.add (*(manage (new Image (get_xpm("tool_stretch.xpm")))));
+ mouse_timefx_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_timefx_button);
+ mouse_audition_button.add (*(manage (new Image (get_xpm("tool_audition.xpm")))));
+ mouse_audition_button.set_relief(Gtk::RELIEF_NONE);
mouse_mode_buttons.push_back (&mouse_audition_button);
+
mouse_mode_button_set = new GroupedButtons (mouse_mode_buttons);
- mouse_mode_button_table.set_homogeneous (true);
- mouse_mode_button_table.set_col_spacings (2);
- mouse_mode_button_table.set_row_spacings (2);
- mouse_mode_button_table.set_border_width (5);
+ HBox* mode_box = manage(new HBox);
+ mode_box->set_border_width (2);
+ mode_box->set_spacing(4);
+ mouse_mode_button_box.set_spacing(1);
+ mouse_mode_button_box.pack_start(mouse_move_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_select_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_zoom_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_gain_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_timefx_button, true, true);
+ mouse_mode_button_box.pack_start(mouse_audition_button, true, true);
+ mouse_mode_button_box.set_homogeneous(true);
- mouse_mode_button_table.attach (mouse_move_button, 0, 1, 0, 1);
- mouse_mode_button_table.attach (mouse_select_button, 1, 2, 0, 1);
- mouse_mode_button_table.attach (mouse_zoom_button, 2, 3, 0, 1);
-
- mouse_mode_button_table.attach (mouse_gain_button, 0, 1, 1, 2);
- mouse_mode_button_table.attach (mouse_timefx_button, 1, 2, 1, 2);
- mouse_mode_button_table.attach (mouse_audition_button, 2, 3, 1, 2);
+ edit_mode_selector.set_name ("EditModeSelector");
+ Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "Splice Edit", 2+FUDGE, 10);
+ set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings));
+ edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done));
- mouse_mode_tearoff = manage (new TearOff (mouse_mode_button_table));
+ mode_box->pack_start(edit_mode_selector);
+ mode_box->pack_start(mouse_mode_button_box);
+
+ mouse_mode_tearoff = manage (new TearOff (*mode_box));
mouse_mode_tearoff->set_name ("MouseModeBase");
mouse_mode_tearoff->Detach.connect (bind (mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
@@ -2628,12 +2607,12 @@ Editor::setup_toolbar ()
mouse_timefx_button.set_name ("MouseModeButton");
mouse_audition_button.set_name ("MouseModeButton");
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("select/move objects"));
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("select/move ranges"));
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("draw gain automation"));
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("select zoom range"));
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("stretch/shrink regions"));
- ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("listen to specific regions"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_move_button, _("Select/Move Objects"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_gain_button, _("Draw Gain Automation"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_zoom_button, _("Select Zoom Range"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_timefx_button, _("Stretch/Shrink Regions"));
+ ARDOUR_UI::instance()->tooltips().set_tip (mouse_audition_button, _("Listen to Specific Regions"));
mouse_move_button.unset_flags (CAN_FOCUS);
mouse_select_button.unset_flags (CAN_FOCUS);
@@ -2652,160 +2631,82 @@ Editor::setup_toolbar ()
mouse_audition_button.signal_toggled().connect (bind (mem_fun(*this, &Editor::mouse_mode_toggled), Editing::MouseAudition));
// mouse_move_button.set_active (true);
+
- /* automation control */
-
- global_automation_button.set_name ("MouseModeButton");
- automation_mode_button.set_name ("MouseModeButton");
-
- automation_box.set_spacing (2);
- automation_box.set_border_width (2);
- automation_box.pack_start (global_automation_button, false, false);
- automation_box.pack_start (automation_mode_button, false, false);
-
- /* Edit mode */
-
- edit_mode_label.set_name ("ToolBarLabel");
-
- edit_mode_selector.set_name ("EditModeSelector");
+ /* Zoom */
+
+ zoom_box.set_spacing (1);
+ zoom_box.set_border_width (2);
- edit_mode_box.set_spacing (3);
- edit_mode_box.set_border_width (3);
+ zoom_in_button.set_name ("EditorTimeButton");
+ zoom_in_button.add (*(manage (new Image (get_xpm("zoom_in.xpm")))));
+ zoom_in_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), false));
+ ARDOUR_UI::instance()->tooltips().set_tip (zoom_in_button, _("Zoom In"));
+
+ zoom_out_button.set_name ("EditorTimeButton");
+ zoom_out_button.add (*(manage (new Image (get_xpm("zoom_out.xpm")))));
+ zoom_out_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::temporal_zoom_step), true));
+ ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_button, _("Zoom Out"));
- /* XXX another disgusting hack because of the way combo boxes size themselves */
+ zoom_out_full_button.set_name ("EditorTimeButton");
+ zoom_out_full_button.add (*(manage (new Image (get_xpm("zoom_full.xpm")))));
+ zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
+ ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
+
+ zoom_box.pack_start (zoom_out_button, false, false);
+ zoom_box.pack_start (zoom_in_button, false, false);
+ zoom_box.pack_start (zoom_range_clock, false, false);
+ zoom_box.pack_start (zoom_out_full_button, false, false);
+
+ ARDOUR_UI::instance()->tooltips().set_tip (zoom_range_clock, _("Current Zoom Range\n(Width of visible area)"));
+
+ zoom_focus_selector.set_name ("ZoomFocusSelector");
+ Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Focus Center", 2+FUDGE, 0);
+ set_popdown_strings (zoom_focus_selector, internationalize (zoom_focus_strings));
+ zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
- const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
- Gtkmm2ext::set_size_request_to_display_given_text (edit_mode_selector, "EdgtMode", 2+FUDGE, 10);
- set_popdown_strings (edit_mode_selector, internationalize (edit_mode_strings));
- edit_mode_box.pack_start (edit_mode_label, false, false);
- edit_mode_box.pack_start (edit_mode_selector, false, false);
+ zoom_box.pack_start (zoom_focus_selector, false, false);
- edit_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_mode_selection_done));
- /* Snap Type */
+ /* Edit Cursor / Snap */
- snap_type_label.set_name ("ToolBarLabel");
+ snap_box.set_spacing (1);
+ snap_box.set_border_width (2);
snap_type_selector.set_name ("SnapTypeSelector");
-
- snap_type_box.set_spacing (3);
- snap_type_box.set_border_width (3);
-
- /* XXX another disgusting hack because of the way combo boxes size themselves */
-
Gtkmm2ext::set_size_request_to_display_given_text (snap_type_selector, "SMPTE Seconds", 2+FUDGE, 10);
set_popdown_strings (snap_type_selector, internationalize (snap_type_strings));
-
- snap_type_box.pack_start (snap_type_label, false, false);
- snap_type_box.pack_start (snap_type_selector, false, false);
-
snap_type_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_type_selection_done));
-
- /* Snap mode, not snap type */
-
- snap_mode_label.set_name ("ToolBarLabel");
+ ARDOUR_UI::instance()->tooltips().set_tip (snap_type_selector, _("Unit to snap cursors and ranges to"));
snap_mode_selector.set_name ("SnapModeSelector");
-
- snap_mode_box.set_spacing (3);
- snap_mode_box.set_border_width (3);
-
- Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "SngpMode", 2+FUDGE, 10);
+ Gtkmm2ext::set_size_request_to_display_given_text (snap_mode_selector, "Magnetic Snap", 2+FUDGE, 10);
set_popdown_strings (snap_mode_selector, internationalize (snap_mode_strings));
-
- snap_mode_box.pack_start (snap_mode_label, false, false);
- snap_mode_box.pack_start (snap_mode_selector, false, false);
-
snap_mode_selector.signal_changed().connect (mem_fun(*this, &Editor::snap_mode_selection_done));
- /* Zoom focus mode */
-
- zoom_focus_label.set_name ("ToolBarLabel");
-
- zoom_focus_selector.set_name ("ZoomFocusSelector");
-
- zoom_focus_box.set_spacing (3);
- zoom_focus_box.set_border_width (3);
-
- /* XXX another disgusting hack because of the way combo boxes size themselves */
-
- Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Edgt Cursor", 2+FUDGE, 10);
- set_popdown_strings (zoom_focus_selector, internationalize (zoom_focus_strings));
-
- zoom_focus_box.pack_start (zoom_focus_label, false, false);
- zoom_focus_box.pack_start (zoom_focus_selector, false, false);
-
- zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
-
- /* selection/cursor clocks */
-
- toolbar_selection_cursor_label.set_name ("ToolBarLabel");
- selection_start_clock_label.set_name ("ToolBarLabel");
- selection_end_clock_label.set_name ("ToolBarLabel");
- edit_cursor_clock_label.set_name ("ToolBarLabel");
-
- selection_start_clock_label.set_text (_("Start:"));
- selection_end_clock_label.set_text (_("End:"));
- edit_cursor_clock_label.set_text (_("Edit"));
-
- /* the zoom in/out buttons are generally taller than the clocks, so
- put all the toolbar clocks into a size group with one of the
- buttons to make them all equal height.
+ snap_box.pack_start (edit_cursor_clock, false, false);
+ snap_box.pack_start (snap_mode_selector, false, false);
+ snap_box.pack_start (snap_type_selector, false, false);
- this also applies to the various toolbar combos
- */
-
- RefPtr<SizeGroup> toolbar_clock_size_group = SizeGroup::create (SIZE_GROUP_VERTICAL);
- toolbar_clock_size_group->add_widget (zoom_out_button);
- toolbar_clock_size_group->add_widget (edit_cursor_clock);
- toolbar_clock_size_group->add_widget (zoom_range_clock);
- toolbar_clock_size_group->add_widget (nudge_clock);
- toolbar_clock_size_group->add_widget (edit_mode_selector);
- toolbar_clock_size_group->add_widget (snap_type_selector);
- toolbar_clock_size_group->add_widget (snap_mode_selector);
- toolbar_clock_size_group->add_widget (zoom_focus_selector);
-
- HBox* edit_clock_hbox = manage (new HBox());
- VBox* edit_clock_vbox = manage (new VBox());
-
- edit_clock_hbox->pack_start (edit_cursor_clock, false, false);
-
- edit_clock_vbox->set_spacing (3);
- edit_clock_vbox->set_border_width (3);
- edit_clock_vbox->pack_start (edit_cursor_clock_label, false, false);
- edit_clock_vbox->pack_start (*edit_clock_hbox, false, false);
-
- HBox* hbox = new HBox;
- hbox->pack_start (*edit_clock_vbox, false, false);
- hbox->pack_start (zoom_indicator_vbox, false, false);
- hbox->pack_start (zoom_focus_box, false, false);
- hbox->pack_start (snap_type_box, false, false);
- hbox->pack_start (snap_mode_box, false, false);
- hbox->pack_start (edit_mode_box, false, false);
+ /* Nudge */
- VBox *vbox = manage (new VBox);
+ HBox *nudge_box = manage (new HBox);
+ nudge_box->set_spacing(1);
+ nudge_box->set_border_width (2);
- vbox->set_spacing (3);
- vbox->set_border_width (3);
-
- HBox *nbox = manage (new HBox);
-
nudge_forward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_forward), false));
nudge_backward_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::nudge_backward), false));
- nbox->pack_start (nudge_backward_button, false, false);
- nbox->pack_start (nudge_forward_button, false, false);
- nbox->pack_start (nudge_clock, false, false, 5);
-
- nudge_label.set_name ("ToolBarLabel");
+ nudge_box->pack_start (nudge_backward_button, false, false);
+ nudge_box->pack_start (nudge_forward_button, false, false);
+ nudge_box->pack_start (nudge_clock, false, false);
- vbox->pack_start (nudge_label, false, false);
- vbox->pack_start (*nbox, false, false);
- hbox->pack_start (*vbox, false, false);
+ /* Pack everything in... */
- hbox->show_all ();
+ HBox* hbox = new HBox;
+ hbox->set_spacing(10);
tools_tearoff = new TearOff (*hbox);
tools_tearoff->set_name ("MouseModeBase");
@@ -2819,11 +2720,18 @@ Editor::setup_toolbar ()
tools_tearoff->Visible.connect (bind (mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
&tools_tearoff->tearoff_window(), 0));
- toolbar_hbox.set_spacing (8);
- toolbar_hbox.set_border_width (2);
+ toolbar_hbox.set_spacing (10);
+ toolbar_hbox.set_border_width (1);
- toolbar_hbox.pack_start (*tools_tearoff, false, false);
toolbar_hbox.pack_start (*mouse_mode_tearoff, false, false);
+ toolbar_hbox.pack_start (*tools_tearoff, false, false);
+
+
+ hbox->pack_start (snap_box, false, false);
+ hbox->pack_start (zoom_box, false, false);
+ hbox->pack_start (*nudge_box, false, false);
+
+ hbox->show_all ();
toolbar_base.set_name ("ToolBarBase");
toolbar_base.add (toolbar_hbox);
@@ -3055,7 +2963,7 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie
continue;
}
- RouteGroup* group = atv->route().edit_group();
+ RouteGroup* group = atv->route()->edit_group();
if (group && group->is_active()) {
@@ -3067,7 +2975,7 @@ Editor::get_relevant_audio_tracks (AudioTimeAxisView& base, set<AudioTimeAxisVie
if ((tatv = dynamic_cast<AudioTimeAxisView*> (*i)) != 0) {
- if (tatv->route().edit_group() == group) {
+ if (tatv->route()->edit_group() == group) {
relevant_tracks.insert (tatv);
}
}
@@ -3102,31 +3010,31 @@ Editor::mapover_audio_tracks (slot<void,AudioTimeAxisView&,uint32_t> sl)
}
void
-Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint32_t ignored,
- AudioRegionView* basis, vector<AudioRegionView*>* all_equivs)
+Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored,
+ RegionView* basis, vector<RegionView*>* all_equivs)
{
- AudioPlaylist* pl;
- vector<AudioRegion*> results;
- AudioRegionView* marv;
- AudioDiskstream* ds;
+ Playlist* pl;
+ vector<Region*> results;
+ RegionView* marv;
+ Diskstream* ds;
- if ((ds = atv.get_diskstream()) == 0) {
+ if ((ds = tv.get_diskstream()) == 0) {
/* bus */
return;
}
- if (&atv == &basis->get_time_axis_view()) {
+ if (&tv == &basis->get_time_axis_view()) {
/* looking in same track as the original */
return;
}
- if ((pl = ds->playlist()) != 0) {
- pl->get_equivalent_regions (basis->region, results);
+ if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+ pl->get_equivalent_regions (basis->region(), results);
}
- for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
- if ((marv = atv.view->find_view (**ir)) != 0) {
+ for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
+ if ((marv = tv.view()->find_view (**ir)) != 0) {
all_equivs->push_back (marv);
}
}
@@ -3135,7 +3043,7 @@ Editor::mapped_set_selected_regionview_from_click (AudioTimeAxisView& atv, uint3
bool
Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
{
- vector<AudioRegionView*> all_equivalent_regions;
+ vector<RegionView*> all_equivalent_regions;
bool commit = false;
if (!clicked_regionview || !clicked_audio_trackview) {
@@ -3190,7 +3098,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
commit = true;
}
- for (vector<AudioRegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
+ for (vector<RegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
selection->add (*i);
}
}
@@ -3223,58 +3131,58 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
last_frame = 0;
first_frame = max_frames;
- for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
+ for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
- if ((*x)->region.last_frame() > last_frame) {
- last_frame = (*x)->region.last_frame();
+ if ((*x)->region().last_frame() > last_frame) {
+ last_frame = (*x)->region().last_frame();
}
- if ((*x)->region.first_frame() < first_frame) {
- first_frame = (*x)->region.first_frame();
+ if ((*x)->region().first_frame() < first_frame) {
+ first_frame = (*x)->region().first_frame();
}
}
}
/* 2. figure out the boundaries for our search for new objects */
- switch (clicked_regionview->region.coverage (first_frame, last_frame)) {
+ switch (clicked_regionview->region().coverage (first_frame, last_frame)) {
case OverlapNone:
cerr << "no overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
+ << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
- if (last_frame < clicked_regionview->region.first_frame()) {
+ if (last_frame < clicked_regionview->region().first_frame()) {
first_frame = last_frame;
- last_frame = clicked_regionview->region.last_frame();
+ last_frame = clicked_regionview->region().last_frame();
} else {
last_frame = first_frame;
- first_frame = clicked_regionview->region.first_frame();
+ first_frame = clicked_regionview->region().first_frame();
}
break;
case OverlapExternal:
cerr << "external overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
+ << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
- if (last_frame < clicked_regionview->region.first_frame()) {
+ if (last_frame < clicked_regionview->region().first_frame()) {
first_frame = last_frame;
- last_frame = clicked_regionview->region.last_frame();
+ last_frame = clicked_regionview->region().last_frame();
} else {
last_frame = first_frame;
- first_frame = clicked_regionview->region.first_frame();
+ first_frame = clicked_regionview->region().first_frame();
}
break;
case OverlapInternal:
cerr << "internal overlap, first = " << first_frame << " last = " << last_frame << " region = "
- << clicked_regionview->region.first_frame() << " .. " << clicked_regionview->region.last_frame() << endl;
+ << clicked_regionview->region().first_frame() << " .. " << clicked_regionview->region().last_frame() << endl;
- if (last_frame < clicked_regionview->region.first_frame()) {
+ if (last_frame < clicked_regionview->region().first_frame()) {
first_frame = last_frame;
- last_frame = clicked_regionview->region.last_frame();
+ last_frame = clicked_regionview->region().last_frame();
} else {
last_frame = first_frame;
- first_frame = clicked_regionview->region.first_frame();
+ first_frame = clicked_regionview->region().first_frame();
}
break;
@@ -3300,18 +3208,18 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
/* 3. convert to a vector of audio regions */
- vector<AudioRegionView*> audio_regions;
+ vector<RegionView*> regions;
for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) {
- AudioRegionView* arv;
+ RegionView* arv;
- if ((arv = dynamic_cast<AudioRegionView*>(*x)) != 0) {
- audio_regions.push_back (arv);
+ if ((arv = dynamic_cast<RegionView*>(*x)) != 0) {
+ regions.push_back (arv);
}
}
- if (!audio_regions.empty()) {
- selection->add (audio_regions);
+ if (!regions.empty()) {
+ selection->add (regions);
commit = true;
}
}
@@ -3321,37 +3229,32 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
}
void
-Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operation op)
+Editor::set_selected_regionview_from_region_list (Region& region, Selection::Operation op)
{
- vector<AudioRegionView*> all_equivalent_regions;
- AudioRegion* region;
-
- if ((region = dynamic_cast<AudioRegion*>(&r)) == 0) {
- return;
- }
+ vector<RegionView*> all_equivalent_regions;
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- AudioTimeAxisView* tatv;
+ RouteTimeAxisView* tatv;
- if ((tatv = dynamic_cast<AudioTimeAxisView*> (*i)) != 0) {
+ if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
- AudioPlaylist* pl;
- vector<AudioRegion*> results;
- AudioRegionView* marv;
- AudioDiskstream* ds;
+ Playlist* pl;
+ vector<Region*> results;
+ RegionView* marv;
+ Diskstream* ds;
if ((ds = tatv->get_diskstream()) == 0) {
/* bus */
continue;
}
- if ((pl = ds->playlist()) != 0) {
- pl->get_region_list_equivalent_regions (*region, results);
+ if ((pl = dynamic_cast<Playlist*>(ds->playlist())) != 0) {
+ pl->get_region_list_equivalent_regions (region, results);
}
- for (vector<AudioRegion*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
- if ((marv = tatv->view->find_view (**ir)) != 0) {
+ for (vector<Region*>::iterator ir = results.begin(); ir != results.end(); ++ir) {
+ if ((marv = tatv->view()->find_view (**ir)) != 0) {
all_equivalent_regions.push_back (marv);
}
}
@@ -3380,10 +3283,10 @@ Editor::set_selected_regionview_from_region_list (Region& r, Selection::Operatio
bool
Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, Region* r)
{
- AudioRegionView* rv;
- AudioRegion* ar;
+ RegionView* rv;
+ Region* ar;
- if ((ar = dynamic_cast<AudioRegion*> (r)) == 0) {
+ if ((ar = dynamic_cast<Region*> (r)) == 0) {
return TRUE;
}
@@ -3395,7 +3298,7 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv,
a single other region.
*/
- if (selection->audio_regions.size() > 1) {
+ if (selection->regions.size() > 1) {
return TRUE;
}
@@ -3560,7 +3463,7 @@ Editor::duplicate_dialog (bool dup_region)
if (sscanf (text.c_str(), "%f", &times) == 1) {
if (dup_region) {
- AudioRegionSelection regions;
+ RegionSelection regions;
regions.add (clicked_regionview);
duplicate_some_regions (regions, times);
} else {
@@ -3611,9 +3514,9 @@ Editor::edit_mode_selection_done ()
string choice = edit_mode_selector.get_active_text();
EditMode mode = Slide;
- if (choice == _("Splice")) {
+ if (choice == _("Splice Edit")) {
mode = Splice;
- } else if (choice == _("Slide")) {
+ } else if (choice == _("Slide Edit")) {
mode = Slide;
}
@@ -3629,18 +3532,18 @@ Editor::snap_type_selection_done ()
string choice = snap_type_selector.get_active_text();
SnapType snaptype = SnapToFrame;
-
+
if (choice == _("Beats/3")) {
- snaptype = SnapToAThirdBeat;
- } else if (choice == _("Beats/4")) {
- snaptype = SnapToAQuarterBeat;
- } else if (choice == _("Beats/8")) {
- snaptype = SnapToAEighthBeat;
- } else if (choice == _("Beats/16")) {
- snaptype = SnapToASixteenthBeat;
- } else if (choice == _("Beats/32")) {
- snaptype = SnapToAThirtysecondBeat;
- } else if (choice == _("Beats")) {
+ snaptype = SnapToAThirdBeat;
+ } else if (choice == _("Beats/4")) {
+ snaptype = SnapToAQuarterBeat;
+ } else if (choice == _("Beats/8")) {
+ snaptype = SnapToAEighthBeat;
+ } else if (choice == _("Beats/16")) {
+ snaptype = SnapToASixteenthBeat;
+ } else if (choice == _("Beats/32")) {
+ snaptype = SnapToAThirtysecondBeat;
+ } else if (choice == _("Beats")) {
snaptype = SnapToBeat;
} else if (choice == _("Bars")) {
snaptype = SnapToBar;
@@ -3668,10 +3571,10 @@ Editor::snap_type_selection_done ()
snaptype = SnapToSeconds;
} else if (choice == _("Minutes")) {
snaptype = SnapToMinutes;
- } else if (choice == _("None")) {
+ } else if (choice == _("None")) {
snaptype = SnapToFrame;
}
-
+
set_snap_to (snaptype);
}
@@ -3685,9 +3588,9 @@ Editor::snap_mode_selection_done ()
string choice = snap_mode_selector.get_active_text();
SnapMode mode = SnapNormal;
- if (choice == _("Normal")) {
+ if (choice == _("Normal Snap")) {
mode = SnapNormal;
- } else if (choice == _("Magnetic")) {
+ } else if (choice == _("Magnetic Snap")) {
mode = SnapMagnetic;
}
@@ -3704,15 +3607,15 @@ Editor::zoom_focus_selection_done ()
string choice = zoom_focus_selector.get_active_text();
ZoomFocus focus_type = ZoomFocusLeft;
- if (choice == _("Left")) {
+ if (choice == _("Focus Left")) {
focus_type = ZoomFocusLeft;
- } else if (choice == _("Right")) {
+ } else if (choice == _("Focus Right")) {
focus_type = ZoomFocusRight;
- } else if (choice == _("Center")) {
+ } else if (choice == _("Focus Center")) {
focus_type = ZoomFocusCenter;
- } else if (choice == _("Playhead")) {
+ } else if (choice == _("Focus Playhead")) {
focus_type = ZoomFocusPlayhead;
- } else if (choice == _("Edit Cursor")) {
+ } else if (choice == _("Focus Edit Cursor")) {
focus_type = ZoomFocusEdit;
}
@@ -3782,7 +3685,7 @@ void
Editor::region_selection_changed ()
{
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
- (*i)->set_selected_regionviews (selection->audio_regions);
+ (*i)->set_selected_regionviews (selection->regions);
}
}
@@ -4052,8 +3955,8 @@ Editor::playlist_deletion_dialog (Playlist* pl)
bool
Editor::audio_region_selection_covers (jack_nframes_t where)
{
- for (AudioRegionSelection::iterator a = selection->audio_regions.begin(); a != selection->audio_regions.end(); ++a) {
- if ((*a)->region.covers (where)) {
+ for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
+ if ((*a)->region().covers (where)) {
return true;
}
}
@@ -4064,10 +3967,10 @@ Editor::audio_region_selection_covers (jack_nframes_t where)
void
Editor::prepare_for_cleanup ()
{
- cut_buffer->clear_audio_regions ();
+ cut_buffer->clear_regions ();
cut_buffer->clear_playlists ();
- selection->clear_audio_regions ();
+ selection->clear_regions ();
selection->clear_playlists ();
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 478a8c96ab..c31dfd5ede 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -40,7 +40,7 @@
#include <gtkmm2ext/click_box.h>
#include <gtkmm2ext/dndtreeview.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
#include <ardour/session.h>
#include <ardour/tempo.h>
#include <ardour/location.h>
@@ -69,6 +69,7 @@ namespace ARDOUR {
class AudioDiskstream;
class RouteGroup;
class Playlist;
+ class AudioPlaylist;
class Region;
class Location;
class TempoSection;
@@ -83,6 +84,7 @@ namespace LADSPA {
}
class TimeAxisView;
+class RouteTimeAxisView;
class AudioTimeAxisView;
class AutomationTimeAxisView;
class AudioRegionView;
@@ -100,6 +102,7 @@ class TrackSelection;
class AutomationSelection;
class MixerStrip;
class StreamView;
+class AudioStreamView;
class ControlPoint;
#ifdef FFT_ANALYSIS
class AnalysisWindow;
@@ -405,8 +408,8 @@ class Editor : public PublicEditor
TimeAxisView* clicked_trackview;
AudioTimeAxisView* clicked_audio_trackview;
- AudioRegionView* clicked_regionview;
- AudioRegionView* latest_regionview;
+ RegionView* clicked_regionview;
+ RegionView* latest_regionview;
uint32_t clicked_selection;
CrossfadeView* clicked_crossfadeview;
ControlPoint* clicked_control_point;
@@ -416,7 +419,7 @@ class Editor : public PublicEditor
/* functions to be passed to mapover_audio_tracks(), possibly with sigc::bind()-supplied arguments */
- void mapped_set_selected_regionview_from_click (AudioTimeAxisView&, uint32_t, AudioRegionView*, vector<AudioRegionView*>*);
+ void mapped_set_selected_regionview_from_click (RouteTimeAxisView&, uint32_t, RegionView*, vector<RegionView*>*);
void mapped_use_new_playlist (AudioTimeAxisView&, uint32_t);
void mapped_use_copy_playlist (AudioTimeAxisView&, uint32_t);
void mapped_clear_playlist (AudioTimeAxisView&, uint32_t);
@@ -426,7 +429,7 @@ class Editor : public PublicEditor
void button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type);
bool button_release_can_deselect;
- void catch_vanishing_audio_regionview (AudioRegionView *);
+ void catch_vanishing_regionview (RegionView *);
bool set_selected_control_point_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool with_undo = true, bool no_remove=false);
@@ -434,7 +437,7 @@ class Editor : public PublicEditor
void set_selected_regionview_from_region_list (ARDOUR::Region& region, Selection::Operation op = Selection::Set);
bool set_selected_regionview_from_map_event (GdkEventAny*, StreamView*, ARDOUR::Region*);
- void collect_new_region_view (AudioRegionView *);
+ void collect_new_region_view (RegionView *);
Gtk::Menu track_context_menu;
Gtk::Menu track_region_context_menu;
@@ -455,12 +458,11 @@ class Editor : public PublicEditor
Gtk::Menu* build_track_selection_context_menu (jack_nframes_t);
void add_dstream_context_items (Gtk::Menu_Helpers::MenuList&);
void add_bus_context_items (Gtk::Menu_Helpers::MenuList&);
- void add_region_context_items (StreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&);
- void add_crossfade_context_items (StreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
+ void add_region_context_items (AudioStreamView*, ARDOUR::Region*, Gtk::Menu_Helpers::MenuList&);
+ void add_crossfade_context_items (AudioStreamView*, ARDOUR::Crossfade*, Gtk::Menu_Helpers::MenuList&, bool many);
void add_selection_context_items (Gtk::Menu_Helpers::MenuList&);
- void handle_new_route (ARDOUR::Route&);
- void handle_new_route_p (ARDOUR::Route*);
+ void handle_new_route (boost::shared_ptr<ARDOUR::Route>);
void remove_route (TimeAxisView *);
bool route_removal;
@@ -854,7 +856,7 @@ class Editor : public PublicEditor
void lower_region_to_bottom ();
void split_region ();
void split_region_at (jack_nframes_t);
- void split_regions_at (jack_nframes_t, AudioRegionSelection&);
+ void split_regions_at (jack_nframes_t, RegionSelection&);
void crop_region_to_selection ();
void set_a_regions_sync_position (ARDOUR::Region&, jack_nframes_t);
void set_region_sync_from_edit_cursor ();
@@ -867,13 +869,13 @@ class Editor : public PublicEditor
void remove_clicked_region ();
void destroy_clicked_region ();
void edit_region ();
- void duplicate_some_regions (AudioRegionSelection&, float times);
+ void duplicate_some_regions (RegionSelection&, float times);
void duplicate_selection (float times);
void region_fill_selection ();
void region_fill_track ();
- void audition_playlist_region_standalone (ARDOUR::AudioRegion&);
- void audition_playlist_region_via_route (ARDOUR::AudioRegion&, ARDOUR::Route&);
+ void audition_playlist_region_standalone (ARDOUR::Region&);
+ void audition_playlist_region_via_route (ARDOUR::Region&, ARDOUR::Route&);
void split_multichannel_region();
void reverse_region ();
void normalize_region ();
@@ -1020,7 +1022,7 @@ class Editor : public PublicEditor
bool have_pending_keyboard_selection;
jack_nframes_t pending_keyboard_selection_start;
- ARDOUR::AudioRegion* select_region_for_operation (int dir, TimeAxisView **tv);
+ ARDOUR::Region* select_region_for_operation (int dir, TimeAxisView **tv);
void extend_selection_to_end_of_region (bool next);
void extend_selection_to_start_of_region (bool previous);
@@ -1094,7 +1096,7 @@ class Editor : public PublicEditor
void remove_gain_control_point (ArdourCanvas::Item*, GdkEvent*);
void remove_control_point (ArdourCanvas::Item*, GdkEvent*);
- void mouse_brush_insert_region (AudioRegionView*, jack_nframes_t pos);
+ void mouse_brush_insert_region (RegionView*, jack_nframes_t pos);
void brush (jack_nframes_t);
void show_verbose_time_cursor (jack_nframes_t frame, double offset = 0, double xpos=-1, double ypos=-1);
@@ -1112,10 +1114,10 @@ class Editor : public PublicEditor
bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
- bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
- bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
- bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*);
- bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*);
+ bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
+ bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
+ bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*);
+ bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*);
bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*);
bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*);
bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*);
@@ -1263,12 +1265,7 @@ class Editor : public PublicEditor
void editor_mixer_button_toggled ();
- AudioClock selection_start_clock;
- Gtk::Label selection_start_clock_label;
- AudioClock selection_end_clock;
- Gtk::Label selection_end_clock_label;
AudioClock edit_cursor_clock;
- Gtk::Label edit_cursor_clock_label;
AudioClock zoom_range_clock;
Gtk::Button zoom_in_button;
Gtk::Button zoom_out_button;
@@ -1280,8 +1277,8 @@ class Editor : public PublicEditor
Gtk::Table toolbar_selection_clock_table;
Gtk::Label toolbar_selection_cursor_label;
- Gtk::Table mouse_mode_button_table;
- Gtkmm2ext::TearOff* mouse_mode_tearoff;
+ Gtk::HBox mouse_mode_button_box;
+ Gtkmm2ext::TearOff* mouse_mode_tearoff;
Gtk::ToggleButton mouse_select_button;
Gtk::ToggleButton mouse_move_button;
Gtk::ToggleButton mouse_gain_button;
@@ -1299,32 +1296,23 @@ class Editor : public PublicEditor
Gtk::ToggleButton global_automation_button;
Gtk::ComboBoxText edit_mode_selector;
- Gtk::Label edit_mode_label;
- Gtk::VBox edit_mode_box;
+ Gtk::VBox edit_mode_box;
void edit_mode_selection_done ();
Gtk::ComboBoxText snap_type_selector;
- Gtk::Label snap_type_label;
- Gtk::VBox snap_type_box;
+ Gtk::ComboBoxText snap_mode_selector;
+ Gtk::HBox snap_box;
void snap_type_selection_done ();
-
- Gtk::ComboBoxText snap_mode_selector;
- Gtk::Label snap_mode_label;
- Gtk::VBox snap_mode_box;
-
void snap_mode_selection_done ();
Gtk::ComboBoxText zoom_focus_selector;
- Gtk::Label zoom_focus_label;
Gtk::VBox zoom_focus_box;
void zoom_focus_selection_done ();
- Gtk::Label zoom_indicator_label;
- Gtk::HBox zoom_indicator_box;
- Gtk::VBox zoom_indicator_vbox;
+ Gtk::HBox zoom_box;
void update_zoom_indicator ();
void zoom_adjustment_changed();
@@ -1533,12 +1521,12 @@ class Editor : public PublicEditor
void start_trim (ArdourCanvas::Item*, GdkEvent*);
void point_trim (GdkEvent*);
void trim_motion_callback (ArdourCanvas::Item*, GdkEvent*);
- void single_contents_trim (AudioRegionView&, jack_nframes_t, bool, bool, bool);
- void single_start_trim (AudioRegionView&, jack_nframes_t, bool, bool);
- void single_end_trim (AudioRegionView&, jack_nframes_t, bool, bool);
+ void single_contents_trim (RegionView&, jack_nframes_t, bool, bool, bool);
+ void single_start_trim (RegionView&, jack_nframes_t, bool, bool);
+ void single_end_trim (RegionView&, jack_nframes_t, bool, bool);
void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
- void thaw_region_after_trim (AudioRegionView& rv);
+ void thaw_region_after_trim (RegionView& rv);
void trim_region_to_edit_cursor ();
void trim_region_from_edit_cursor ();
@@ -1592,7 +1580,7 @@ class Editor : public PublicEditor
void export_range (jack_nframes_t start, jack_nframes_t end);
void export_range_markers ();
- int write_region_selection(AudioRegionSelection&);
+ int write_region_selection(RegionSelection&);
bool write_region (string path, ARDOUR::AudioRegion&);
void export_region ();
void bounce_region_selection ();
@@ -1600,7 +1588,7 @@ class Editor : public PublicEditor
void external_edit_region ();
int write_audio_selection (TimeSelection&);
- bool write_audio_range (ARDOUR::Playlist&, uint32_t channels, list<ARDOUR::AudioRange>&);
+ bool write_audio_range (ARDOUR::AudioPlaylist&, uint32_t channels, list<ARDOUR::AudioRange>&);
void write_selection ();
@@ -1671,7 +1659,7 @@ class Editor : public PublicEditor
struct TimeStretchDialog : public ArdourDialog {
ARDOUR::Session::TimeStretchRequest request;
Editor& editor;
- AudioRegionSelection regions;
+ RegionSelection regions;
Gtk::ProgressBar progress_bar;
Gtk::ToggleButton quick_button;
Gtk::ToggleButton antialias_button;
@@ -1697,7 +1685,7 @@ class Editor : public PublicEditor
TimeStretchDialog* current_timestretch;
static void* timestretch_thread (void *arg);
- int run_timestretch (AudioRegionSelection&, float fraction);
+ int run_timestretch (RegionSelection&, float fraction);
void do_timestretch (TimeStretchDialog&);
/* editor-mixer strip */
@@ -1776,7 +1764,6 @@ class Editor : public PublicEditor
Gtk::Button nudge_backward_button;
Gtk::HBox nudge_hbox;
Gtk::VBox nudge_vbox;
- Gtk::Label nudge_label;
AudioClock nudge_clock;
jack_nframes_t get_nudge_distance (jack_nframes_t pos, jack_nframes_t& next);
@@ -1799,11 +1786,11 @@ class Editor : public PublicEditor
sigc::connection step_timeout;
TimeAxisView* entered_track;
- AudioRegionView* entered_regionview;
+ RegionView* entered_regionview;
bool clear_entered_track;
gint left_track_canvas (GdkEventCrossing*);
void set_entered_track (TimeAxisView*);
- void set_entered_regionview (AudioRegionView*);
+ void set_entered_regionview (RegionView*);
gint left_automation_track ();
bool _new_regionviews_show_envelope;
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index e20e6ee8eb..65195ca822 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -357,6 +357,8 @@ Editor::register_actions ()
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsTrack"), _("as Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTrack));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, X_("addExternalAudioAsTapeTrack"), _("as Tape Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportAsTapeTrack));
+ ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (editor_actions, X_("addExternalAudioToTrack"), _("to Tracks"), bind (mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 2c64f2cf15..7524f9605c 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -268,7 +268,7 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
idspec += string_compose(":%1", n);
try {
- source = AudioFileSource::create (idspec.c_str());
+ source = AudioFileSource::create (idspec.c_str(), (mode == ImportAsTrack ? AudioFileSource::Destructive : AudioFileSource::Flag (0)));
sources.push_back(source);
}
@@ -306,16 +306,18 @@ Editor::embed_sndfile (Glib::ustring path, bool split, bool multiple_files, bool
}
int
- Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, jack_nframes_t& pos, ImportMode mode)
- {
- switch (mode) {
- case ImportAsRegion:
- /* relax, its been done */
- break;
+Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32_t out_chans, AudioTrack* track, jack_nframes_t& pos, ImportMode mode)
+{
+ AudioRegion* copy;
+
+ switch (mode) {
+ case ImportAsRegion:
+ /* relax, its been done */
+ break;
case ImportToTrack:
if (track) {
- Playlist* playlist = track->disk_stream().playlist();
+ Playlist* playlist = track->diskstream().playlist();
AudioRegion* copy = new AudioRegion (region);
begin_reversible_command (_("insert sndfile"));
@@ -329,11 +331,21 @@ int
break;
case ImportAsTrack:
- AudioTrack* at = session->new_audio_track (in_chans, out_chans);
- AudioRegion* copy = new AudioRegion (region);
- at->disk_stream().playlist()->add_region (*copy, pos);
+ {
+ boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Normal));
+ copy = new AudioRegion (region);
+ at->diskstream().playlist()->add_region (*copy, pos);
+ break;
+ }
+
+ case ImportAsTapeTrack:
+ {
+ boost::shared_ptr<AudioTrack> at (session->new_audio_track (in_chans, out_chans, Destructive));
+ copy = new AudioRegion (region);
+ at->diskstream().playlist()->add_region (*copy, pos);
break;
}
+ }
return 0;
}
diff --git a/gtk2_ardour/editor_audiotrack.cc b/gtk2_ardour/editor_audiotrack.cc
index acad3371a0..5b575b4814 100644
--- a/gtk2_ardour/editor_audiotrack.cc
+++ b/gtk2_ardour/editor_audiotrack.cc
@@ -4,7 +4,7 @@
#include "editor.h"
#include "editing.h"
#include "audio_time_axis.h"
-#include "regionview.h"
+#include "region_view.h"
#include "selection.h"
using namespace ARDOUR;
diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc
index 41350a1da4..e8ba2b8a60 100644
--- a/gtk2_ardour/editor_canvas.cc
+++ b/gtk2_ardour/editor_canvas.cc
@@ -128,7 +128,7 @@ Editor::initialize_canvas ()
time_line_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
cursor_group = new ArdourCanvas::Group (*track_canvas.root(), 0.0, 0.0);
-
+
time_canvas.set_name ("EditorTimeCanvas");
time_canvas.add_events (Gdk::POINTER_MOTION_HINT_MASK);
time_canvas.set_flags (CAN_FOCUS);
diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc
index 43114534c5..8e635bbe13 100644
--- a/gtk2_ardour/editor_canvas_events.cc
+++ b/gtk2_ardour/editor_canvas_events.cc
@@ -26,8 +26,8 @@
#include "editor.h"
#include "public_editor.h"
-#include "regionview.h"
-#include "streamview.h"
+#include "audio_region_view.h"
+#include "audio_streamview.h"
#include "crossfade_view.h"
#include "audio_time_axis.h"
#include "region_gain_line.h"
@@ -212,7 +212,7 @@ Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type)
}
bool
-Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv)
+Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv)
{
gint ret = FALSE;
@@ -251,7 +251,7 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud
}
bool
-Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, AudioTimeAxisView *tv)
+Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv)
{
bool ret = FALSE;
@@ -262,7 +262,7 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Aud
clicked_regionview = 0;
clicked_control_point = 0;
clicked_trackview = tv;
- clicked_audio_trackview = tv;
+ clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(tv);
ret = button_press_handler (item, event, StreamItem);
break;
@@ -512,22 +512,25 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
if ((atv = dynamic_cast<AudioTimeAxisView*>(&tv)) != 0) {
if (atv->is_audio_track()) {
-
- AudioPlaylist* pl = atv->get_diskstream()->playlist();
- Playlist::RegionList* rl = pl->regions_at (event_frame (event));
- if (!rl->empty()) {
- DescendingRegionLayerSorter cmp;
- rl->sort (cmp);
+ AudioPlaylist* pl;
+ if ((pl = dynamic_cast<AudioPlaylist*> (atv->get_diskstream()->playlist())) != 0) {
+
+ Playlist::RegionList* rl = pl->regions_at (event_frame (event));
+
+ if (!rl->empty()) {
+ DescendingRegionLayerSorter cmp;
+ rl->sort (cmp);
- AudioRegionView* arv = atv->view->find_view (*(dynamic_cast<AudioRegion*> (rl->front())));
+ RegionView* rv = atv->view()->find_view (*rl->front());
- /* proxy */
-
- delete rl;
+ /* proxy */
- return canvas_region_view_event (event, arv->get_canvas_group(), arv);
- }
+ delete rl;
+
+ return canvas_region_view_event (event, rv->get_canvas_group(), rv);
+ }
+ }
}
}
@@ -696,7 +699,7 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it
bool
-Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, AudioRegionView* rv)
+Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv)
{
bool ret = false;
@@ -708,20 +711,20 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::
clicked_control_point = 0;
clicked_trackview = &clicked_regionview->get_time_axis_view();
clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
- ret = button_press_handler (item, event, AudioRegionViewNameHighlight);
+ ret = button_press_handler (item, event, RegionViewNameHighlight);
break;
case GDK_BUTTON_RELEASE:
- ret = button_release_handler (item, event, AudioRegionViewNameHighlight);
+ ret = button_release_handler (item, event, RegionViewNameHighlight);
break;
case GDK_MOTION_NOTIFY:
- ret = motion_handler (item, event, AudioRegionViewNameHighlight);
+ ret = motion_handler (item, event, RegionViewNameHighlight);
break;
case GDK_ENTER_NOTIFY:
- ret = enter_handler (item, event, AudioRegionViewNameHighlight);
+ ret = enter_handler (item, event, RegionViewNameHighlight);
break;
case GDK_LEAVE_NOTIFY:
- ret = leave_handler (item, event, AudioRegionViewNameHighlight);
+ ret = leave_handler (item, event, RegionViewNameHighlight);
break;
default:
@@ -732,7 +735,7 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::
}
bool
-Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView* rv)
+Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView* rv)
{
bool ret = false;
@@ -744,20 +747,20 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item
clicked_control_point = 0;
clicked_trackview = &clicked_regionview->get_time_axis_view();
clicked_audio_trackview = dynamic_cast<AudioTimeAxisView*>(clicked_trackview);
- ret = button_press_handler (item, event, AudioRegionViewName);
+ ret = button_press_handler (item, event, RegionViewName);
break;
case GDK_BUTTON_RELEASE:
- ret = button_release_handler (item, event, AudioRegionViewName);
+ ret = button_release_handler (item, event, RegionViewName);
break;
case GDK_MOTION_NOTIFY:
- ret = motion_handler (item, event, AudioRegionViewName);
+ ret = motion_handler (item, event, RegionViewName);
break;
case GDK_ENTER_NOTIFY:
- ret = enter_handler (item, event, AudioRegionViewName);
+ ret = enter_handler (item, event, RegionViewName);
break;
case GDK_LEAVE_NOTIFY:
- ret = leave_handler (item, event, AudioRegionViewName);
+ ret = leave_handler (item, event, RegionViewName);
break;
default:
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index 7339536e42..46a704b435 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -31,7 +31,7 @@
#include "selection.h"
#include "time_axis_view.h"
#include "audio_time_axis.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include <pbd/pthread_utils.h>
#include <ardour/types.h>
@@ -92,12 +92,12 @@ Editor::export_region ()
return;
}
- ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region);
+ ExportDialog* dialog = new ExportRegionDialog (*this, &clicked_regionview->region());
dialog->connect_to_session (session);
dialog->set_range (
- clicked_regionview->region.first_frame(),
- clicked_regionview->region.last_frame());
+ clicked_regionview->region().first_frame(),
+ clicked_regionview->region().last_frame());
dialog->start_export();
}
@@ -123,24 +123,26 @@ Editor::export_range_markers ()
}
int
-Editor::write_region_selection (AudioRegionSelection& regions)
+Editor::write_region_selection (RegionSelection& regions)
{
- for (AudioRegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
- if (write_region ("", (*i)->region) == false) {
- return -1;
- }
+ for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ if (write_region ("", arv->audio_region()) == false)
+ return -1;
}
+
return 0;
}
void
Editor::bounce_region_selection ()
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- AudioRegion& region ((*i)->region);
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&(*i)->get_time_axis_view());
- AudioTrack* track = dynamic_cast<AudioTrack*>(&(atv->route()));
+ Region& region ((*i)->region());
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
+ Track* track = dynamic_cast<Track*>(rtv->route().get());
InterThreadInfo itt;
@@ -287,7 +289,7 @@ Editor::write_audio_selection (TimeSelection& ts)
if (atv->is_audio_track()) {
- Playlist* playlist = atv->get_diskstream()->playlist();
+ AudioPlaylist* playlist = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
if (playlist && write_audio_range (*playlist, atv->get_diskstream()->n_channels(), ts) == 0) {
ret = -1;
@@ -300,7 +302,7 @@ Editor::write_audio_selection (TimeSelection& ts)
}
bool
-Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRange>& range)
+Editor::write_audio_range (AudioPlaylist& playlist, uint32_t channels, list<AudioRange>& range)
{
AudioFileSource* fs;
const jack_nframes_t chunk_size = 4096;
@@ -435,7 +437,7 @@ Editor::write_selection ()
{
if (!selection->time.empty()) {
write_audio_selection (selection->time);
- } else if (!selection->audio_regions.empty()) {
- write_region_selection (selection->audio_regions);
+ } else if (!selection->regions.empty()) {
+ write_region_selection (selection->regions);
}
}
diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h
index 4f6010ec2c..7f3a0d3fcc 100644
--- a/gtk2_ardour/editor_items.h
+++ b/gtk2_ardour/editor_items.h
@@ -23,8 +23,8 @@ enum ItemType {
TempoMarkerItem,
MeterBarItem,
TempoBarItem,
- AudioRegionViewNameHighlight,
- AudioRegionViewName,
+ RegionViewNameHighlight,
+ RegionViewName,
StartSelectionTrimItem,
EndSelectionTrimItem,
AutomationTrackItem,
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index b665f8b0a6..a0368b23b0 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -23,7 +23,7 @@
#include <pbd/memento_command.h>
#include "editor.h"
-#include "regionview.h"
+#include "region_view.h"
#include "selection.h"
#include "i18n.h"
@@ -82,10 +82,10 @@ Editor::kbd_do_split (GdkEvent* ev)
jack_nframes_t where = event_frame (ev);
if (entered_regionview) {
- if (selection->audio_regions.find (entered_regionview) != selection->audio_regions.end()) {
- split_regions_at (where, selection->audio_regions);
+ if (selection->regions.find (entered_regionview) != selection->regions.end()) {
+ split_regions_at (where, selection->regions);
} else {
- AudioRegionSelection s;
+ RegionSelection s;
s.add (entered_regionview);
split_regions_at (where, s);
}
@@ -103,11 +103,11 @@ Editor::kbd_mute_unmute_region ()
{
if (entered_regionview) {
begin_reversible_command (_("mute region"));
- XMLNode &before = entered_regionview->region.playlist()->get_state();
+ XMLNode &before = entered_regionview->region().playlist()->get_state();
- entered_regionview->region.set_muted (!entered_regionview->region.muted());
+ entered_regionview->region().set_muted (!entered_regionview->region().muted());
- XMLNode &after = entered_regionview->region.playlist()->get_state();
+ XMLNode &after = entered_regionview->region().playlist()->get_state();
session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region.playlist()), before, after));
commit_reversible_command();
}
@@ -126,7 +126,7 @@ Editor::kbd_do_set_sync_position (GdkEvent* ev)
snap_to (where);
if (entered_regionview) {
- set_a_regions_sync_position (entered_regionview->region, where);
+ set_a_regions_sync_position (entered_regionview->region(), where);
}
}
diff --git a/gtk2_ardour/editor_keys.cc b/gtk2_ardour/editor_keys.cc
index baa158cbf8..1bcaafd279 100644
--- a/gtk2_ardour/editor_keys.cc
+++ b/gtk2_ardour/editor_keys.cc
@@ -30,7 +30,7 @@
#include "ardour_ui.h"
#include "editor.h"
#include "time_axis_view.h"
-#include "regionview.h"
+#include "region_view.h"
#include "selection.h"
#include "i18n.h"
@@ -66,7 +66,7 @@ Editor::keyboard_selection_begin ()
void
Editor::keyboard_duplicate_region ()
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
@@ -74,9 +74,9 @@ Editor::keyboard_duplicate_region ()
bool was_floating;
if (get_prefix (prefix, was_floating) == 0) {
- duplicate_some_regions (selection->audio_regions, prefix);
+ duplicate_some_regions (selection->regions, prefix);
} else {
- duplicate_some_regions (selection->audio_regions, 1);
+ duplicate_some_regions (selection->regions, 1);
}
}
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index c4d8f3143f..ccc1415888 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -717,9 +717,9 @@ Editor::marker_menu_set_from_selection ()
}
}
else {
- if (!selection->audio_regions.empty()) {
- l->set_start (selection->audio_regions.start());
- l->set_end (selection->audio_regions.end_frame());
+ if (!selection->regions.empty()) {
+ l->set_start (selection->regions.start());
+ l->set_end (selection->regions.end_frame());
}
}
}
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index a55b6f2066..246dbdc647 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -131,7 +131,7 @@ Editor::set_selected_mixer_strip (TimeAxisView& view)
/* might be nothing to do */
- if (&current_mixer_strip->route() == &at->route()) {
+ if (current_mixer_strip->route() == at->route()) {
return;
}
@@ -221,7 +221,7 @@ Editor::current_mixer_strip_hidden ()
AudioTimeAxisView* tmp;
if ((tmp = dynamic_cast<AudioTimeAxisView*>(*i)) != 0) {
- if (&(tmp->route()) == &(current_mixer_strip->route())) {
+ if (tmp->route() == current_mixer_strip->route()) {
(*i)->set_selected (false);
break;
}
@@ -270,8 +270,6 @@ Editor::session_going_away ()
group_model->clear ();
edit_cursor_clock.set_session (0);
- selection_start_clock.set_session (0);
- selection_end_clock.set_session (0);
zoom_range_clock.set_session (0);
nudge_clock.set_session (0);
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index c7199984a8..f7abe7fdea 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -18,6 +18,7 @@
$Id$
*/
+#include <cassert>
#include <cstdlib>
#include <stdint.h>
#include <cmath>
@@ -33,7 +34,7 @@
#include "editor.h"
#include "time_axis_view.h"
#include "audio_time_axis.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "marker.h"
#include "streamview.h"
#include "region_gain_line.h"
@@ -183,7 +184,7 @@ Editor::set_mouse_mode (MouseMode m, bool force)
show the object (region) selection.
*/
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
(*i)->set_should_show_selection (true);
}
for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
@@ -320,8 +321,8 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
commit = (c1 || c2);
break;
- case AudioRegionViewNameHighlight:
- case AudioRegionViewName:
+ case RegionViewNameHighlight:
+ case RegionViewName:
c1 = set_selected_track_from_click (press, op, true, true);
c2 = set_selected_regionview_from_click (press, op, true);
commit = (c1 || c2);
@@ -522,12 +523,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
}
break;
- case AudioRegionViewNameHighlight:
+ case RegionViewNameHighlight:
start_trim (item, event);
return true;
break;
- case AudioRegionViewName:
+ case RegionViewName:
/* rename happens on edit clicks */
start_trim (clicked_regionview->get_name_highlight(), event);
return true;
@@ -693,12 +694,12 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
switch (item_type) {
- case AudioRegionViewNameHighlight:
+ case RegionViewNameHighlight:
start_trim (item, event);
return true;
break;
- case AudioRegionViewName:
+ case RegionViewName:
start_trim (clicked_regionview->get_name_highlight(), event);
return true;
break;
@@ -854,7 +855,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
edit_meter_marker (item);
break;
- case AudioRegionViewName:
+ case RegionViewName:
if (clicked_regionview->name_active()) {
return mouse_rename_region (item, event);
}
@@ -889,8 +890,8 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
break;
case RegionItem:
- case AudioRegionViewNameHighlight:
- case AudioRegionViewName:
+ case RegionViewNameHighlight:
+ case RegionViewName:
popup_track_context_menu (1, event->button.time, item_type, false, where);
break;
@@ -1048,9 +1049,13 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
break;
case MouseGain:
+ // Gain only makes sense for audio regions
+ if ( ! dynamic_cast<AudioRegionView*>(clicked_regionview))
+ break;
+
switch (item_type) {
case RegionItem:
- clicked_regionview->add_gain_point_event (item, event);
+ dynamic_cast<AudioRegionView*>(clicked_regionview)->add_gain_point_event (item, event);
return true;
break;
@@ -1204,7 +1209,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
}
break;
- case AudioRegionViewNameHighlight:
+ case RegionViewNameHighlight:
if (is_drawable() && mouse_mode == MouseObject) {
track_canvas.get_window()->set_cursor (*trimmer_cursor);
}
@@ -1231,11 +1236,11 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
}
break;
- case AudioRegionViewName:
+ case RegionViewName:
/* when the name is not an active item, the entire name highlight is for trimming */
- if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) {
+ if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
if (mouse_mode == MouseObject && is_drawable()) {
track_canvas.get_window()->set_cursor (*trimmer_cursor);
}
@@ -1340,7 +1345,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
ControlPoint* cp;
Marker *marker;
Location *loc;
- AudioRegionView* rv;
+ RegionView* rv;
bool is_start;
switch (item_type) {
@@ -1362,7 +1367,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
hide_verbose_canvas_cursor ();
break;
- case AudioRegionViewNameHighlight:
+ case RegionViewNameHighlight:
case StartSelectionTrimItem:
case EndSelectionTrimItem:
case EditCursorItem:
@@ -1393,9 +1398,9 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
}
break;
- case AudioRegionViewName:
+ case RegionViewName:
/* see enter_handler() for notes */
- if (!reinterpret_cast<AudioRegionView *> (item->get_data ("regionview"))->name_active()) {
+ if (!reinterpret_cast<RegionView *> (item->get_data ("regionview"))->name_active()) {
if (is_drawable() && mouse_mode == MouseObject) {
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
}
@@ -1430,7 +1435,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
case FadeInHandleItem:
case FadeOutHandleItem:
- rv = static_cast<AudioRegionView*>(item->get_data ("regionview"));
+ rv = static_cast<RegionView*>(item->get_data ("regionview"));
{
ArdourCanvas::SimpleRect *rect = dynamic_cast<ArdourCanvas::SimpleRect *> (item);
if (rect) {
@@ -1525,7 +1530,7 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
case PanAutomationControlPointItem:
case TempoMarkerItem:
case MeterMarkerItem:
- case AudioRegionViewNameHighlight:
+ case RegionViewNameHighlight:
case StartSelectionTrimItem:
case EndSelectionTrimItem:
case SelectionItem:
@@ -1746,7 +1751,7 @@ Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event)
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->region.fade_in().back()->when + arv->region.position());
+ drag_info.pointer_frame_offset = drag_info.grab_frame - ((jack_nframes_t) arv->audio_region().fade_in().back()->when + arv->region().position());
}
void
@@ -1767,17 +1772,17 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
snap_to (pos);
}
- if (pos < (arv->region.position() + 64)) {
+ if (pos < (arv->region().position() + 64)) {
fade_length = 64; // this should be a minimum defined somewhere
- } else if (pos > arv->region.last_frame()) {
- fade_length = arv->region.length();
+ } else if (pos > arv->region().last_frame()) {
+ fade_length = arv->region().length();
} else {
- fade_length = pos - arv->region.position();
+ fade_length = pos - arv->region().position();
}
arv->reset_fade_in_shape_width (fade_length);
- show_verbose_duration_cursor (arv->region.position(), arv->region.position() + fade_length, 10);
+ show_verbose_duration_cursor (arv->region().position(), arv->region().position() + fade_length, 10);
drag_info.first_move = false;
}
@@ -1802,23 +1807,23 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even
snap_to (pos);
}
- if (pos < (arv->region.position() + 64)) {
+ if (pos < (arv->region().position() + 64)) {
fade_length = 64; // this should be a minimum defined somewhere
}
- else if (pos > arv->region.last_frame()) {
- fade_length = arv->region.length();
+ else if (pos > arv->region().last_frame()) {
+ fade_length = arv->region().length();
}
else {
- fade_length = pos - arv->region.position();
+ fade_length = pos - arv->region().position();
}
begin_reversible_command (_("change fade in length"));
- XMLNode &before = arv->region.get_state();
+ XMLNode &before = arv->audio_region().get_state();
- arv->region.set_fade_in_length (fade_length);
+ arv->audio_region().set_fade_in_length (fade_length);
- XMLNode &after = arv->region.get_state();
- session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region,
+ XMLNode &after = arv->audio_region().get_state();
+ session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->audio_regio(),
before,
after));
commit_reversible_command ();
@@ -1841,7 +1846,7 @@ Editor::start_fade_out_grab (ArdourCanvas::Item* item, GdkEvent* event)
AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
- drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region.length() - (jack_nframes_t) arv->region.fade_out().back()->when + arv->region.position());
+ drag_info.pointer_frame_offset = drag_info.grab_frame - (arv->region().length() - (jack_nframes_t) arv->audio_region().fade_out().back()->when + arv->region().position());
}
void
@@ -1862,19 +1867,19 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event
snap_to (pos);
}
- if (pos > (arv->region.last_frame() - 64)) {
+ if (pos > (arv->region().last_frame() - 64)) {
fade_length = 64; // this should really be a minimum fade defined somewhere
}
- else if (pos < arv->region.position()) {
- fade_length = arv->region.length();
+ else if (pos < arv->region().position()) {
+ fade_length = arv->region().length();
}
else {
- fade_length = arv->region.last_frame() - pos;
+ fade_length = arv->region().last_frame() - pos;
}
arv->reset_fade_out_shape_width (fade_length);
- show_verbose_duration_cursor (arv->region.last_frame() - fade_length, arv->region.last_frame(), 10);
+ show_verbose_duration_cursor (arv->region().last_frame() - fade_length, arv->region().last_frame(), 10);
drag_info.first_move = false;
}
@@ -1899,23 +1904,23 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
snap_to (pos);
}
- if (pos > (arv->region.last_frame() - 64)) {
+ if (pos > (arv->region().last_frame() - 64)) {
fade_length = 64; // this should really be a minimum fade defined somewhere
}
- else if (pos < arv->region.position()) {
- fade_length = arv->region.length();
+ else if (pos < arv->region().position()) {
+ fade_length = arv->region().length();
}
else {
- fade_length = arv->region.last_frame() - pos;
+ fade_length = arv->region().last_frame() - pos;
}
begin_reversible_command (_("change fade out length"));
- XMLNode &before = arv->region.get_state();
+ XMLNode &before = arv->region().get_state();
- arv->region.set_fade_out_length (fade_length);
+ arv->audio_region().set_fade_out_length (fade_length);
- XMLNode &after = arv->region.get_state();
- session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region, before, after));
+ XMLNode &after = arv->region().get_state();
+ session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->region(), before, after));
commit_reversible_command ();
fade_out_drag_motion_callback (item, event);
@@ -2038,7 +2043,7 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
drag_info.copied_location = new Location (*location);
drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end());
-
+
update_marker_drag_item (location);
if (location->is_mark()) {
@@ -2097,31 +2102,39 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
move_both = true;
}
- if (is_start) { // start marker
+ if (copy_location->is_mark()) {
+ /* just move it */
- if (move_both) {
- copy_location->set_start (newframe);
- copy_location->set_end (newframe + f_delta);
- } else if (newframe < copy_location->end()) {
- copy_location->set_start (newframe);
- } else {
- snap_to (next, 1, true);
- copy_location->set_end (next);
- copy_location->set_start (newframe);
- }
+ copy_location->set_start (newframe);
- } else { // end marker
+ } else {
- if (move_both) {
- copy_location->set_end (newframe);
- copy_location->set_start (newframe - f_delta);
- } else if (newframe > copy_location->start()) {
- copy_location->set_end (newframe);
+ if (is_start) { // start-of-range marker
- } else if (newframe > 0) {
- snap_to (next, -1, true);
- copy_location->set_start (next);
- copy_location->set_end (newframe);
+ if (move_both) {
+ copy_location->set_start (newframe);
+ copy_location->set_end (newframe + f_delta);
+ } else if (newframe < copy_location->end()) {
+ copy_location->set_start (newframe);
+ } else {
+ snap_to (next, 1, true);
+ copy_location->set_end (next);
+ copy_location->set_start (newframe);
+ }
+
+ } else { // end marker
+
+ if (move_both) {
+ copy_location->set_end (newframe);
+ copy_location->set_start (newframe - f_delta);
+ } else if (newframe > copy_location->start()) {
+ copy_location->set_end (newframe);
+
+ } else if (newframe > 0) {
+ snap_to (next, -1, true);
+ copy_location->set_start (next);
+ copy_location->set_end (newframe);
+ }
}
}
@@ -2154,7 +2167,11 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
Location * location = find_location_from_marker (marker, is_start);
if (location) {
- location->set (drag_info.copied_location->start(), drag_info.copied_location->end());
+ if (location->is_mark()) {
+ location->set_start (drag_info.copied_location->start());
+ } else {
+ location->set (drag_info.copied_location->start(), drag_info.copied_location->end());
+ }
}
XMLNode &after = session->locations()->get_state();
@@ -2553,7 +2570,8 @@ Editor::start_line_grab_from_regionview (ArdourCanvas::Item* item, GdkEvent* eve
{
switch (mouse_mode) {
case MouseGain:
- start_line_grab (clicked_regionview->get_gain_line(), event);
+ assert(dynamic_cast<AudioRegionView*>(clicked_regionview));
+ start_line_grab (dynamic_cast<AudioRegionView*>(clicked_regionview)->get_gain_line(), event);
break;
default:
break;
@@ -2647,7 +2665,7 @@ Editor::line_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
- if (selection->audio_regions.empty() || clicked_regionview == 0) {
+ if (selection->regions.empty() || clicked_regionview == 0) {
return;
}
@@ -2661,13 +2679,13 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
double speed = 1.0;
TimeAxisView* tvp = clicked_trackview;
- AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
+ RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
if (tv && tv->is_audio_track()) {
speed = tv->get_diskstream()->speed();
}
- drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
+ drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
// we want a move threshold
@@ -2681,7 +2699,7 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
- if (selection->audio_regions.empty() || clicked_regionview == 0) {
+ if (selection->regions.empty() || clicked_regionview == 0) {
return;
}
@@ -2692,7 +2710,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
start_grab(event);
TimeAxisView* tv = &clicked_regionview->get_time_axis_view();
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(tv);
+ RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(tv);
double speed = 1.0;
if (atv && atv->is_audio_track()) {
@@ -2700,7 +2718,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
}
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
- drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
+ drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
// we want a move threshold
drag_info.want_move_threshold = true;
@@ -2711,7 +2729,7 @@ Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event)
{
- if (selection->audio_regions.empty() || clicked_regionview == 0) {
+ if (selection->regions.empty() || clicked_regionview == 0) {
return;
}
@@ -2725,13 +2743,13 @@ Editor::start_region_brush_grab (ArdourCanvas::Item* item, GdkEvent* event)
double speed = 1.0;
TimeAxisView* tvp = clicked_trackview;
- AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
+ RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
if (tv && tv->is_audio_track()) {
speed = tv->get_diskstream()->speed();
}
- drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region.position() / speed);
+ drag_info.last_frame_position = (jack_nframes_t) (clicked_regionview->region().position() / speed);
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
drag_info.last_trackview = &clicked_regionview->get_time_axis_view();
// we want a move threshold
@@ -2746,7 +2764,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
double x_delta;
double y_delta = 0;
- AudioRegionView *rv = reinterpret_cast<AudioRegionView*> (drag_info.data);
+ RegionView* rv = reinterpret_cast<RegionView*> (drag_info.data);
jack_nframes_t pending_region_position = 0;
int32_t pointer_y_span = 0, canvas_pointer_y_span = 0, original_pointer_order;
int32_t visible_y_high = 0, visible_y_low = 512; //high meaning higher numbered.. not the height on the screen
@@ -2766,18 +2784,18 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
/* duplicate the region(s) */
- vector<AudioRegionView*> new_regionviews;
+ vector<RegionView*> new_regionviews;
set<Playlist*> affected_playlists;
pair<set<Playlist*>::iterator,bool> insert_result;
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
- AudioRegionView* rv;
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+ RegionView* rv;
rv = (*i);
- Playlist* to_playlist = rv->region.playlist();
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
+ Playlist* to_playlist = rv->region().playlist();
+ RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&rv->get_time_axis_view());
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
@@ -2786,18 +2804,21 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
latest_regionview = 0;
- sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
-
- /* create a new region with the same name.
- */
+ sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
- AudioRegion* newregion = new AudioRegion (rv->region);
+ /* create a new region with the same name. */
+ // FIXME: ew. need a (virtual) Region::duplicate() or something?
+ Region* newregion = NULL;
+ if (dynamic_cast<AudioRegion*>(&rv->region()))
+ newregion = new AudioRegion (dynamic_cast<AudioRegion&>(rv->region()));
+ assert(newregion);
+
/* if the original region was locked, we don't care */
newregion->set_locked (false);
- to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region.position() * atv->get_diskstream()->speed()));
+ to_playlist->add_region (*newregion, (jack_nframes_t) (rv->region().position() * atv->get_diskstream()->speed()));
c.disconnect ();
@@ -2909,16 +2930,15 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
}
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
- AudioRegionView* rv2;
- rv2 = (*i);
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+ RegionView* rv2 = (*i);
double ix1, ix2, iy1, iy2;
int32_t n = 0;
rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
rv2->get_canvas_group()->i2w (ix1, iy1);
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
- AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
+ RouteTimeAxisView* atv2 = dynamic_cast<RouteTimeAxisView*>(tvp2);
if (atv2->order != original_pointer_order) {
/* this isn't the pointer track */
@@ -3013,8 +3033,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
pending_region_position = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
- sync_offset = rv->region.sync_offset (sync_dir);
- sync_frame = rv->region.adjust_to_sync (pending_region_position);
+ sync_offset = rv->region().sync_offset (sync_dir);
+ sync_frame = rv->region().adjust_to_sync (pending_region_position);
/* we snap if the snap modifier is not enabled.
*/
@@ -3033,7 +3053,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
pending_region_position = 0;
}
- if (pending_region_position > max_frames - rv->region.length()) {
+ if (pending_region_position > max_frames - rv->region().length()) {
pending_region_position = drag_info.last_frame_position;
}
@@ -3075,14 +3095,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
if (x_delta < 0) {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
- AudioRegionView* rv2;
- rv2 = (*i);
+ RegionView* rv2 = (*i);
- /* if any regionview is at zero, we need to know so we can
- stop further leftward motion.
- */
+ // If any regionview is at zero, we need to know so we can stop further leftward motion.
double ix1, ix2, iy1, iy2;
rv2->get_canvas_frame()->get_bounds (ix1, iy1, ix2, iy2);
@@ -3100,12 +3117,11 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
************************************************************/
pair<set<Playlist*>::iterator,bool> insert_result;
- const list<AudioRegionView*>& layered_regions = selection->audio_regions.by_layer();
+ const list<RegionView*>& layered_regions = selection->regions.by_layer();
- for (list<AudioRegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
+ for (list<RegionView*>::const_iterator i = layered_regions.begin(); i != layered_regions.end(); ++i) {
- AudioRegionView* rv;
- rv = (*i);
+ RegionView* rv = (*i);
double ix1, ix2, iy1, iy2;
int32_t temp_pointer_y_span = pointer_y_span;
@@ -3186,8 +3202,8 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
if (-x_delta > ix1) {
x_delta = -ix1;
}
- } else if ((x_delta > 0) &&(rv->region.last_frame() > max_frames - x_delta)) {
- x_delta = max_frames - rv->region.last_frame();
+ } else if ((x_delta > 0) &&(rv->region().last_frame() > max_frames - x_delta)) {
+ x_delta = max_frames - rv->region().last_frame();
}
if (drag_info.first_move) {
@@ -3212,7 +3228,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&rv->get_time_axis_view());
if (atv && atv->is_audio_track()) {
- AudioPlaylist* pl = atv->get_diskstream()->playlist();
+ AudioPlaylist* pl = dynamic_cast<AudioPlaylist*>(atv->get_diskstream()->playlist());
if (pl) {
/* only freeze and capture state once */
@@ -3248,11 +3264,11 @@ void
Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
jack_nframes_t where;
- AudioRegionView* rv = reinterpret_cast<AudioRegionView *> (drag_info.data);
+ RegionView* rv = reinterpret_cast<RegionView *> (drag_info.data);
pair<set<Playlist*>::iterator,bool> insert_result;
bool nocommit = true;
double speed;
- AudioTimeAxisView* atv;
+ RouteTimeAxisView* atv;
bool regionview_y_movement;
bool regionview_x_movement;
@@ -3286,7 +3302,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
speed = atv->get_diskstream()->speed();
}
- regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region.position()/speed));
+ regionview_x_movement = (drag_info.last_frame_position != (jack_nframes_t) (rv->region().position()/speed));
regionview_y_movement = (drag_info.last_trackview != &rv->get_time_axis_view());
//printf ("last_frame: %s position is %lu %g\n", rv->get_time_axis_view().name().c_str(), drag_info.last_frame_position, speed);
@@ -3296,13 +3312,13 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* motion between tracks */
- list<AudioRegionView*> new_selection;
+ list<RegionView*> new_selection;
/* moved to a different audio track. */
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ) {
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ) {
- AudioRegionView* rv2 = (*i);
+ RegionView* rv2 = (*i);
/* the region that used to be in the old playlist is not
moved to the new one - we make a copy of it. as a result,
@@ -3319,7 +3335,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* first, freeze the target tracks */
- for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
+ for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
Playlist* from_playlist;
Playlist* to_playlist;
@@ -3331,7 +3347,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
- from_playlist = (*i)->region.playlist();
+ from_playlist = (*i)->region().playlist();
to_playlist = atv2->playlist();
/* the from_playlist was frozen in the "first_move" case
@@ -3354,7 +3370,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* now do it again with the actual operations */
- for (list<AudioRegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
+ for (list<RegionView*>::const_iterator i = new_selection.begin(); i != new_selection.end();i++ ) {
Playlist* from_playlist;
Playlist* to_playlist;
@@ -3366,17 +3382,17 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
TimeAxisView* tvp2 = trackview_by_y_position (iy1);
AudioTimeAxisView* atv2 = dynamic_cast<AudioTimeAxisView*>(tvp2);
- from_playlist = (*i)->region.playlist();
+ from_playlist = (*i)->region().playlist();
to_playlist = atv2->playlist();
latest_regionview = 0;
where = (jack_nframes_t) (unit_to_frame (ix1) * speed);
- Region* new_region = createRegion ((*i)->region);
+ Region* new_region = createRegion ((*i)->region());
- from_playlist->remove_region (&((*i)->region));
+ from_playlist->remove_region (&((*i)->region()));
- sigc::connection c = atv2->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
+ sigc::connection c = atv2->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
to_playlist->add_region (*new_region, where);
c.disconnect ();
@@ -3389,11 +3405,11 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
/* motion within a single track */
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
rv = (*i);
- if (rv->region.locked()) {
+ if (rv->region().locked()) {
continue;
}
@@ -3415,14 +3431,14 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
} else {
- where = rv->region.position();
+ where = rv->region().position();
}
rv->get_time_axis_view().reveal_dependent_views (*rv);
/* no need to add an undo here, we did that when we added this playlist to motion_frozen playlists */
- rv->region.set_position (where, (void *) this);
+ rv->region().set_position (where, (void *) this);
}
}
@@ -3456,15 +3472,15 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event)
if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
- align_region (rv.region, SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed));
+ align_region (rv.region(), SyncPoint, (jack_nframes_t) (edit_cursor->current_frame * speed));
} else if (Keyboard::modifier_state_equals (event->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
- align_region (rv.region, End, (jack_nframes_t) (edit_cursor->current_frame * speed));
+ align_region (rv.region(), End, (jack_nframes_t) (edit_cursor->current_frame * speed));
} else {
- align_region (rv.region, Start, (jack_nframes_t) (edit_cursor->current_frame * speed));
+ align_region (rv.region(), Start, (jack_nframes_t) (edit_cursor->current_frame * speed));
}
}
}
@@ -3581,7 +3597,7 @@ Editor::show_verbose_duration_cursor (jack_nframes_t start, jack_nframes_t end,
}
void
-Editor::collect_new_region_view (AudioRegionView* rv)
+Editor::collect_new_region_view (RegionView* rv)
{
latest_regionview = rv;
}
@@ -3614,7 +3630,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
*/
latest_regionview = 0;
- sigc::connection c = clicked_audio_trackview->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
+ sigc::connection c = clicked_audio_trackview->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
/* A selection grab currently creates two undo/redo operations, one for
creating the new region and another for moving it.
@@ -3650,7 +3666,7 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
start_grab (event);
drag_info.last_trackview = clicked_trackview;
- drag_info.last_frame_position = latest_regionview->region.position();
+ drag_info.last_frame_position = latest_regionview->region().position();
drag_info.pointer_frame_offset = drag_info.grab_frame - drag_info.last_frame_position;
show_verbose_time_cursor (drag_info.last_frame_position, 10);
@@ -3891,9 +3907,9 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event)
speed = tv->get_diskstream()->speed();
}
- jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region.position() / speed);
- jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region.last_frame() / speed);
- jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region.length() / speed);
+ jack_nframes_t region_start = (jack_nframes_t) (clicked_regionview->region().position() / speed);
+ jack_nframes_t region_end = (jack_nframes_t) (clicked_regionview->region().last_frame() / speed);
+ jack_nframes_t region_length = (jack_nframes_t) (clicked_regionview->region().length() / speed);
motion_frozen_playlists.clear();
@@ -3933,7 +3949,7 @@ Editor::start_trim (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
{
- AudioRegionView* rv = clicked_regionview;
+ RegionView* rv = clicked_regionview;
jack_nframes_t frame_delta = 0;
bool left_direction;
bool obey_snap = !Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier());
@@ -3945,7 +3961,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
double speed = 1.0;
TimeAxisView* tvp = clicked_trackview;
- AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
+ RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
pair<set<Playlist*>::iterator,bool> insert_result;
if (tv && tv->is_audio_track()) {
@@ -3984,11 +4000,14 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
begin_reversible_command (trim_type);
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
- (*i)->region.freeze ();
- (*i)->temporarily_hide_envelope ();
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
+ (*i)->region().freeze ();
+
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->temporarily_hide_envelope ();
- Playlist * pl = (*i)->region.playlist();
+ Playlist * pl = (*i)->region().playlist();
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
@@ -4004,20 +4023,20 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
switch (trim_op) {
case StartTrim:
- if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region.first_frame()/speed)) {
+ if ((left_direction == false) && (drag_info.current_pointer_frame <= rv->region().first_frame()/speed)) {
break;
} else {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
single_start_trim (**i, frame_delta, left_direction, obey_snap);
}
break;
}
case EndTrim:
- if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region.last_frame()/speed))) {
+ if ((left_direction == true) && (drag_info.current_pointer_frame > (jack_nframes_t) (rv->region().last_frame()/speed))) {
break;
} else {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i) {
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i) {
single_end_trim (**i, frame_delta, left_direction, obey_snap);
}
break;
@@ -4031,8 +4050,8 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
swap_direction = true;
}
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
- i != selection->audio_regions.by_layer().end(); ++i)
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
+ i != selection->regions.by_layer().end(); ++i)
{
single_contents_trim (**i, frame_delta, left_direction, swap_direction, obey_snap);
}
@@ -4042,10 +4061,10 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
switch (trim_op) {
case StartTrim:
- show_verbose_time_cursor((jack_nframes_t) (rv->region.position()/speed), 10);
+ show_verbose_time_cursor((jack_nframes_t) (rv->region().position()/speed), 10);
break;
case EndTrim:
- show_verbose_time_cursor((jack_nframes_t) (rv->region.last_frame()/speed), 10);
+ show_verbose_time_cursor((jack_nframes_t) (rv->region().last_frame()/speed), 10);
break;
case ContentsTrim:
show_verbose_time_cursor(drag_info.current_pointer_frame, 10);
@@ -4057,9 +4076,9 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
}
void
-Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
+Editor::single_contents_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool swap_direction, bool obey_snap)
{
- Region& region (rv.region);
+ Region& region (rv.region());
if (region.locked()) {
return;
@@ -4069,7 +4088,7 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b
double speed = 1.0;
TimeAxisView* tvp = clicked_trackview;
- AudioTimeAxisView* tv = dynamic_cast<AudioTimeAxisView*>(tvp);
+ RouteTimeAxisView* tv = dynamic_cast<RouteTimeAxisView*>(tvp);
if (tv && tv->is_audio_track()) {
speed = tv->get_diskstream()->speed();
@@ -4097,9 +4116,9 @@ Editor::single_contents_trim (AudioRegionView& rv, jack_nframes_t frame_delta, b
}
void
-Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_start_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
{
- Region& region (rv.region);
+ Region& region (rv.region());
if (region.locked()) {
return;
@@ -4131,9 +4150,9 @@ Editor::single_start_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool
}
void
-Editor::single_end_trim (AudioRegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
+Editor::single_end_trim (RegionView& rv, jack_nframes_t frame_delta, bool left_direction, bool obey_snap)
{
- Region& region (rv.region);
+ Region& region (rv.region());
if (region.locked()) {
return;
@@ -4172,8 +4191,8 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
thaw_region_after_trim (*clicked_regionview);
} else {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
- i != selection->audio_regions.by_layer().end(); ++i)
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
+ i != selection->regions.by_layer().end(); ++i)
{
thaw_region_after_trim (**i);
}
@@ -4196,7 +4215,7 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::point_trim (GdkEvent* event)
{
- AudioRegionView* rv = clicked_regionview;
+ RegionView* rv = clicked_regionview;
jack_nframes_t new_bound = drag_info.current_pointer_frame;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
@@ -4211,13 +4230,13 @@ Editor::point_trim (GdkEvent* event)
if (rv->get_selected()) {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin();
- i != selection->audio_regions.by_layer().end(); ++i)
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin();
+ i != selection->regions.by_layer().end(); ++i)
{
- if (!(*i)->region.locked()) {
+ if (!(*i)->region().locked()) {
Playlist *pl = (*i)->region.playlist();
XMLNode &before = pl->get_state();
- (*i)->region.trim_front (new_bound, this);
+ (*i)->region().trim_front (new_bound, this);
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
@@ -4225,10 +4244,10 @@ Editor::point_trim (GdkEvent* event)
} else {
- if (!rv->region.locked()) {
- Playlist *pl = rv->region.playlist();
+ if (!rv->region().locked()) {
+ Playlist *pl = rv->region().playlist();
XMLNode &before = pl->get_state();
- rv->region.trim_front (new_bound, this);
+ rv->region().trim_front (new_bound, this);
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
@@ -4243,12 +4262,12 @@ Editor::point_trim (GdkEvent* event)
if (rv->get_selected()) {
- for (list<AudioRegionView*>::const_iterator i = selection->audio_regions.by_layer().begin(); i != selection->audio_regions.by_layer().end(); ++i)
+ for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
{
- if (!(*i)->region.locked()) {
- Playlist *pl = (*i)->region.playlist();
+ if (!(*i)->region().locked()) {
+ Playlist *pl = (*i)->region().playlist();
XMLNode &before = pl->get_state();
- (*i)->region.trim_end (new_bound, this);
+ (*i)->region().trim_end (new_bound, this);
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
@@ -4256,10 +4275,10 @@ Editor::point_trim (GdkEvent* event)
} else {
- if (!rv->region.locked()) {
- Playlist *pl = rv->region.playlist();
+ if (!rv->region().locked()) {
+ Playlist *pl = rv->region().playlist();
XMLNode &before = pl->get_state();
- rv->region.trim_end (new_bound, this);
+ rv->region().trim_end (new_bound, this);
XMLNode &after = pl->get_state();
session->add_command (new MementoCommand<Playlist>(*pl, before, after));
}
@@ -4274,9 +4293,9 @@ Editor::point_trim (GdkEvent* event)
}
void
-Editor::thaw_region_after_trim (AudioRegionView& rv)
+Editor::thaw_region_after_trim (RegionView& rv)
{
- Region& region (rv.region);
+ Region& region (rv.region());
if (region.locked()) {
return;
@@ -4286,7 +4305,9 @@ Editor::thaw_region_after_trim (AudioRegionView& rv)
XMLNode &after = region.playlist()->get_state();
session->add_command (new MementoRedoCommand<Playlist>(*(region.playlist()), after));
- rv.unhide_envelope ();
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
+ if (arv)
+ arv->unhide_envelope ();
}
void
@@ -4679,7 +4700,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
}
} else {
- selection->clear_audio_regions();
+ selection->clear_regions();
selection->clear_points ();
selection->clear_lines ();
}
@@ -4696,7 +4717,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event)
ArdourPrompter prompter (false);
prompter.set_prompt (_("Name for region:"));
- prompter.set_initial_text (clicked_regionview->region.name());
+ prompter.set_initial_text (clicked_regionview->region().name());
prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
prompter.show_all ();
@@ -4705,7 +4726,7 @@ Editor::mouse_rename_region (ArdourCanvas::Item* item, GdkEvent* event)
string str;
prompter.get_result(str);
if (str.length()) {
- clicked_regionview->region.set_name (str);
+ clicked_regionview->region().set_name (str);
}
break;
}
@@ -4727,7 +4748,7 @@ Editor::start_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
void
Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event)
{
- AudioRegionView* rv = clicked_regionview;
+ RegionView* rv = clicked_regionview;
if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
snap_to (drag_info.current_pointer_frame);
@@ -4737,8 +4758,8 @@ Editor::time_fx_motion (ArdourCanvas::Item *item, GdkEvent* event)
return;
}
- if (drag_info.current_pointer_frame > rv->region.position()) {
- rv->get_time_axis_view().show_timestretch (rv->region.position(), drag_info.current_pointer_frame);
+ if (drag_info.current_pointer_frame > rv->region().position()) {
+ rv->get_time_axis_view().show_timestretch (rv->region().position(), drag_info.current_pointer_frame);
}
drag_info.last_pointer_frame = drag_info.current_pointer_frame;
@@ -4756,21 +4777,25 @@ Editor::end_time_fx (ArdourCanvas::Item* item, GdkEvent* event)
return;
}
- jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region.position();
- float percentage = (float) ((double) newlen - (double) clicked_regionview->region.length()) / ((double) newlen) * 100.0f;
+ jack_nframes_t newlen = drag_info.last_pointer_frame - clicked_regionview->region().position();
+ float percentage = (float) ((double) newlen - (double) clicked_regionview->region().length()) / ((double) newlen) * 100.0f;
begin_reversible_command (_("timestretch"));
- if (run_timestretch (selection->audio_regions, percentage) == 0) {
+ if (run_timestretch (selection->regions, percentage) == 0) {
session->commit_reversible_command ();
}
}
void
-Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
+Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos)
{
/* no brushing without a useful snap setting */
+ // FIXME
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(rv);
+ assert(arv);
+
switch (snap_mode) {
case SnapMagnetic:
return; /* can't work because it allows region to be placed anywhere */
@@ -4790,11 +4815,11 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
/* don't brush a copy over the original */
- if (pos == rv->region.position()) {
+ if (pos == rv->region().position()) {
return;
}
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(&rv->get_time_axis_view());
+ RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(&arv->get_time_axis_view());
if (atv == 0 || !atv->is_audio_track()) {
return;
@@ -4804,7 +4829,7 @@ Editor::mouse_brush_insert_region (AudioRegionView* rv, jack_nframes_t pos)
double speed = atv->get_diskstream()->speed();
XMLNode &before = playlist->get_state();
- playlist->add_region (*(new AudioRegion (rv->region)), (jack_nframes_t) (pos * speed));
+ playlist->add_region (*(new AudioRegion (arv->audio_region)), (jack_nframes_t) (pos * speed));
XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index e9fcc028e6..d98be4f088 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -52,7 +52,7 @@
#include "audio_time_axis.h"
#include "automation_time_axis.h"
#include "streamview.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "rgb_macros.h"
#include "selection_templates.h"
#include "selection.h"
@@ -187,29 +187,31 @@ Editor::split_region ()
void
Editor::split_region_at (jack_nframes_t where)
{
- split_regions_at (where, selection->audio_regions);
+ split_regions_at (where, selection->regions);
}
void
-Editor::split_regions_at (jack_nframes_t where, AudioRegionSelection& regions)
+Editor::split_regions_at (jack_nframes_t where, RegionSelection& regions)
{
begin_reversible_command (_("split"));
snap_to (where);
- for (AudioRegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
+ for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
- AudioRegionSelection::iterator tmp;
+ RegionSelection::iterator tmp;
tmp = a;
++tmp;
- Playlist* pl = (*a)->region.playlist();
+ Playlist* pl = (*a)->region().playlist();
- _new_regionviews_show_envelope = (*a)->envelope_visible();
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
+ if (arv)
+ _new_regionviews_show_envelope = arv->envelope_visible();
if (pl) {
XMLNode &before = pl->get_state();
- pl->split_region ((*a)->region, where);
+ pl->split_region ((*a)->region(), where);
XMLNode &after = pl->get_state();
session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
@@ -232,7 +234,7 @@ Editor::remove_clicked_region ()
begin_reversible_command (_("remove region"));
XMLNode &before = playlist->get_state();
- playlist->remove_region (&clicked_regionview->region);
+ playlist->remove_region (&clicked_regionview->region());
XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
commit_reversible_command ();
@@ -241,7 +243,7 @@ Editor::remove_clicked_region ()
void
Editor::destroy_clicked_region ()
{
- int32_t selected = selection->audio_regions.size();
+ int32_t selected = selection->regions.size();
if (!session || clicked_regionview == 0 && selected == 0) {
return;
@@ -273,29 +275,29 @@ Do you really want to destroy %1 ?"),
if (selected > 0) {
list<Region*> r;
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- r.push_back (&(*i)->region);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ r.push_back (&(*i)->region());
}
session->destroy_regions (r);
} else if (clicked_regionview) {
- session->destroy_region (&clicked_regionview->region);
+ session->destroy_region (&clicked_regionview->region());
}
}
-AudioRegion *
+Region *
Editor::select_region_for_operation (int dir, TimeAxisView **tv)
{
- AudioRegionView* rv;
- AudioRegion *region;
+ RegionView* rv;
+ Region *region;
jack_nframes_t start = 0;
if (selection->time.start () == selection->time.end_frame ()) {
/* no current selection-> is there a selected regionview? */
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return 0;
}
@@ -303,26 +305,26 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
region = 0;
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
- rv = *(selection->audio_regions.begin());
+ rv = *(selection->regions.begin());
(*tv) = &rv->get_time_axis_view();
- region = &rv->region;
+ region = &rv->region();
} else if (!selection->tracks.empty()) {
(*tv) = selection->tracks.front();
- AudioTimeAxisView* atv;
+ RouteTimeAxisView* rtv;
- if ((atv = dynamic_cast<AudioTimeAxisView*> (*tv)) != 0) {
+ if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
Playlist *pl;
- if ((pl = atv->playlist()) == 0) {
+ if ((pl = rtv->playlist()) == 0) {
return 0;
}
- region = dynamic_cast<AudioRegion*> (pl->top_region_at (start));
+ region = pl->top_region_at (start);
}
}
@@ -394,12 +396,12 @@ Editor::nudge_forward (bool next)
if (!session) return;
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
begin_reversible_command (_("nudge forward"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- AudioRegion& r ((*i)->region);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ Region& r ((*i)->region());
distance = get_nudge_distance (r.position(), next_distance);
@@ -429,12 +431,12 @@ Editor::nudge_backward (bool next)
if (!session) return;
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
begin_reversible_command (_("nudge forward"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- AudioRegion& r ((*i)->region);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ Region& r ((*i)->region());
distance = get_nudge_distance (r.position(), next_distance);
@@ -474,14 +476,14 @@ Editor::nudge_forward_capture_offset ()
if (!session) return;
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
begin_reversible_command (_("nudge forward"));
distance = session->worst_output_latency();
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- AudioRegion& r ((*i)->region);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ Region& r ((*i)->region());
XMLNode &before = r.playlist()->get_state();
r.set_position (r.position() + distance, this);
@@ -501,14 +503,14 @@ Editor::nudge_backward_capture_offset ()
if (!session) return;
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
begin_reversible_command (_("nudge forward"));
distance = session->worst_output_latency();
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- AudioRegion& r ((*i)->region);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ Region& r ((*i)->region());
XMLNode &before = r.playlist()->get_state();
@@ -789,8 +791,8 @@ Editor::cursor_to_selection_start (Cursor *cursor)
jack_nframes_t pos = 0;
switch (mouse_mode) {
case MouseObject:
- if (!selection->audio_regions.empty()) {
- pos = selection->audio_regions.start();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.start();
}
break;
@@ -818,8 +820,8 @@ Editor::cursor_to_selection_end (Cursor *cursor)
switch (mouse_mode) {
case MouseObject:
- if (!selection->audio_regions.empty()) {
- pos = selection->audio_regions.end_frame();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.end_frame();
}
break;
@@ -1319,12 +1321,12 @@ Editor::add_location_from_playhead_cursor ()
void
Editor::add_location_from_audio_region ()
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
- AudioRegionView* rv = *(selection->audio_regions.begin());
- Region& region = rv->region;
+ RegionView* rv = *(selection->regions.begin());
+ Region& region = rv->region();
Location *location = new Location (region.position(), region.last_frame(), region.name());
session->begin_reversible_command (_("add marker"));
@@ -1452,12 +1454,12 @@ Editor::select_all_within (jack_nframes_t start, jack_nframes_t end, double top,
void
Editor::set_selection_from_audio_region ()
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
- AudioRegionView* rv = *(selection->audio_regions.begin());
- Region& region = rv->region;
+ RegionView* rv = *(selection->regions.begin());
+ Region& region = rv->region();
begin_reversible_command (_("set selection from region"));
selection->set (0, region.position(), region.last_frame());
@@ -1840,13 +1842,13 @@ Editor::insert_region_list_drag (AudioRegion& region, int x, int y)
void
Editor::insert_region_list_selection (float times)
{
- AudioTimeAxisView *tv = 0;
+ RouteTimeAxisView *tv = 0;
Playlist *playlist;
if (clicked_audio_trackview != 0) {
tv = clicked_audio_trackview;
} else if (!selection->tracks.empty()) {
- if ((tv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front())) == 0) {
+ if ((tv = dynamic_cast<RouteTimeAxisView*>(selection->tracks.front())) == 0) {
return;
}
} else {
@@ -1941,23 +1943,23 @@ Editor::play_selection ()
void
Editor::play_selected_region ()
{
- if (!selection->audio_regions.empty()) {
- AudioRegionView *rv = *(selection->audio_regions.begin());
+ if (!selection->regions.empty()) {
+ RegionView *rv = *(selection->regions.begin());
- session->request_bounded_roll (rv->region.position(), rv->region.last_frame());
+ session->request_bounded_roll (rv->region().position(), rv->region().last_frame());
}
}
void
Editor::loop_selected_region ()
{
- if (!selection->audio_regions.empty()) {
- AudioRegionView *rv = *(selection->audio_regions.begin());
+ if (!selection->regions.empty()) {
+ RegionView *rv = *(selection->regions.begin());
Location* tll;
if ((tll = transport_loop_location()) != 0) {
- tll->set (rv->region.position(), rv->region.last_frame());
+ tll->set (rv->region().position(), rv->region().last_frame());
// enable looping, reposition and start rolling
@@ -2000,10 +2002,10 @@ void
Editor::toggle_region_mute ()
{
if (clicked_regionview) {
- clicked_regionview->region.set_muted (!clicked_regionview->region.muted());
- } else if (!selection->audio_regions.empty()) {
- bool yn = ! (*selection->audio_regions.begin())->region.muted();
- selection->foreach_audio_region (&AudioRegion::set_muted, yn);
+ clicked_regionview->region().set_muted (!clicked_regionview->region().muted());
+ } else if (!selection->regions.empty()) {
+ bool yn = ! (*selection->regions.begin())->region().muted();
+ selection->foreach_region (&Region::set_muted, yn);
}
}
@@ -2011,35 +2013,35 @@ void
Editor::toggle_region_opaque ()
{
if (clicked_regionview) {
- clicked_regionview->region.set_opaque (!clicked_regionview->region.opaque());
- } else if (!selection->audio_regions.empty()) {
- bool yn = ! (*selection->audio_regions.begin())->region.opaque();
- selection->foreach_audio_region (&Region::set_opaque, yn);
+ clicked_regionview->region().set_opaque (!clicked_regionview->region().opaque());
+ } else if (!selection->regions.empty()) {
+ bool yn = ! (*selection->regions.begin())->region().opaque();
+ selection->foreach_region (&Region::set_opaque, yn);
}
}
void
Editor::raise_region ()
{
- selection->foreach_audio_region (&Region::raise);
+ selection->foreach_region (&Region::raise);
}
void
Editor::raise_region_to_top ()
{
- selection->foreach_audio_region (&Region::raise_to_top);
+ selection->foreach_region (&Region::raise_to_top);
}
void
Editor::lower_region ()
{
- selection->foreach_audio_region (&Region::lower);
+ selection->foreach_region (&Region::lower);
}
void
Editor::lower_region_to_bottom ()
{
- selection->foreach_audio_region (&Region::lower_to_bottom);
+ selection->foreach_region (&Region::lower_to_bottom);
}
void
@@ -2060,7 +2062,7 @@ Editor::rename_region ()
Button ok_button (_("OK"));
Button cancel_button (_("Cancel"));
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
@@ -2091,7 +2093,7 @@ Editor::rename_region ()
Main::run ();
if (region_renamed) {
- (*selection->audio_regions.begin())->region.set_name (entry.get_text());
+ (*selection->regions.begin())->region().set_name (entry.get_text());
redisplay_regions ();
}
}
@@ -2105,7 +2107,7 @@ Editor::rename_region_finished (bool status)
}
void
-Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route)
+Editor::audition_playlist_region_via_route (Region& region, Route& route)
{
if (session->is_auditioning()) {
session->cancel_audition ();
@@ -2126,14 +2128,14 @@ Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route)
void
Editor::audition_selected_region ()
{
- if (!selection->audio_regions.empty()) {
- AudioRegionView* rv = *(selection->audio_regions.begin());
- session->audition_region (rv->region);
+ if (!selection->regions.empty()) {
+ RegionView* rv = *(selection->regions.begin());
+ session->audition_region (rv->region());
}
}
void
-Editor::audition_playlist_region_standalone (AudioRegion& region)
+Editor::audition_playlist_region_standalone (Region& region)
{
session->audition_region (region);
}
@@ -2183,7 +2185,6 @@ Editor::region_from_selection ()
jack_nframes_t selection_cnt = end - start + 1;
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-
AudioRegion *region;
AudioRegion *current;
Region* current_r;
@@ -2200,7 +2201,9 @@ Editor::region_from_selection ()
continue;
}
- if ((current = dynamic_cast<AudioRegion*> (current_r)) != 0) {
+ current = dynamic_cast<AudioRegion*> (current_r);
+ // FIXME: audio only
+ if (current != 0) {
internal_start = start - current->position();
session->region_name (new_name, current->name(), true);
region = new AudioRegion (*current, internal_start, selection_cnt, new_name);
@@ -2250,11 +2253,13 @@ Editor::split_multichannel_region ()
{
vector<AudioRegion*> v;
- if (!clicked_regionview || clicked_regionview->region.n_channels() < 2) {
+ AudioRegionView* clicked_arv = dynamic_cast<AudioRegionView*>(clicked_regionview);
+
+ if (!clicked_arv || clicked_arv->audio_region().n_channels() < 2) {
return;
}
- clicked_regionview->region.separate_by_channel (*session, v);
+ clicked_arv->audio_region().separate_by_channel (*session, v);
/* nothing else to do, really */
}
@@ -2440,7 +2445,7 @@ Editor::region_fill_track ()
{
jack_nframes_t end;
- if (!session || selection->audio_regions.empty()) {
+ if (!session || selection->regions.empty()) {
return;
}
@@ -2448,9 +2453,15 @@ Editor::region_fill_track ()
begin_reversible_command (_("region fill"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+
+ Region& region ((*i)->region());
+
+ // FIXME
+ AudioRegion* const ar = dynamic_cast<AudioRegion*>(&region);
+ if (!ar)
+ continue;
- AudioRegion& region ((*i)->region);
Playlist* pl = region.playlist();
if (end <= region.last_frame()) {
@@ -2464,7 +2475,7 @@ Editor::region_fill_track ()
}
XMLNode &before = pl->get_state();
- pl->add_region (*(new AudioRegion (region)), region.last_frame(), times);
+ pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state()));
}
@@ -2544,12 +2555,12 @@ Editor::set_region_sync_from_edit_cursor ()
return;
}
- if (!clicked_regionview->region.covers (edit_cursor->current_frame)) {
+ if (!clicked_regionview->region().covers (edit_cursor->current_frame)) {
error << _("Place the edit cursor at the desired sync point") << endmsg;
return;
}
- Region& region (clicked_regionview->region);
+ Region& region (clicked_regionview->region());
begin_reversible_command (_("set sync from edit cursor"));
XMLNode &before = region.playlist()->get_state();
region.set_sync_position (edit_cursor->current_frame);
@@ -2562,7 +2573,7 @@ void
Editor::remove_region_sync ()
{
if (clicked_regionview) {
- Region& region (clicked_regionview->region);
+ Region& region (clicked_regionview->region());
begin_reversible_command (_("remove sync"));
XMLNode &before = region.playlist()->get_state();
region.clear_sync_position ();
@@ -2575,15 +2586,15 @@ Editor::remove_region_sync ()
void
Editor::naturalize ()
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
begin_reversible_command (_("naturalize"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- XMLNode &before = (*i)->region.get_state();
- (*i)->region.move_to_natural_position (this);
- XMLNode &after = (*i)->region.get_state();
- session->add_command (new MementoCommand<AudioRegion>((*i)->region, before, after));
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ XMLNode &before = (*i)->region().get_state();
+ (*i)->region().move_to_natural_position (this);
+ XMLNode &after = (*i)->region().get_state();
+ session->add_command (new MementoCommand<AudioRegion>((*i)->region(), before, after));
}
commit_reversible_command ();
}
@@ -2602,14 +2613,14 @@ Editor::align_relative (RegionPoint what)
struct RegionSortByTime {
bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
- return a->region.position() < b->region.position();
+ return a->region().position() < b->region().position();
}
};
void
Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
@@ -2617,9 +2628,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
jack_nframes_t pos = 0;
int dir;
- list<AudioRegionView*> sorted;
- selection->audio_regions.by_position (sorted);
- Region& r ((*sorted.begin())->region);
+ list<RegionView*> sorted;
+ selection->regions.by_position (sorted);
+ Region& r ((*sorted.begin())->region());
switch (point) {
case Start:
@@ -2645,9 +2656,9 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
begin_reversible_command (_("align selection (relative)"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- Region& region ((*i)->region);
+ Region& region ((*i)->region());
XMLNode &before = region.playlist()->get_state();
@@ -2668,14 +2679,14 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
void
Editor::align_selection (RegionPoint point, jack_nframes_t position)
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
begin_reversible_command (_("align selection"));
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- align_region_internal ((*i)->region, point, position);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ align_region_internal ((*i)->region(), point, position);
}
commit_reversible_command ();
@@ -2721,7 +2732,7 @@ Editor::trim_region_to_edit_cursor ()
return;
}
- Region& region (clicked_regionview->region);
+ Region& region (clicked_regionview->region());
float speed = 1.0f;
AudioTimeAxisView *atav;
@@ -2747,7 +2758,7 @@ Editor::trim_region_from_edit_cursor ()
return;
}
- Region& region (clicked_regionview->region);
+ Region& region (clicked_regionview->region());
float speed = 1.0f;
AudioTimeAxisView *atav;
@@ -2920,16 +2931,16 @@ Editor::cut_copy (CutCopyOp op)
switch (current_mouse_mode()) {
case MouseObject:
- if (!selection->audio_regions.empty() || !selection->points.empty()) {
+ if (!selection->regions.empty() || !selection->points.empty()) {
begin_reversible_command (opname + _(" objects"));
- if (!selection->audio_regions.empty()) {
+ if (!selection->regions.empty()) {
cut_copy_regions (op);
if (op == Cut) {
- selection->clear_audio_regions ();
+ selection->clear_regions ();
}
}
@@ -2986,11 +2997,11 @@ Editor::cut_copy_regions (CutCopyOp op)
set<Playlist*> freezelist;
pair<set<Playlist*>::iterator,bool> insert_result;
- for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
- first_position = min ((*x)->region.position(), first_position);
+ for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ first_position = min ((*x)->region().position(), first_position);
if (op == Cut || op == Clear) {
- AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
+ AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist());
if (pl) {
insert_result = freezelist.insert (pl);
if (insert_result.second) {
@@ -3001,11 +3012,11 @@ Editor::cut_copy_regions (CutCopyOp op)
}
}
- for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ) {
+ for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
- AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
+ AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region().playlist());
AudioPlaylist* npl;
- AudioRegionSelection::iterator tmp;
+ RegionSelection::iterator tmp;
tmp = x;
++tmp;
@@ -3022,18 +3033,24 @@ Editor::cut_copy_regions (CutCopyOp op)
npl = pi->second;
}
+ // FIXME
+ AudioRegion* const ar = dynamic_cast<AudioRegion*>(&(*x)->region());
switch (op) {
case Cut:
- npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
- pl->remove_region (&((*x)->region));
+ if (!ar) break;
+
+ npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position);
+ pl->remove_region (&((*x)->region()));
break;
case Copy:
- npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
+ if (!ar) break;
+
+ npl->add_region (*(new AudioRegion (*ar)), (*x)->region().position() - first_position);
break;
case Clear:
- pl->remove_region (&((*x)->region));
+ pl->remove_region (&((*x)->region()));
break;
}
}
@@ -3179,24 +3196,24 @@ Editor::paste_named_selection (float times)
}
void
-Editor::duplicate_some_regions (AudioRegionSelection& regions, float times)
+Editor::duplicate_some_regions (RegionSelection& regions, float times)
{
Playlist *playlist;
- AudioRegionSelection sel = regions; // clear (below) will clear the argument list
+ RegionSelection sel = regions; // clear (below) will clear the argument list
begin_reversible_command (_("duplicate region"));
- selection->clear_audio_regions ();
+ selection->clear_regions ();
- for (AudioRegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
+ for (RegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
- Region& r ((*i)->region);
+ Region& r ((*i)->region());
TimeAxisView& tv = (*i)->get_time_axis_view();
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv);
- sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
+ sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
- playlist = (*i)->region.playlist();
+ playlist = (*i)->region().playlist();
XMLNode &before = playlist->get_state();
playlist->duplicate (r, r.last_frame(), times);
session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
@@ -3369,7 +3386,7 @@ Editor::normalize_region ()
return;
}
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
@@ -3378,11 +3395,13 @@ Editor::normalize_region ()
track_canvas.get_window()->set_cursor (*wait_cursor);
gdk_flush ();
- for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
- XMLNode &before = (*r)->region.get_state();
- (*r)->region.normalize_to (0.0f);
- XMLNode &after = (*r)->region.get_state();
- session->add_command (new MementoCommand<AudioRegion>((*r)->region, before, after));
+ for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
+ if (!arv)
+ continue;
+ XMLNode &before = arv->region().get_state();
+ arv->audio_region().normalize_to (0.0f);
+ session->add_command (new MementoCommand<Region>(arv->region, arv->region().get_state());
}
commit_reversible_command ();
@@ -3397,17 +3416,19 @@ Editor::denormalize_region ()
return;
}
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
begin_reversible_command ("denormalize");
- for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
- XMLNode &before = (*r)->region.get_state();
- (*r)->region.set_scale_amplitude (1.0f);
- XMLNode &after = (*r)->region.get_state();
- session->add_command (new MementoCommand<AudioRegion>((*r)->region, before, after));
+ for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
+ if (!arv)
+ continue;
+ XMLNode &before = arv->region().get_state();
+ arv->audio_region().set_scale_amplitude (1.0f);
+ session->add_command (new MementoCommand<Region>(arv->region, before, arv->region().get_state());
}
commit_reversible_command ();
@@ -3428,7 +3449,7 @@ Editor::reverse_region ()
void
Editor::apply_filter (AudioFilter& filter, string command)
{
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
return;
}
@@ -3437,20 +3458,22 @@ Editor::apply_filter (AudioFilter& filter, string command)
track_canvas.get_window()->set_cursor (*wait_cursor);
gdk_flush ();
- for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ) {
+ for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
+ if (!arv)
+ continue;
- AudioRegion& region ((*r)->region);
- Playlist* playlist = region.playlist();
+ Playlist* playlist = arv->region().playlist();
- AudioRegionSelection::iterator tmp;
+ RegionSelection::iterator tmp;
tmp = r;
++tmp;
- if (region.apply (filter) == 0) {
+ if (arv->audio_region().apply (filter) == 0) {
XMLNode &before = playlist->get_state();
- playlist->replace_region (region, *(filter.results.front()), region.position());
+ playlist->replace_region (arv->region(), *(filter.results.front()), arv->region()position());
XMLNode &after = playlist->get_state();
session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
} else {
@@ -3461,7 +3484,7 @@ Editor::apply_filter (AudioFilter& filter, string command)
}
commit_reversible_command ();
- selection->audio_regions.clear ();
+ selection->regions.clear ();
out:
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
@@ -3470,8 +3493,8 @@ Editor::apply_filter (AudioFilter& filter, string command)
void
Editor::region_selection_op (void (Region::*pmf)(void))
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- ((*i)->region.*pmf)();
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ ((*i)->region().*pmf)();
}
}
@@ -3479,16 +3502,16 @@ Editor::region_selection_op (void (Region::*pmf)(void))
void
Editor::region_selection_op (void (Region::*pmf)(void*), void *arg)
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- ((*i)->region.*pmf)(arg);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ ((*i)->region().*pmf)(arg);
}
}
void
Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- ((*i)->region.*pmf)(yn);
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ ((*i)->region().*pmf)(yn);
}
}
@@ -3505,20 +3528,20 @@ Editor::external_edit_region ()
void
Editor::brush (jack_nframes_t pos)
{
- AudioRegionSelection sel;
+ RegionSelection sel;
snap_to (pos);
- if (selection->audio_regions.empty()) {
+ if (selection->regions.empty()) {
/* XXX get selection from region list */
} else {
- sel = selection->audio_regions;
+ sel = selection->regions;
}
if (sel.empty()) {
return;
}
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
mouse_brush_insert_region ((*i), pos);
}
}
@@ -3526,18 +3549,19 @@ Editor::brush (jack_nframes_t pos)
void
Editor::toggle_gain_envelope_visibility ()
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- (*i)->set_envelope_visible (!(*i)->envelope_visible());
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->set_envelope_visible (!arv->envelope_visible());
}
}
void
Editor::toggle_gain_envelope_active ()
{
- for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
- AudioRegion* ar = dynamic_cast<AudioRegion*>(&(*i)->region);
- if (ar) {
- ar->set_envelope_active (true);
- }
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
+ if (arv)
+ arv->audio_region().set_envelope_active (true);
}
}
diff --git a/gtk2_ardour/editor_route_list.cc b/gtk2_ardour/editor_route_list.cc
index 2e036f5001..c93cf9aba2 100644
--- a/gtk2_ardour/editor_route_list.cc
+++ b/gtk2_ardour/editor_route_list.cc
@@ -39,21 +39,16 @@ using namespace PBD;
using namespace Gtk;
void
-Editor::handle_new_route_p (Route* route)
-{
- ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route_p), route));
- handle_new_route (*route);
-}
-
-void
-Editor::handle_new_route (Route& route)
+Editor::handle_new_route (boost::shared_ptr<Route> route)
{
+ ENSURE_GUI_THREAD(bind (mem_fun(*this, &Editor::handle_new_route), route));
+
TimeAxisView *tv;
AudioTimeAxisView *atv;
TreeModel::Row parent;
TreeModel::Row row;
- if (route.hidden()) {
+ if (route->hidden()) {
return;
}
@@ -75,7 +70,7 @@ Editor::handle_new_route (Route& route)
}
- if (dynamic_cast<AudioTrack*>(&route) != 0) {
+ if (dynamic_cast<AudioTrack*>(route.get()) != 0) {
TreeModel::iterator iter = route_display_model->get_iter ("1"); // audio tracks
parent = *iter;
} else {
@@ -89,7 +84,7 @@ Editor::handle_new_route (Route& route)
row = *(route_display_model->append ());
#endif
- row[route_display_columns.text] = route.name();
+ row[route_display_columns.text] = route->name();
row[route_display_columns.visible] = tv->marked_for_display();
row[route_display_columns.tv] = tv;
@@ -99,14 +94,14 @@ Editor::handle_new_route (Route& route)
if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
/* added a new fresh one at the end */
- if (atv->route().order_key(N_("editor")) == -1) {
- atv->route().set_order_key (N_("editor"), route_display_model->children().size()-1);
+ if (atv->route()->order_key(N_("editor")) == -1) {
+ atv->route()->set_order_key (N_("editor"), route_display_model->children().size()-1);
}
}
ignore_route_list_reorder = false;
- route.gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
+ route->gui_changed.connect (mem_fun(*this, &Editor::handle_gui_changes));
tv->GoingAway.connect (bind (mem_fun(*this, &Editor::remove_route), tv));
@@ -188,7 +183,7 @@ Editor::hide_track_in_display (TimeAxisView& tv)
AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv);
- if (atv && current_mixer_strip && &(atv->route()) == &(current_mixer_strip->route())) {
+ if (atv && current_mixer_strip && (atv->route() == current_mixer_strip->route())) {
// this will hide the mixer strip
set_selected_mixer_strip (tv);
}
@@ -244,7 +239,7 @@ Editor::redisplay_route_list ()
*/
if ((at = dynamic_cast<AudioTimeAxisView*> (tv)) != 0) {
- at->route().set_order_key (N_("editor"), order);
+ at->route()->set_order_key (N_("editor"), order);
++order;
}
}
@@ -263,6 +258,10 @@ Editor::redisplay_route_list ()
}
+ /* make sure the cursors stay on top of every newly added track */
+
+ cursor_group->raise_to_top ();
+
reset_scrolling_region ();
}
@@ -473,7 +472,7 @@ Editor::route_list_selection_filter (const Glib::RefPtr<TreeModel>& model, const
}
struct EditorOrderRouteSorter {
- bool operator() (Route* a, Route* b) {
+ bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
return a->order_key ("editor") < b->order_key ("editor");
}
@@ -482,17 +481,18 @@ struct EditorOrderRouteSorter {
void
Editor::initial_route_list_display ()
{
- Session::RouteList routes = session->get_routes();
+ boost::shared_ptr<Session::RouteList> routes = session->get_routes();
+ Session::RouteList r (*routes);
EditorOrderRouteSorter sorter;
- routes.sort (sorter);
+ r.sort (sorter);
no_route_list_redisplay = true;
route_display_model->clear ();
- for (Session::RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- handle_new_route (**i);
+ for (Session::RouteList::iterator i = r.begin(); i != r.end(); ++i) {
+ handle_new_route (*i);
}
no_route_list_redisplay = false;
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index 27fa6c9651..3fe0023d07 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -29,7 +29,7 @@
#include "editor.h"
#include "audio_time_axis.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "region_selection.h"
#include <ardour/session.h>
@@ -101,7 +101,7 @@ Editor::TimeStretchDialog::delete_timestretch_in_progress (GdkEventAny* ev)
}
int
-Editor::run_timestretch (AudioRegionSelection& regions, float fraction)
+Editor::run_timestretch (RegionSelection& regions, float fraction)
{
pthread_t thread;
@@ -158,39 +158,42 @@ Editor::run_timestretch (AudioRegionSelection& regions, float fraction)
void
Editor::do_timestretch (TimeStretchDialog& dialog)
{
- AudioTrack* at;
+ Track* t;
Playlist* playlist;
- AudioRegion* new_region;
+ Region* new_region;
- for (AudioRegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
+ for (RegionSelection::iterator i = dialog.regions.begin(); i != dialog.regions.end(); ) {
+ AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*i);
+ if (!arv)
+ continue;
- AudioRegion& aregion ((*i)->region);
- TimeAxisView* tv = &(*i)->get_time_axis_view();
- AudioTimeAxisView* atv;
- AudioRegionSelection::iterator tmp;
+ AudioRegion& region (arv->audio_region());
+ TimeAxisView* tv = &(arv->get_time_axis_view());
+ RouteTimeAxisView* rtv;
+ RegionSelection::iterator tmp;
- cerr << "stretch " << aregion.name() << endl;
+ cerr << "stretch " << region.name() << endl;
tmp = i;
++tmp;
- if ((atv = dynamic_cast<AudioTimeAxisView*> (tv)) == 0) {
+ if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv)) == 0) {
i = tmp;
continue;
}
- if ((at = dynamic_cast<AudioTrack*> (&atv->route())) == 0) {
+ if ((t = dynamic_cast<Track*> (rtv->route().get())) == 0) {
i = tmp;
continue;
}
- if ((playlist = at->disk_stream().playlist()) == 0) {
+ if ((playlist = t->diskstream().playlist()) == 0) {
i = tmp;
continue;
}
- dialog.request.region = &aregion;
+ dialog.request.region = &region;
if (!dialog.request.running) {
/* we were cancelled */
@@ -205,7 +208,7 @@ Editor::do_timestretch (TimeStretchDialog& dialog)
}
XMLNode &before = playlist->get_state();
- playlist->replace_region (aregion, *new_region, aregion.position());
+ playlist->replace_region (region, *new_region, region.position());
XMLNode &after = playlist->get_state();
session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
diff --git a/gtk2_ardour/export_dialog.cc b/gtk2_ardour/export_dialog.cc
index bcf8cd85ad..b5a4757090 100644
--- a/gtk2_ardour/export_dialog.cc
+++ b/gtk2_ardour/export_dialog.cc
@@ -1082,11 +1082,11 @@ ExportDialog::fill_lists ()
track_list->clear();
master_list->clear();
- Session::RouteList routes = session->get_routes ();
+ boost::shared_ptr<Session::RouteList> routes = session->get_routes ();
- for (Session::RouteList::iterator ri = routes.begin(); ri != routes.end(); ++ri) {
-
- Route* route = (*ri);
+ for (Session::RouteList::iterator ri = routes->begin(); ri != routes->end(); ++ri) {
+
+ boost::shared_ptr<Route> route = (*ri);
if (route->hidden()) {
continue;
diff --git a/gtk2_ardour/export_region_dialog.cc b/gtk2_ardour/export_region_dialog.cc
index 97bf7c22b1..1964fabbfe 100644
--- a/gtk2_ardour/export_region_dialog.cc
+++ b/gtk2_ardour/export_region_dialog.cc
@@ -18,6 +18,8 @@
*/
+#include <cassert>
+
#include <pbd/pthread_utils.h>
#include <ardour/audioregion.h>
@@ -26,11 +28,13 @@
#include "i18n.h"
-ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::AudioRegion* region)
+ExportRegionDialog::ExportRegionDialog (PublicEditor& editor, ARDOUR::Region* region)
: ExportDialog(editor)
{
- audio_region = region;
-
+ // FIXME
+ ARDOUR::AudioRegion* audio_region = dynamic_cast<ARDOUR::AudioRegion*>(region);
+ assert(audio_region);
+
do_not_allow_track_and_master_selection();
do_not_allow_channel_count_selection();
}
diff --git a/gtk2_ardour/export_region_dialog.h b/gtk2_ardour/export_region_dialog.h
index 00464eb5b3..e8afe97d6b 100644
--- a/gtk2_ardour/export_region_dialog.h
+++ b/gtk2_ardour/export_region_dialog.h
@@ -27,7 +27,7 @@
class ExportRegionDialog : public ExportDialog
{
public:
- ExportRegionDialog (PublicEditor&, ARDOUR::AudioRegion*);
+ ExportRegionDialog (PublicEditor&, ARDOUR::Region*);
static void* _export_region_thread (void *);
void export_region ();
diff --git a/gtk2_ardour/fft_graph.cc b/gtk2_ardour/fft_graph.cc
index c2d81abf3c..367dc54b7c 100644
--- a/gtk2_ardour/fft_graph.cc
+++ b/gtk2_ardour/fft_graph.cc
@@ -234,11 +234,11 @@ FFTGraph::draw_scales(Glib::RefPtr<Gdk::Window> window)
while (_logScale[logscale_pos] < position_on_scale)
logscale_pos++;
- int coord = v_margin + 1.0 + position_on_scale;
+ int coord = (int)(v_margin + 1.0 + position_on_scale);
int SR = 44100;
- int rate_at_pos = (double)(SR/2) * (double)logscale_pos / (double)_dataSize;
+ int rate_at_pos = (int)((double)(SR/2) * (double)logscale_pos / (double)_dataSize);
char buf[32];
snprintf(buf,32,"%dhz",rate_at_pos);
@@ -384,7 +384,7 @@ FFTGraph::on_size_request(Gtk::Requisition* requisition)
}
void
-FFTGraph::on_size_allocate(Gtk::Allocation alloc)
+FFTGraph::on_size_allocate(Gtk::Allocation & alloc)
{
width = alloc.get_width();
height = alloc.get_height();
diff --git a/gtk2_ardour/fft_graph.h b/gtk2_ardour/fft_graph.h
index 80c78180a6..73636b989d 100644
--- a/gtk2_ardour/fft_graph.h
+++ b/gtk2_ardour/fft_graph.h
@@ -51,7 +51,7 @@ class FFTGraph : public Gtk::DrawingArea
bool on_expose_event (GdkEventExpose* event);
void on_size_request(Gtk::Requisition* requisition);
- void on_size_allocate(Gtk::Allocation alloc);
+ void on_size_allocate(Gtk::Allocation & alloc);
FFTResult *prepareResult(Gdk::Color color, std::string trackname);
private:
diff --git a/gtk2_ardour/fft_result.cc b/gtk2_ardour/fft_result.cc
index 9a55b59cb5..f5acef92ed 100644
--- a/gtk2_ardour/fft_result.cc
+++ b/gtk2_ardour/fft_result.cc
@@ -20,9 +20,9 @@
#include <fft_result.h>
#include <fft_graph.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
+#include <cstdlib>
+#include <string>
+#include <cmath>
#include <iostream>
diff --git a/gtk2_ardour/gain_automation_time_axis.cc b/gtk2_ardour/gain_automation_time_axis.cc
index 3e3d02bfc4..c86c1390f3 100644
--- a/gtk2_ardour/gain_automation_time_axis.cc
+++ b/gtk2_ardour/gain_automation_time_axis.cc
@@ -32,7 +32,9 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
-GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c)
+GainAutomationTimeAxisView::GainAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
+ PublicEditor& e, TimeAxisView& parent,
+ ArdourCanvas::Canvas& canvas, const string & n, ARDOUR::Curve& c)
: AxisView (s),
AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("gain"), ""),
@@ -74,6 +76,6 @@ void
GainAutomationTimeAxisView::set_automation_state (AutoState state)
{
if (!ignore_state_request) {
- route.set_gain_automation_state (state);
+ route->set_gain_automation_state (state);
}
}
diff --git a/gtk2_ardour/gain_automation_time_axis.h b/gtk2_ardour/gain_automation_time_axis.h
index 50f1cba3f9..dc6d5bd28e 100644
--- a/gtk2_ardour/gain_automation_time_axis.h
+++ b/gtk2_ardour/gain_automation_time_axis.h
@@ -13,7 +13,7 @@ class GainAutomationTimeAxisView : public AutomationTimeAxisView
{
public:
GainAutomationTimeAxisView (ARDOUR::Session&,
- ARDOUR::Route&,
+ boost::shared_ptr<ARDOUR::Route>,
PublicEditor&,
TimeAxisView& parent_axis,
ArdourCanvas::Canvas& canvas,
diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc
index b7746c4b19..5fa8c462bc 100644
--- a/gtk2_ardour/gain_meter.cc
+++ b/gtk2_ardour/gain_meter.cc
@@ -79,7 +79,7 @@ GainMeter::setup_slider_pix ()
return 0;
}
-GainMeter::GainMeter (IO& io, Session& s)
+GainMeter::GainMeter (boost::shared_ptr<IO> io, Session& s)
: _io (io),
_session (s),
gain_slider (0),
@@ -99,18 +99,13 @@ GainMeter::GainMeter (IO& io, Session& s)
gain_slider = manage (new VSliderController (slider, rail,
&gain_adjustment,
- & _io.midi_gain_control(),
+ _io->gain_control(),
false));
gain_slider->signal_button_press_event().connect (mem_fun(*this, &GainMeter::start_gain_touch));
gain_slider->signal_button_release_event().connect (mem_fun(*this, &GainMeter::end_gain_touch));
gain_slider->set_name ("MixerGainMeter");
- if (_session.midi_port()) {
- _io.set_midi_to_gain_function (slider_position_to_gain);
- _io.set_gain_to_midi_function (gain_to_slider_position);
- }
-
gain_display.set_print_func (_gain_printer, this);
gain_display_box.set_spacing (2);
@@ -157,7 +152,7 @@ GainMeter::GainMeter (IO& io, Session& s)
Route* r;
- if ((r = dynamic_cast<Route*> (&_io)) != 0) {
+ if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
/*
if we don't have a route (if we're the click),
pack some route-dependent stuff.
@@ -170,13 +165,13 @@ GainMeter::GainMeter (IO& io, Session& s)
using namespace Menu_Helpers;
gain_astate_menu.items().push_back (MenuElem (_("Off"),
- bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Off)));
+ bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Off)));
gain_astate_menu.items().push_back (MenuElem (_("Play"),
- bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Play)));
+ bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Play)));
gain_astate_menu.items().push_back (MenuElem (_("Write"),
- bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Write)));
+ bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Write)));
gain_astate_menu.items().push_back (MenuElem (_("Touch"),
- bind (mem_fun (&_io, &IO::set_gain_automation_state), (AutoState) Touch)));
+ bind (mem_fun (*_io, &IO::set_gain_automation_state), (AutoState) Touch)));
gain_astyle_menu.items().push_back (MenuElem (_("Trim")));
gain_astyle_menu.items().push_back (MenuElem (_("Abs")));
@@ -200,7 +195,7 @@ GainMeter::GainMeter (IO& io, Session& s)
pack_start (gain_display_box, Gtk::PACK_SHRINK);
pack_start (hbox, Gtk::PACK_SHRINK);
- _io.gain_changed.connect (mem_fun(*this, &GainMeter::gain_changed));
+ _io->gain_changed.connect (mem_fun(*this, &GainMeter::gain_changed));
meter_metric_area.signal_expose_event().connect (mem_fun(*this, &GainMeter::meter_metrics_expose));
gain_adjustment.signal_value_changed().connect (mem_fun(*this, &GainMeter::gain_adjusted));
@@ -328,7 +323,7 @@ GainMeter::update_meters ()
for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) {
if ((*i).packed) {
- peak = _io.peak_input_power (n);
+ peak = _io->peak_input_power (n);
(*i).meter->set (log_meter (peak), peak);
@@ -387,14 +382,14 @@ GainMeter::hide_all_meters ()
void
GainMeter::setup_meters ()
{
- uint32_t nmeters = _io.n_outputs();
+ uint32_t nmeters = _io->n_outputs();
guint16 width;
hide_all_meters ();
Route* r;
- if ((r = dynamic_cast<Route*> (&_io)) != 0) {
+ if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
switch (r->meter_point()) {
case MeterPreFader:
@@ -408,7 +403,7 @@ GainMeter::setup_meters ()
} else {
- nmeters = _io.n_outputs();
+ nmeters = _io->n_outputs();
}
@@ -456,7 +451,7 @@ GainMeter::peak_button_release (GdkEventButton* ev)
ResetAllPeakDisplays ();
} else if (ev->button == 1 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
Route* r;
- if ((r = dynamic_cast<Route*> (&_io)) != 0) {
+ if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
ResetGroupPeakDisplays (r->mix_group());
}
} else {
@@ -477,7 +472,7 @@ void
GainMeter::reset_group_peak_display (RouteGroup* group)
{
Route* r;
- if ((r = dynamic_cast<Route*> (&_io)) != 0) {
+ if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
if (group == r->mix_group()) {
reset_peak_display ();
}
@@ -546,14 +541,14 @@ void
GainMeter::gain_adjusted ()
{
if (!ignore_toggle) {
- _io.set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
+ _io->set_gain (slider_position_to_gain (gain_adjustment.get_value()), this);
}
}
void
GainMeter::effective_gain_display ()
{
- gfloat value = gain_to_slider_position (_io.effective_gain());
+ gfloat value = gain_to_slider_position (_io->effective_gain());
if (gain_adjustment.get_value() != value) {
ignore_toggle = true;
@@ -583,7 +578,7 @@ GainMeter::set_fader_name (const char * name)
void
GainMeter::update_gain_sensitive ()
{
- static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io.gain_automation_state() & Play));
+ static_cast<Gtkmm2ext::SliderController*>(gain_slider)->set_sensitive (!(_io->gain_automation_state() & Play));
}
@@ -614,7 +609,7 @@ GainMeter::meter_press(GdkEventButton* ev)
wait_for_release = false;
- if ((_route = dynamic_cast<Route*>(&_io)) == 0) {
+ if ((_route = dynamic_cast<Route*>(_io.get())) == 0) {
return FALSE;
}
@@ -676,7 +671,7 @@ GainMeter::meter_release(GdkEventButton* ev)
if(!ignore_toggle){
if (wait_for_release){
wait_for_release = false;
- set_meter_point (*(dynamic_cast<Route*>(&_io)), old_meter_point);
+ set_meter_point (*(dynamic_cast<Route*>(_io.get())), old_meter_point);
}
}
return true;
@@ -705,7 +700,7 @@ GainMeter::meter_point_clicked ()
{
Route* r;
- if ((r = dynamic_cast<Route*> (&_io)) != 0) {
+ if ((r = dynamic_cast<Route*> (_io.get())) != 0) {
}
}
@@ -713,14 +708,14 @@ GainMeter::meter_point_clicked ()
gint
GainMeter::start_gain_touch (GdkEventButton* ev)
{
- _io.start_gain_touch ();
+ _io->start_gain_touch ();
return FALSE;
}
gint
GainMeter::end_gain_touch (GdkEventButton* ev)
{
- _io.end_gain_touch ();
+ _io->end_gain_touch ();
return FALSE;
}
@@ -824,10 +819,10 @@ GainMeter::gain_automation_style_changed ()
// Route* _route = dynamic_cast<Route*>(&_io);
switch (_width) {
case Wide:
- gain_automation_style_button.set_label (astyle_string(_io.gain_automation_curve().automation_style()));
+ gain_automation_style_button.set_label (astyle_string(_io->gain_automation_curve().automation_style()));
break;
case Narrow:
- gain_automation_style_button.set_label (short_astyle_string(_io.gain_automation_curve().automation_style()));
+ gain_automation_style_button.set_label (short_astyle_string(_io->gain_automation_curve().automation_style()));
break;
}
}
@@ -842,14 +837,14 @@ GainMeter::gain_automation_state_changed ()
switch (_width) {
case Wide:
- gain_automation_state_button.set_label (astate_string(_io.gain_automation_curve().automation_state()));
+ gain_automation_state_button.set_label (astate_string(_io->gain_automation_curve().automation_state()));
break;
case Narrow:
- gain_automation_state_button.set_label (short_astate_string(_io.gain_automation_curve().automation_state()));
+ gain_automation_state_button.set_label (short_astate_string(_io->gain_automation_curve().automation_state()));
break;
}
- x = (_io.gain_automation_state() != Off);
+ x = (_io->gain_automation_state() != Off);
if (gain_automation_state_button.get_active() != x) {
ignore_toggle = true;
diff --git a/gtk2_ardour/gain_meter.h b/gtk2_ardour/gain_meter.h
index ddf93b579f..1dfc088248 100644
--- a/gtk2_ardour/gain_meter.h
+++ b/gtk2_ardour/gain_meter.h
@@ -34,8 +34,8 @@
#include <ardour/types.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/click_box.h>
+#include <gtkmm2ext/slider_controller.h>
#include "enums.h"
@@ -56,7 +56,7 @@ namespace Gtk {
class GainMeter : public Gtk::VBox
{
public:
- GainMeter (ARDOUR::IO&, ARDOUR::Session&);
+ GainMeter (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
~GainMeter ();
void update_gain_sensitive ();
@@ -75,7 +75,7 @@ class GainMeter : public Gtk::VBox
private:
friend class MixerStrip;
- ARDOUR::IO& _io;
+ boost::shared_ptr<ARDOUR::IO> _io;
ARDOUR::Session& _session;
bool ignore_toggle;
diff --git a/gtk2_ardour/io_selector.cc b/gtk2_ardour/io_selector.cc
index b0ecd05077..f754435112 100644
--- a/gtk2_ardour/io_selector.cc
+++ b/gtk2_ardour/io_selector.cc
@@ -52,7 +52,7 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gtkmm2ext;
-IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can_cancel)
+IOSelectorWindow::IOSelectorWindow (Session& sess, boost::shared_ptr<IO> ior, bool input, bool can_cancel)
: ArdourDialog ("i/o selector"),
_selector (sess, ior, input),
ok_button (can_cancel ? _("OK"): _("Close")),
@@ -65,9 +65,9 @@ IOSelectorWindow::IOSelectorWindow (Session& sess, IO& ior, bool input, bool can
string title;
if (input) {
- title = string_compose(_("%1 input"), ior.name());
+ title = string_compose(_("%1 input"), ior->name());
} else {
- title = string_compose(_("%1 output"), ior.name());
+ title = string_compose(_("%1 output"), ior->name());
}
ok_button.set_name ("IOSelectorButton");
@@ -135,7 +135,7 @@ IOSelectorWindow::on_map ()
The IO Selector "widget"
*************************/
-IOSelector::IOSelector (Session& sess, IO& ior, bool input)
+IOSelector::IOSelector (Session& sess, boost::shared_ptr<IO> ior, bool input)
: session (sess),
io (ior),
for_input (input),
@@ -184,14 +184,14 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input)
port_button_box.pack_start (add_port_button, false, false);
if (for_input) {
- if (io.input_maximum() < 0 || io.input_maximum() > (int) io.n_inputs()) {
+ if (io->input_maximum() < 0 || io->input_maximum() > (int) io->n_inputs()) {
add_port_button.set_sensitive (true);
} else {
add_port_button.set_sensitive (false);
}
} else {
- if (io.output_maximum() < 0 || io.output_maximum() > (int) io.n_outputs()) {
+ if (io->output_maximum() < 0 || io->output_maximum() > (int) io->n_outputs()) {
add_port_button.set_sensitive (true);
} else {
add_port_button.set_sensitive (false);
@@ -202,14 +202,14 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input)
port_button_box.pack_start (remove_port_button, false, false);
if (for_input) {
- if (io.input_minimum() < 0 || io.input_minimum() < (int) io.n_inputs()) {
+ if (io->input_minimum() < 0 || io->input_minimum() < (int) io->n_inputs()) {
remove_port_button.set_sensitive (true);
} else {
remove_port_button.set_sensitive (false);
}
} else {
- if (io.output_minimum() < 0 || io.output_minimum() < (int) io.n_outputs()) {
+ if (io->output_minimum() < 0 || io->output_minimum() < (int) io->n_outputs()) {
remove_port_button.set_sensitive (true);
} else {
remove_port_button.set_sensitive (false);
@@ -241,12 +241,12 @@ IOSelector::IOSelector (Session& sess, IO& ior, bool input)
remove_port_button.signal_clicked().connect (mem_fun(*this, &IOSelector::remove_port));
if (for_input) {
- io.input_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
+ io->input_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
} else {
- io.output_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
+ io->output_changed.connect (mem_fun(*this, &IOSelector::ports_changed));
}
- io.name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
+ io->name_changed.connect (mem_fun(*this, &IOSelector::name_changed));
}
IOSelector::~IOSelector ()
@@ -265,9 +265,9 @@ void
IOSelector::clear_connections ()
{
if (for_input) {
- io.disconnect_inputs (this);
+ io->disconnect_inputs (this);
} else {
- io.disconnect_outputs (this);
+ io->disconnect_outputs (this);
}
}
@@ -374,9 +374,9 @@ IOSelector::display_ports ()
uint32_t limit;
if (for_input) {
- limit = io.n_inputs();
+ limit = io->n_inputs();
} else {
- limit = io.n_outputs();
+ limit = io->n_outputs();
}
for (slist<TreeView *>::iterator i = port_displays.begin(); i != port_displays.end(); ) {
@@ -401,9 +401,9 @@ IOSelector::display_ports ()
string really_short_name;
if (for_input) {
- port = io.input (n);
+ port = io->input (n);
} else {
- port = io.output (n);
+ port = io->output (n);
}
/* we know there is '/' because we put it there */
@@ -443,7 +443,7 @@ IOSelector::display_ports ()
if (for_input) {
- if (io.input_maximum() == 1) {
+ if (io->input_maximum() == 1) {
selected_port = port;
selected_port_tview = tview;
} else {
@@ -454,7 +454,7 @@ IOSelector::display_ports ()
} else {
- if (io.output_maximum() == 1) {
+ if (io->output_maximum() == 1) {
selected_port = port;
selected_port_tview = tview;
} else {
@@ -516,12 +516,12 @@ IOSelector::port_selection_changed (GdkEventButton *ev, TreeView* treeview)
ustring other_port_name = (*i)[port_display_columns.full_name];
if (for_input) {
- if ((status = io.connect_input (selected_port, other_port_name, this)) == 0) {
+ if ((status = io->connect_input (selected_port, other_port_name, this)) == 0) {
Port *p = session.engine().get_port_by_name (other_port_name);
p->enable_metering();
}
} else {
- status = io.connect_output (selected_port, other_port_name, this);
+ status = io->connect_output (selected_port, other_port_name, this);
}
if (status == 0) {
@@ -548,7 +548,7 @@ IOSelector::add_port ()
if (for_input) {
try {
- io.add_input_port ("", this);
+ io->add_input_port ("", this);
}
catch (AudioEngine::PortRegistrationFailure& err) {
@@ -556,18 +556,18 @@ IOSelector::add_port ()
msg.run ();
}
- if (io.input_maximum() >= 0 && io.input_maximum() <= (int) io.n_inputs()) {
+ if (io->input_maximum() >= 0 && io->input_maximum() <= (int) io->n_inputs()) {
add_port_button.set_sensitive (false);
}
- if (io.input_minimum() < (int) io.n_inputs()) {
+ if (io->input_minimum() < (int) io->n_inputs()) {
remove_port_button.set_sensitive (true);
}
} else {
try {
- io.add_output_port ("", this);
+ io->add_output_port ("", this);
}
catch (AudioEngine::PortRegistrationFailure& err) {
@@ -575,7 +575,7 @@ IOSelector::add_port ()
msg.run ();
}
- if (io.output_maximum() >= 0 && io.output_maximum() <= (int) io.n_outputs()) {
+ if (io->output_maximum() >= 0 && io->output_maximum() <= (int) io->n_outputs()) {
add_port_button.set_sensitive (false);
}
}
@@ -589,15 +589,15 @@ IOSelector::remove_port ()
// always remove last port
if (for_input) {
- if ((nports = io.n_inputs()) > 0) {
- io.remove_input_port (io.input(nports-1), this);
+ if ((nports = io->n_inputs()) > 0) {
+ io->remove_input_port (io->input(nports-1), this);
}
- if (io.input_minimum() == (int) io.n_inputs()) {
+ if (io->input_minimum() == (int) io->n_inputs()) {
remove_port_button.set_sensitive (false);
}
} else {
- if ((nports = io.n_outputs()) > 0) {
- io.remove_output_port (io.output(nports-1), this);
+ if ((nports = io->n_outputs()) > 0) {
+ io->remove_output_port (io->output(nports-1), this);
}
}
}
@@ -606,9 +606,9 @@ gint
IOSelector::remove_port_when_idle (Port *port)
{
if (for_input) {
- io.remove_input_port (port, this);
+ io->remove_input_port (port, this);
} else {
- io.remove_output_port (port, this);
+ io->remove_output_port (port, this);
}
return FALSE;
@@ -651,9 +651,9 @@ IOSelector::connection_button_release (GdkEventButton *ev, TreeView *treeview)
if (for_input) {
Port *p = session.engine().get_port_by_name (connected_port_name);
p->disable_metering();
- io.disconnect_input (port, connected_port_name, this);
+ io->disconnect_input (port, connected_port_name, this);
} else {
- io.disconnect_output (port, connected_port_name, this);
+ io->disconnect_output (port, connected_port_name, this);
}
}
@@ -749,17 +749,17 @@ IOSelector::redisplay ()
display_ports ();
if (for_input) {
- if (io.input_maximum() != 0) {
+ if (io->input_maximum() != 0) {
rescan ();
}
} else {
- if (io.output_maximum() != 0) {
+ if (io->output_maximum() != 0) {
rescan();
}
}
}
-PortInsertUI::PortInsertUI (Session& sess, PortInsert& pi)
+PortInsertUI::PortInsertUI (Session& sess, boost::shared_ptr<PortInsert> pi)
: input_selector (sess, pi, true),
output_selector (sess, pi, false)
{
@@ -786,9 +786,9 @@ PortInsertUI::finished(IOSelector::Result r)
}
-PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_cancel)
+PortInsertWindow::PortInsertWindow (Session& sess, boost::shared_ptr<PortInsert> pi, bool can_cancel)
: ArdourDialog ("port insert dialog"),
- _portinsertui(sess, pi),
+ _portinsertui (sess, pi),
ok_button (can_cancel ? _("OK"): _("Close")),
cancel_button (_("Cancel")),
rescan_button (_("Rescan"))
@@ -796,7 +796,7 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc
set_name ("IOSelectorWindow");
string title = _("ardour: ");
- title += pi.name();
+ title += pi->name();
set_title (title);
ok_button.set_name ("IOSelectorButton");
@@ -823,7 +823,7 @@ PortInsertWindow::PortInsertWindow (Session& sess, PortInsert& pi, bool can_canc
rescan_button.signal_clicked().connect (mem_fun(*this, &PortInsertWindow::rescan));
signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window *> (this)));
- pi.GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away));
+ pi->GoingAway.connect (mem_fun(*this, &PortInsertWindow::plugin_going_away));
}
void
diff --git a/gtk2_ardour/io_selector.h b/gtk2_ardour/io_selector.h
index 44518e6759..993d4aa1ad 100644
--- a/gtk2_ardour/io_selector.h
+++ b/gtk2_ardour/io_selector.h
@@ -53,7 +53,7 @@ namespace ARDOUR {
class IOSelector : public Gtk::VBox {
public:
- IOSelector (ARDOUR::Session&, ARDOUR::IO&, bool for_input);
+ IOSelector (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool for_input);
~IOSelector ();
void redisplay ();
@@ -67,9 +67,9 @@ class IOSelector : public Gtk::VBox {
protected:
ARDOUR::Session& session;
-
+
private:
- ARDOUR::IO& io;
+ boost::shared_ptr<ARDOUR::IO> io;
bool for_input;
ARDOUR::Port *selected_port;
@@ -135,7 +135,7 @@ class IOSelector : public Gtk::VBox {
class IOSelectorWindow : public ArdourDialog
{
public:
- IOSelectorWindow (ARDOUR::Session&, ARDOUR::IO&, bool for_input, bool can_cancel=false);
+ IOSelectorWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::IO>, bool for_input, bool can_cancel=false);
~IOSelectorWindow ();
IOSelector& selector() { return _selector; }
@@ -162,7 +162,7 @@ class IOSelectorWindow : public ArdourDialog
class PortInsertUI : public Gtk::VBox
{
public:
- PortInsertUI (ARDOUR::Session&, ARDOUR::PortInsert&);
+ PortInsertUI (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>);
void redisplay ();
void finished (IOSelector::Result);
@@ -178,7 +178,7 @@ class PortInsertUI : public Gtk::VBox
class PortInsertWindow : public ArdourDialog
{
public:
- PortInsertWindow (ARDOUR::Session&, ARDOUR::PortInsert&, bool can_cancel=false);
+ PortInsertWindow (ARDOUR::Session&, boost::shared_ptr<ARDOUR::PortInsert>, bool can_cancel=false);
protected:
void on_map ();
diff --git a/gtk2_ardour/keyboard.h b/gtk2_ardour/keyboard.h
index 06ed4c800d..c13b06afe5 100644
--- a/gtk2_ardour/keyboard.h
+++ b/gtk2_ardour/keyboard.h
@@ -28,7 +28,7 @@
#include <gtk/gtk.h>
#include <ardour/types.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
#include "selection.h"
diff --git a/gtk2_ardour/main.cc b/gtk2_ardour/main.cc
index 778355c858..047bb130a4 100644
--- a/gtk2_ardour/main.cc
+++ b/gtk2_ardour/main.cc
@@ -446,7 +446,7 @@ int main (int argc, char *argv[])
try {
engine = new ARDOUR::AudioEngine (jack_client_name);
- ARDOUR::init (*engine, use_vst, try_hw_optimization);
+ ARDOUR::init (use_vst, try_hw_optimization);
ui->set_engine (*engine);
} catch (AudioEngine::NoBackendAvailable& err) {
gui_jack_error ();
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 47d884be5e..4f3dc720d9 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -27,10 +27,10 @@
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/stop_signal.h>
-#include <gtkmm2ext/bindable_button.h>
#include <gtkmm2ext/doi.h>
+#include <gtkmm2ext/slider_controller.h>
+#include <gtkmm2ext/bindable_button.h>
#include <ardour/ardour.h>
#include <ardour/session.h>
@@ -52,7 +52,6 @@
#include "keyboard.h"
#include "plugin_selector.h"
#include "public_editor.h"
-
#include "plugin_ui.h"
#include "send_ui.h"
#include "io_selector.h"
@@ -81,7 +80,7 @@ speed_printer (char buf[32], Gtk::Adjustment& adj, void* arg)
}
#endif
-MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
+MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, boost::shared_ptr<Route> rt, bool in_mixer)
: AxisView(sess),
RouteUI (rt, sess, _("Mute"), _("Solo"), _("Record")),
_mixer(mx),
@@ -126,12 +125,12 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
output_button.set_name ("MixerIOButton");
output_label.set_name ("MixerIOButtonLabel");
- _route.meter_change.connect (mem_fun(*this, &MixerStrip::meter_changed));
+ _route->meter_change.connect (mem_fun(*this, &MixerStrip::meter_changed));
meter_point_button.add (meter_point_label);
meter_point_button.set_name ("MixerStripMeterPreButton");
meter_point_label.set_name ("MixerStripMeterPreButton");
- switch (_route.meter_point()) {
+ switch (_route->meter_point()) {
case MeterInput:
meter_point_label.set_text (_("input"));
break;
@@ -159,9 +158,6 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
/* XXX what is this meant to do? */
//meter_point_button.signal_button_release_event().connect (mem_fun (gpm, &GainMeter::meter_release), false);
- rec_enable_button->set_name ("MixerRecordEnableButton");
- rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
-
solo_button->set_name ("MixerSoloButton");
mute_button->set_name ("MixerMuteButton");
@@ -191,7 +187,11 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
if (is_audio_track()) {
- AudioTrack* at = dynamic_cast<AudioTrack*>(&_route);
+ rec_enable_button->set_name ("MixerRecordEnableButton");
+ rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
+ rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
+
+ AudioTrack* at = audio_track();
at->FreezeChange.connect (mem_fun(*this, &MixerStrip::map_frozen));
@@ -217,10 +217,10 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2);
name_label.set_name ("MixerNameButtonLabel");
- if (_route.phase_invert()) {
+ if (_route->phase_invert()) {
name_label.set_text (X_("Ø ") + name_label.get_text());
} else {
- name_label.set_text (_route.name());
+ name_label.set_text (_route->name());
}
group_button.add (group_label);
@@ -229,9 +229,9 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
comment_button.set_name ("MixerCommentButton");
- ARDOUR_UI::instance()->tooltips().set_tip (comment_button, _route.comment()=="" ?
+ ARDOUR_UI::instance()->tooltips().set_tip (comment_button, _route->comment()=="" ?
_("Click to Add/Edit Comments"):
- _route.comment());
+ _route->comment());
comment_button.signal_clicked().connect (mem_fun(*this, &MixerStrip::comment_button_clicked));
@@ -281,27 +281,26 @@ MixerStrip::MixerStrip (Mixer_UI& mx, Session& sess, Route& rt, bool in_mixer)
_session.engine().Stopped.connect (mem_fun(*this, &MixerStrip::engine_stopped));
_session.engine().Running.connect (mem_fun(*this, &MixerStrip::engine_running));
- _route.input_changed.connect (mem_fun(*this, &MixerStrip::input_changed));
- _route.output_changed.connect (mem_fun(*this, &MixerStrip::output_changed));
- _route.mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
- _route.solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
- _route.solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
- _route.mix_group_changed.connect (mem_fun(*this, &MixerStrip::mix_group_changed));
- _route.panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan));
+ _route->input_changed.connect (mem_fun(*this, &MixerStrip::input_changed));
+ _route->output_changed.connect (mem_fun(*this, &MixerStrip::output_changed));
+ _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
+ _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
+ _route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
+ _route->mix_group_changed.connect (mem_fun(*this, &MixerStrip::mix_group_changed));
+ _route->panner().Changed.connect (mem_fun(*this, &MixerStrip::connect_to_pan));
if (is_audio_track()) {
- audio_track()->diskstream_changed.connect (mem_fun(*this, &MixerStrip::diskstream_changed));
- get_diskstream()->speed_changed.connect (mem_fun(*this, &MixerStrip::speed_changed));
+ audio_track()->DiskstreamChanged.connect (mem_fun(*this, &MixerStrip::diskstream_changed));
+ get_diskstream()->SpeedChanged.connect (mem_fun(*this, &MixerStrip::speed_changed));
}
- _route.name_changed.connect (mem_fun(*this, &RouteUI::name_changed));
- _route.comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed));
- _route.gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed));
+ _route->name_changed.connect (mem_fun(*this, &RouteUI::name_changed));
+ _route->comment_changed.connect (mem_fun(*this, &MixerStrip::comment_changed));
+ _route->gui_changed.connect (mem_fun(*this, &MixerStrip::route_gui_changed));
input_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::input_press), false);
output_button.signal_button_press_event().connect (mem_fun(*this, &MixerStrip::output_press), false);
- rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false);
solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false);
mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false);
@@ -414,20 +413,22 @@ MixerStrip::set_width (Width w)
set_size_request (-1, -1);
xml_node->add_property ("strip_width", "wide");
- rec_enable_button->set_label (_("record"));
+ if (rec_enable_button) {
+ rec_enable_button->set_label (_("record"));
+ }
mute_button->set_label (_("mute"));
solo_button->set_label (_("solo"));
- if (_route.comment() == "") {
+ if (_route->comment() == "") {
comment_button.set_label (_("comments"));
} else {
comment_button.set_label (_("*comments*"));
}
- gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route.gain_automation_curve().automation_style()));
- gpm.gain_automation_state_button.set_label (gpm.astate_string(_route.gain_automation_curve().automation_state()));
- panners.pan_automation_style_button.set_label (panners.astyle_string(_route.panner().automation_style()));
- panners.pan_automation_state_button.set_label (panners.astate_string(_route.panner().automation_state()));
+ gpm.gain_automation_style_button.set_label (gpm.astyle_string(_route->gain_automation_curve().automation_style()));
+ gpm.gain_automation_state_button.set_label (gpm.astate_string(_route->gain_automation_curve().automation_state()));
+ panners.pan_automation_style_button.set_label (panners.astyle_string(_route->panner().automation_style()));
+ panners.pan_automation_state_button.set_label (panners.astate_string(_route->panner().automation_state()));
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "long", 2, 2);
break;
@@ -435,20 +436,22 @@ MixerStrip::set_width (Width w)
set_size_request (50, -1);
xml_node->add_property ("strip_width", "narrow");
- rec_enable_button->set_label (_("Rec"));
+ if (rec_enable_button) {
+ rec_enable_button->set_label (_("Rec"));
+ }
mute_button->set_label (_("M"));
solo_button->set_label (_("S"));
- if (_route.comment() == "") {
+ if (_route->comment() == "") {
comment_button.set_label (_("Cmt"));
} else {
comment_button.set_label (_("*Cmt*"));
}
- gpm.gain_automation_style_button.set_label (gpm.short_astyle_string(_route.gain_automation_curve().automation_style()));
- gpm.gain_automation_state_button.set_label (gpm.short_astate_string(_route.gain_automation_curve().automation_state()));
- panners.pan_automation_style_button.set_label (panners.short_astyle_string(_route.panner().automation_style()));
- panners.pan_automation_state_button.set_label (panners.short_astate_string(_route.panner().automation_state()));
+ gpm.gain_automation_style_button.set_label (gpm.short_astyle_string(_route->gain_automation_curve().automation_style()));
+ gpm.gain_automation_state_button.set_label (gpm.short_astate_string(_route->gain_automation_curve().automation_state()));
+ panners.pan_automation_style_button.set_label (panners.short_astyle_string(_route->panner().automation_style()));
+ panners.pan_automation_state_button.set_label (panners.short_astate_string(_route->panner().automation_state()));
Gtkmm2ext::set_size_request_to_display_given_text (name_button, "longest label", 2, 2);
break;
}
@@ -555,11 +558,6 @@ MixerStrip::input_press (GdkEventButton *ev)
case 1:
-#if ADVANCED_ROUTE_DISKSTREAM_CONNECTIVITY
- if (is_audio_track()) {
- citems.push_back (MenuElem (_("Track"), mem_fun(*this, &MixerStrip::select_stream_input)));
- }
-#endif
citems.push_back (MenuElem (_("Edit"), mem_fun(*this, &MixerStrip::edit_input_configuration)));
citems.push_back (SeparatorElem());
citems.push_back (MenuElem (_("Disconnect"), mem_fun (*(static_cast<RouteUI*>(this)), &RouteUI::disconnect_input)));
@@ -581,7 +579,7 @@ MixerStrip::connection_input_chosen (ARDOUR::Connection *c)
if (!ignore_toggle) {
try {
- _route.use_input_connection (*c, this);
+ _route->use_input_connection (*c, this);
}
catch (AudioEngine::PortRegistrationFailure& err) {
@@ -597,7 +595,7 @@ MixerStrip::connection_output_chosen (ARDOUR::Connection *c)
if (!ignore_toggle) {
try {
- _route.use_output_connection (*c, this);
+ _route->use_output_connection (*c, this);
}
catch (AudioEngine::PortRegistrationFailure& err) {
@@ -618,11 +616,11 @@ MixerStrip::add_connection_to_input_menu (ARDOUR::Connection* c)
MenuList& citems = input_menu.items();
- if (c->nports() == _route.n_inputs()) {
+ if (c->nports() == _route->n_inputs()) {
citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_input_chosen), c)));
- ARDOUR::Connection *current = _route.input_connection();
+ ARDOUR::Connection *current = _route->input_connection();
if (current == c) {
ignore_toggle = true;
@@ -641,12 +639,12 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c)
return;
}
- if (c->nports() == _route.n_outputs()) {
+ if (c->nports() == _route->n_outputs()) {
MenuList& citems = output_menu.items();
citems.push_back (CheckMenuElem (c->name(), bind (mem_fun(*this, &MixerStrip::connection_output_chosen), c)));
- ARDOUR::Connection *current = _route.output_connection();
+ ARDOUR::Connection *current = _route->output_connection();
if (current == c) {
ignore_toggle = true;
@@ -657,42 +655,6 @@ MixerStrip::add_connection_to_output_menu (ARDOUR::Connection* c)
}
void
-MixerStrip::select_stream_input ()
-{
- using namespace Menu_Helpers;
-
- Menu *stream_menu = manage (new Menu);
- MenuList& items = stream_menu->items();
- stream_menu->set_name ("ArdourContextMenu");
-
- Session::AudioDiskstreamList streams = _session.audio_disk_streams();
-
- for (Session::AudioDiskstreamList::iterator i = streams.begin(); i != streams.end(); ++i) {
-
- if (!(*i)->hidden()) {
-
- items.push_back (CheckMenuElem ((*i)->name(), bind (mem_fun(*this, &MixerStrip::stream_input_chosen), *i)));
-
- if (get_diskstream() == *i) {
- ignore_toggle = true;
- static_cast<CheckMenuItem *> (&items.back())->set_active (true);
- ignore_toggle = false;
- }
- }
- }
-
- stream_menu->popup (1, 0);
-}
-
-void
-MixerStrip::stream_input_chosen (AudioDiskstream *stream)
-{
- if (is_audio_track()) {
- audio_track()->set_diskstream (*stream, this);
- }
-}
-
-void
MixerStrip::update_diskstream_display ()
{
if (is_audio_track()) {
@@ -724,8 +686,8 @@ MixerStrip::connect_to_pan ()
panstate_connection.disconnect ();
panstyle_connection.disconnect ();
- if (!_route.panner().empty()) {
- StreamPanner* sp = _route.panner().front();
+ if (!_route->panner().empty()) {
+ StreamPanner* sp = _route->panner().front();
panstate_connection = sp->automation().automation_state_changed.connect (mem_fun(panners, &PannerUI::pan_automation_state_changed));
panstyle_connection = sp->automation().automation_style_changed.connect (mem_fun(panners, &PannerUI::pan_automation_style_changed));
@@ -739,7 +701,7 @@ MixerStrip::update_input_display ()
{
ARDOUR::Connection *c;
- if ((c = _route.input_connection()) != 0) {
+ if ((c = _route->input_connection()) != 0) {
input_label.set_text (c->name());
} else {
switch (_width) {
@@ -759,7 +721,7 @@ MixerStrip::update_output_display ()
{
ARDOUR::Connection *c;
- if ((c = _route.output_connection()) != 0) {
+ if ((c = _route->output_connection()) != 0) {
output_label.set_text (c->name());
} else {
switch (_width) {
@@ -782,7 +744,7 @@ MixerStrip::fast_update ()
}
void
-MixerStrip::diskstream_changed (void *src)
+MixerStrip::diskstream_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &MixerStrip::update_diskstream_display));
}
@@ -810,8 +772,8 @@ MixerStrip::comment_button_clicked ()
if (comment_window->is_visible()) {
string str = comment_area->get_buffer()->get_text();
- if (_route.comment() != str) {
- _route.set_comment (str, this);
+ if (_route->comment() != str) {
+ _route->set_comment (str, this);
switch (_width) {
@@ -855,7 +817,7 @@ void
MixerStrip::setup_comment_editor ()
{
string title;
- title = _route.name();
+ title = _route->name();
title += _(": comment editor");
comment_window = new ArdourDialog (title, false);
@@ -867,7 +829,7 @@ MixerStrip::setup_comment_editor ()
comment_area->set_size_request (110, 178);
comment_area->set_wrap_mode (WRAP_WORD);
comment_area->set_editable (true);
- comment_area->get_buffer()->set_text (_route.comment());
+ comment_area->get_buffer()->set_text (_route->comment());
comment_area->show ();
comment_window->get_vbox()->pack_start (*comment_area);
@@ -882,7 +844,7 @@ MixerStrip::comment_changed (void *src)
if (src != this) {
ignore_comment_edit = true;
if (comment_area) {
- comment_area->get_buffer()->set_text (_route.comment());
+ comment_area->get_buffer()->set_text (_route->comment());
}
ignore_comment_edit = false;
}
@@ -891,7 +853,7 @@ MixerStrip::comment_changed (void *src)
void
MixerStrip::set_mix_group (RouteGroup *rg)
{
- _route.set_mix_group (rg, this);
+ _route->set_mix_group (rg, this);
}
void
@@ -903,7 +865,7 @@ MixerStrip::add_mix_group_to_menu (RouteGroup *rg, RadioMenuItem::Group* group)
items.push_back (RadioMenuElem (*group, rg->name(), bind (mem_fun(*this, &MixerStrip::set_mix_group), rg)));
- if (_route.mix_group() == rg) {
+ if (_route->mix_group() == rg) {
static_cast<RadioMenuItem*>(&items.back())->set_active ();
}
}
@@ -943,7 +905,7 @@ MixerStrip::mix_group_changed (void *ignored)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &MixerStrip::mix_group_changed), ignored));
- RouteGroup *rg = _route.mix_group();
+ RouteGroup *rg = _route->mix_group();
if (rg) {
group_label.set_text (rg->name());
@@ -999,11 +961,11 @@ MixerStrip::build_route_ops_menu ()
items.push_back (SeparatorElem());
items.push_back (CheckMenuElem (_("Active"), mem_fun (*this, &RouteUI::toggle_route_active)));
route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
- route_active_menu_item->set_active (_route.active());
+ route_active_menu_item->set_active (_route->active());
items.push_back (SeparatorElem());
items.push_back (CheckMenuElem (_("Invert Polarity"), mem_fun (*this, &RouteUI::toggle_polarity)));
polarity_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
- polarity_menu_item->set_active (_route.phase_invert());
+ polarity_menu_item->set_active (_route->phase_invert());
build_remote_control_menu ();
@@ -1093,10 +1055,10 @@ MixerStrip::name_changed (void *src)
RouteUI::name_changed (src);
break;
case Narrow:
- name_label.set_text (PBD::short_version (_route.name(), 5));
+ name_label.set_text (PBD::short_version (_route->name(), 5));
break;
}
- if (_route.phase_invert()) {
+ if (_route->phase_invert()) {
name_label.set_text (X_("Ø ") + name_label.get_text());
}
}
@@ -1135,7 +1097,7 @@ MixerStrip::map_frozen ()
{
ENSURE_GUI_THREAD (mem_fun(*this, &MixerStrip::map_frozen));
- AudioTrack* at = dynamic_cast<AudioTrack*>(&_route);
+ AudioTrack* at = audio_track();
if (at) {
switch (at->freeze_state()) {
@@ -1151,11 +1113,11 @@ MixerStrip::map_frozen ()
break;
}
}
- _route.foreach_redirect (this, &MixerStrip::hide_redirect_editor);
+ _route->foreach_redirect (this, &MixerStrip::hide_redirect_editor);
}
void
-MixerStrip::hide_redirect_editor (Redirect* redirect)
+MixerStrip::hide_redirect_editor (boost::shared_ptr<Redirect> redirect)
{
void* gui = redirect->get_gui ();
@@ -1170,7 +1132,7 @@ MixerStrip::route_active_changed ()
RouteUI::route_active_changed ();
if (is_audio_track()) {
- if (_route.active()) {
+ if (_route->active()) {
set_name ("AudioTrackStripBase");
gpm.set_meter_strip_name ("AudioTrackStripBase");
} else {
@@ -1178,8 +1140,8 @@ MixerStrip::route_active_changed ()
gpm.set_meter_strip_name ("AudioTrackStripBaseInactive");
}
gpm.set_fader_name ("AudioTrackFader");
- } else {
- if (_route.active()) {
+ } else { // FIXME: assumed audio bus
+ if (_route->active()) {
set_name ("AudioBusStripBase");
gpm.set_meter_strip_name ("AudioBusStripBase");
} else {
@@ -1193,14 +1155,16 @@ MixerStrip::route_active_changed ()
RouteGroup*
MixerStrip::mix_group() const
{
- return _route.mix_group();
+ return _route->mix_group();
}
void
MixerStrip::engine_stopped ()
{
input_button.set_sensitive (false);
- rec_enable_button->set_sensitive (false);
+ if (rec_enable_button) {
+ rec_enable_button->set_sensitive (false);
+ }
output_button.set_sensitive (false);
}
@@ -1208,7 +1172,9 @@ void
MixerStrip::engine_running ()
{
input_button.set_sensitive (true);
- rec_enable_button->set_sensitive (true);
+ if (rec_enable_button) {
+ rec_enable_button->set_sensitive (true);
+ }
output_button.set_sensitive (true);
}
@@ -1218,7 +1184,7 @@ MixerStrip::meter_changed (void *src)
ENSURE_GUI_THREAD (bind (mem_fun(*this, &MixerStrip::meter_changed), src));
- switch (_route.meter_point()) {
+ switch (_route->meter_point()) {
case MeterInput:
meter_point_label.set_text (_("input"));
break;
diff --git a/gtk2_ardour/mixer_strip.h b/gtk2_ardour/mixer_strip.h
index 0cc8fed8e3..21db0d14ca 100644
--- a/gtk2_ardour/mixer_strip.h
+++ b/gtk2_ardour/mixer_strip.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -14,8 +14,6 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
*/
#ifndef __ardour_mixer_strip__
@@ -37,14 +35,15 @@
#include <gtkmm/adjustment.h>
#include <gtkmm2ext/auto_spin.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/click_box.h>
+#include <gtkmm2ext/slider_controller.h>
+
+#include <pbd/stateful.h>
#include <ardour/types.h>
#include <ardour/ardour.h>
#include <ardour/io.h>
#include <ardour/insert.h>
-#include <ardour/stateful.h>
#include <ardour/redirect.h>
#include <pbd/fastlog.h>
@@ -83,7 +82,7 @@ class Mixer_UI;
class MixerStrip : public RouteUI, public Gtk::EventBox
{
public:
- MixerStrip (Mixer_UI&, ARDOUR::Session&, ARDOUR::Route &, bool in_mixer = true);
+ MixerStrip (Mixer_UI&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, bool in_mixer = true);
~MixerStrip ();
void set_width (Width);
@@ -170,15 +169,13 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
Gtk::Menu output_menu;
void add_connection_to_output_menu (ARDOUR::Connection *);
- void stream_input_chosen (ARDOUR::AudioDiskstream*);
- void select_stream_input ();
void connection_input_chosen (ARDOUR::Connection *);
void connection_output_chosen (ARDOUR::Connection *);
void edit_input_configuration ();
void edit_output_configuration ();
- void diskstream_changed (void *src);
+ void diskstream_changed ();
Gtk::Menu *send_action_menu;
void build_send_action_menu ();
@@ -238,7 +235,7 @@ class MixerStrip : public RouteUI, public Gtk::EventBox
void name_changed (void *src);
void update_speed_display ();
void map_frozen ();
- void hide_redirect_editor (ARDOUR::Redirect* redirect);
+ void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect> redirect);
bool ignore_speed_adjustment;
diff --git a/gtk2_ardour/mixer_ui.cc b/gtk2_ardour/mixer_ui.cc
index 983903d6dd..c2eb588b2f 100644
--- a/gtk2_ardour/mixer_ui.cc
+++ b/gtk2_ardour/mixer_ui.cc
@@ -251,7 +251,7 @@ Mixer_UI::show_window ()
}
void
-Mixer_UI::add_strip (Route* route)
+Mixer_UI::add_strip (boost::shared_ptr<Route> route)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &Mixer_UI::add_strip), route));
@@ -261,7 +261,7 @@ Mixer_UI::add_strip (Route* route)
return;
}
- strip = new MixerStrip (*this, *session, *route);
+ strip = new MixerStrip (*this, *session, route);
strips.push_back (strip);
strip->set_width (_strip_width);
@@ -310,7 +310,7 @@ void
Mixer_UI::follow_strip_selection ()
{
for (list<MixerStrip *>::iterator i = strips.begin(); i != strips.end(); ++i) {
- (*i)->set_selected (_selection.selected (&(*i)->route()));
+ (*i)->set_selected (_selection.selected ((*i)->route()));
}
}
@@ -324,13 +324,13 @@ Mixer_UI::strip_button_release_event (GdkEventButton *ev, MixerStrip *strip)
at the same time.
*/
- if (_selection.selected (&strip->route())) {
- _selection.remove (&strip->route());
+ if (_selection.selected (strip->route())) {
+ _selection.remove (strip->route());
} else {
if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
- _selection.add (&strip->route());
+ _selection.add (strip->route());
} else {
- _selection.set (&strip->route());
+ _selection.set (strip->route());
}
}
}
@@ -444,7 +444,7 @@ Mixer_UI::set_all_strips_visibility (bool yn)
continue;
}
- if (strip->route().master() || strip->route().control()) {
+ if (strip->route()->master() || strip->route()->control()) {
continue;
}
@@ -472,11 +472,11 @@ Mixer_UI::set_all_audio_visibility (int tracks, bool yn)
continue;
}
- if (strip->route().master() || strip->route().control()) {
+ if (strip->route()->master() || strip->route()->control()) {
continue;
}
- AudioTrack* at = dynamic_cast<AudioTrack*> (&strip->route());
+ AudioTrack* at = strip->audio_track();
switch (tracks) {
case 0:
@@ -570,11 +570,11 @@ Mixer_UI::redisplay_track_list ()
if (visible) {
strip->set_marked_for_display (true);
- strip->route().set_order_key (N_("signal"), order);
+ strip->route()->set_order_key (N_("signal"), order);
if (strip->packed()) {
- if (strip->route().master() || strip->route().control()) {
+ if (strip->route()->master() || strip->route()->control()) {
out_packer.reorder_child (*strip, -1);
} else {
strip_packer.reorder_child (*strip, -1); /* put at end */
@@ -582,7 +582,7 @@ Mixer_UI::redisplay_track_list ()
} else {
- if (strip->route().master() || strip->route().control()) {
+ if (strip->route()->master() || strip->route()->control()) {
out_packer.pack_start (*strip, false, false);
} else {
strip_packer.pack_start (*strip, false, false);
@@ -593,7 +593,7 @@ Mixer_UI::redisplay_track_list ()
} else {
- if (strip->route().master() || strip->route().control()) {
+ if (strip->route()->master() || strip->route()->control()) {
/* do nothing, these cannot be hidden */
} else {
strip_packer.remove (*strip);
@@ -604,7 +604,7 @@ Mixer_UI::redisplay_track_list ()
}
struct SignalOrderRouteSorter {
- bool operator() (Route* a, Route* b) {
+ bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
/* use of ">" forces the correct sort order */
return a->order_key ("signal") < b->order_key ("signal");
}
@@ -613,16 +613,17 @@ struct SignalOrderRouteSorter {
void
Mixer_UI::initial_track_display ()
{
- Session::RouteList routes = session->get_routes();
+ boost::shared_ptr<Session::RouteList> routes = session->get_routes();
+ Session::RouteList copy (*routes);
SignalOrderRouteSorter sorter;
- routes.sort (sorter);
+ copy.sort (sorter);
no_track_list_redisplay = true;
track_model->clear ();
- for (Session::RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (Session::RouteList::iterator i = copy.begin(); i != copy.end(); ++i) {
add_strip (*i);
}
@@ -670,7 +671,7 @@ Mixer_UI::track_display_button_press (GdkEventButton* ev)
MixerStrip* strip = (*iter)[track_columns.strip];
if (strip) {
- if (!strip->route().master() && !strip->route().control()) {
+ if (!strip->route()->master() && !strip->route()->control()) {
bool visible = (*iter)[track_columns.visible];
(*iter)[track_columns.visible] = !visible;
}
@@ -715,7 +716,7 @@ Mixer_UI::strip_name_changed (void* src, MixerStrip* mx)
for (i = rows.begin(); i != rows.end(); ++i) {
if ((*i)[track_columns.strip] == mx) {
- (*i)[track_columns.text] = mx->route().name();
+ (*i)[track_columns.text] = mx->route()->name();
return;
}
}
diff --git a/gtk2_ardour/mixer_ui.h b/gtk2_ardour/mixer_ui.h
index 5108df6014..6fe4120427 100644
--- a/gtk2_ardour/mixer_ui.h
+++ b/gtk2_ardour/mixer_ui.h
@@ -33,8 +33,9 @@
#include <gtkmm/menu.h>
#include <gtkmm/treeview.h>
+#include <pbd/stateful.h>
+
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
#include <ardour/io.h>
#include "keyboard_target.h"
@@ -110,7 +111,7 @@ class Mixer_UI : public Gtk::Window
bool strip_scroller_button_release (GdkEventButton*);
- void add_strip (ARDOUR::Route*);
+ void add_strip (boost::shared_ptr<ARDOUR::Route>);
void remove_strip (MixerStrip *);
void hide_all_strips (bool with_select);
@@ -193,7 +194,7 @@ class Mixer_UI : public Gtk::Window
}
Gtk::TreeModelColumn<bool> visible;
Gtk::TreeModelColumn<Glib::ustring> text;
- Gtk::TreeModelColumn<ARDOUR::Route*> route;
+ Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route;
Gtk::TreeModelColumn<MixerStrip*> strip;
};
diff --git a/gtk2_ardour/option_editor.cc b/gtk2_ardour/option_editor.cc
index d4c2715742..b7fc7e746e 100644
--- a/gtk2_ardour/option_editor.cc
+++ b/gtk2_ardour/option_editor.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2001 Paul Davis
+ Copyright (C) 2001-2006 Paul Davis
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
@@ -20,6 +20,7 @@
#include <pbd/whitespace.h>
+#include <ardour/audio_library.h>
#include <ardour/session.h>
#include <ardour/audioengine.h>
#include <ardour/configuration.h>
@@ -59,9 +60,7 @@ OptionEditor::OptionEditor (ARDOUR_UI& uip, PublicEditor& ed, Mixer_UI& mixui)
/* Paths */
path_table (11, 2),
- sfdb_path_columns(),
- sfdb_paths(ListStore::create(sfdb_path_columns)),
- sfdb_path_view(sfdb_paths),
+ sfdb_path_view(),
/* Fades */
@@ -163,7 +162,6 @@ OptionEditor::set_session (Session *s)
return;
}
-
click_path_entry.set_sensitive (true);
click_emphasis_path_entry.set_sensitive (true);
session_raid_entry.set_sensitive (true);
@@ -251,13 +249,19 @@ OptionEditor::setup_path_options()
path_table.attach(*label, 0, 1, 2, 3, FILL|EXPAND, FILL);
path_table.attach(sfdb_path_view, 1, 3, 2, 3, Gtk::FILL|Gtk::EXPAND, FILL);
- sfdb_path_view.append_column(_("Paths"), sfdb_path_columns.paths);
- sfdb_path_view.set_size_request(-1, 100);
+ sfdb_path_view.set_paths(Library->get_paths());
+ sfdb_path_view.PathsUpdated.connect (mem_fun(*this, &OptionEditor::sfdb_paths_changed));
path_table.show_all();
}
void
+OptionEditor::sfdb_paths_changed ()
+{
+ Library->set_paths (sfdb_path_view.get_paths());
+}
+
+void
OptionEditor::add_session_paths ()
{
click_path_entry.set_sensitive (true);
diff --git a/gtk2_ardour/option_editor.h b/gtk2_ardour/option_editor.h
index b9690b02e2..1331d3126e 100644
--- a/gtk2_ardour/option_editor.h
+++ b/gtk2_ardour/option_editor.h
@@ -33,6 +33,8 @@
#include <gtkmm/radiobutton.h>
#include <gtkmm/comboboxtext.h>
+#include <gtkmm2ext/pathlist.h>
+
#include <ardour/session.h>
#include "ardour_dialog.h"
@@ -70,24 +72,16 @@ class OptionEditor : public Gtk::Dialog
/* paths */
- Gtk::Table path_table;
- Gtk::Entry session_raid_entry;
-
- struct SoundFilePathColumns : public Gtk::TreeModel::ColumnRecord {
- public:
- SoundFilePathColumns() { add (paths); }
- Gtk::TreeModelColumn<std::string> paths;
-
- };
+ Gtk::Table path_table;
+ Gtk::Entry session_raid_entry;
- SoundFilePathColumns sfdb_path_columns;
- Glib::RefPtr<Gtk::ListStore> sfdb_paths;
- Gtk::TreeView sfdb_path_view;
+ Gtkmm2ext::PathList sfdb_path_view;
void setup_path_options();
void add_session_paths ();
void remove_session_paths ();
void raid_path_changed ();
+ void sfdb_paths_changed ();
/* fades */
diff --git a/gtk2_ardour/pan_automation_time_axis.cc b/gtk2_ardour/pan_automation_time_axis.cc
index 73d0f7f1aa..3169f65059 100644
--- a/gtk2_ardour/pan_automation_time_axis.cc
+++ b/gtk2_ardour/pan_automation_time_axis.cc
@@ -28,6 +28,7 @@
#include "pan_automation_time_axis.h"
#include "automation_line.h"
#include "canvas_impl.h"
+#include "route_ui.h"
#include "i18n.h"
@@ -35,11 +36,15 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
-PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n)
+PanAutomationTimeAxisView::PanAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r, PublicEditor& e,
+ TimeAxisView& parent, Canvas& canvas, std::string n)
: AxisView (s),
AutomationTimeAxisView (s, r, e, parent, canvas, n, X_("pan"), "")
{
+ multiline_selector.set_name ("PanAutomationLineSelector");
+
+ controls_table.attach (multiline_selector, 1, 5, 1, 2, Gtk::EXPAND, Gtk::EXPAND);
}
PanAutomationTimeAxisView::~PanAutomationTimeAxisView ()
@@ -54,14 +59,19 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
return;
}
+ int line_index = 0;
+
if (lines.size() > 1) {
+ line_index = multiline_selector.get_active_row_number();
- Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true);
-
- msg->set_text (_("You can't graphically edit panning of more than stream"));
- msg->touch ();
+ if (line_index < 0 || line_index >= (int)lines.size()) {
+ Gtkmm2ext::PopUp* msg = new Gtkmm2ext::PopUp (Gtk::WIN_POS_MOUSE, 5000, true);
- return;
+ msg->set_text (_("You need to select which line to edit"));
+ msg->touch ();
+
+ return;
+ }
}
double x = 0;
@@ -76,7 +86,7 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
lines.front()->view_to_model_y (y);
- AutomationList& alist (lines.front()->the_list());
+ AutomationList& alist (lines[line_index]->the_list());
_session.begin_reversible_command (_("add pan automation event"));
XMLNode &before = alist.get_state();
@@ -88,9 +98,56 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
}
void
+PanAutomationTimeAxisView::clear_lines ()
+{
+ AutomationTimeAxisView::clear_lines();
+ multiline_selector.clear();
+}
+
+void
+PanAutomationTimeAxisView::add_line (AutomationLine& line)
+{
+ char buf[32];
+ snprintf(buf,32,"Line %u",lines.size()+1);
+ multiline_selector.append_text(buf);
+
+ if (lines.empty()) {
+ multiline_selector.set_active(0);
+ }
+
+ if (lines.size() + 1 > 1 && (height_style != Small && height_style != Smaller)) {
+ multiline_selector.show();
+ } else {
+ multiline_selector.hide();
+
+ }
+
+ AutomationTimeAxisView::add_line(line);
+}
+
+void
+PanAutomationTimeAxisView::set_height (TimeAxisView::TrackHeight th)
+{
+ AutomationTimeAxisView::set_height(th);
+
+ switch (th) {
+ case Largest:
+ case Large:
+ case Larger:
+ case Normal:
+ if (lines.size() > 1) {
+ multiline_selector.show();
+ break;
+ }
+ default:
+ multiline_selector.hide();
+ }
+}
+
+void
PanAutomationTimeAxisView::set_automation_state (AutoState state)
{
if (!ignore_state_request) {
- route.panner().set_automation_state (state);
+ route->panner().set_automation_state (state);
}
}
diff --git a/gtk2_ardour/pan_automation_time_axis.h b/gtk2_ardour/pan_automation_time_axis.h
index b35ee67735..ca4a4db8e7 100644
--- a/gtk2_ardour/pan_automation_time_axis.h
+++ b/gtk2_ardour/pan_automation_time_axis.h
@@ -4,27 +4,36 @@
#include "canvas.h"
#include "automation_time_axis.h"
+#include <gtkmm/comboboxtext.h>
+
namespace ARDOUR {
class Redirect;
}
class PanAutomationTimeAxisView : public AutomationTimeAxisView
{
- public:
- PanAutomationTimeAxisView (ARDOUR::Session&,
- ARDOUR::Route&,
- PublicEditor&,
- TimeAxisView& parent_axis,
- ArdourCanvas::Canvas& canvas,
- std::string name);
-
- ~PanAutomationTimeAxisView();
-
- void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double);
-
- private:
- void automation_changed ();
- void set_automation_state (ARDOUR::AutoState);
+ public:
+ PanAutomationTimeAxisView (ARDOUR::Session&,
+ boost::shared_ptr<ARDOUR::Route>,
+ PublicEditor&,
+ TimeAxisView& parent_axis,
+ ArdourCanvas::Canvas& canvas,
+ std::string name);
+
+ ~PanAutomationTimeAxisView();
+
+ void add_automation_event (ArdourCanvas::Item *item, GdkEvent *event, jack_nframes_t, double);
+
+ void clear_lines ();
+ void add_line (AutomationLine&);
+ void set_height (TimeAxisView::TrackHeight);
+
+ protected:
+ Gtk::ComboBoxText multiline_selector;
+
+ private:
+ void automation_changed ();
+ void set_automation_state (ARDOUR::AutoState);
};
#endif /* __ardour_gtk_pan_automation_time_axis_h__ */
diff --git a/gtk2_ardour/panner_ui.cc b/gtk2_ardour/panner_ui.cc
index 63a19867a8..ccce2ec9f1 100644
--- a/gtk2_ardour/panner_ui.cc
+++ b/gtk2_ardour/panner_ui.cc
@@ -14,8 +14,6 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
*/
#include <limits.h>
@@ -47,7 +45,7 @@ using namespace Gtk;
using namespace sigc;
-PannerUI::PannerUI (IO& io, Session& s)
+PannerUI::PannerUI (boost::shared_ptr<IO> io, Session& s)
: _io (io),
_session (s),
hAdjustment(0.0, 0.0, 0.0),
@@ -87,13 +85,13 @@ PannerUI::PannerUI (IO& io, Session& s)
using namespace Menu_Helpers;
pan_astate_menu.items().push_back (MenuElem (_("Off"),
- bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Off)));
+ bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Off)));
pan_astate_menu.items().push_back (MenuElem (_("Play"),
- bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Play)));
+ bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Play)));
pan_astate_menu.items().push_back (MenuElem (_("Write"),
- bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Write)));
+ bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Write)));
pan_astate_menu.items().push_back (MenuElem (_("Touch"),
- bind (mem_fun (_io.panner(), &Panner::set_automation_state), (AutoState) Touch)));
+ bind (mem_fun (_io->panner(), &Panner::set_automation_state), (AutoState) Touch)));
pan_astyle_menu.items().push_back (MenuElem (_("Trim")));
pan_astyle_menu.items().push_back (MenuElem (_("Abs")));
@@ -143,9 +141,9 @@ PannerUI::PannerUI (IO& io, Session& s)
set_width(Narrow);
- _io.panner().Changed.connect (mem_fun(*this, &PannerUI::panner_changed));
- _io.panner().LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage));
- _io.panner().StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state));
+ _io->panner().Changed.connect (mem_fun(*this, &PannerUI::panner_changed));
+ _io->panner().LinkStateChanged.connect (mem_fun(*this, &PannerUI::update_pan_linkage));
+ _io->panner().StateChanged.connect (mem_fun(*this, &PannerUI::update_pan_state));
pan_changed (0);
update_pan_sensitive ();
@@ -165,7 +163,7 @@ PannerUI::panning_link_button_release (GdkEventButton* ev)
{
cerr << "link release\n";
if (!ignore_toggle) {
- _io.panner().set_linked (!_io.panner().linked());
+ _io->panner().set_linked (!_io->panner().linked());
}
return true;
}
@@ -173,12 +171,12 @@ PannerUI::panning_link_button_release (GdkEventButton* ev)
void
PannerUI::panning_link_direction_clicked()
{
- switch (_io.panner().link_direction()) {
+ switch (_io->panner().link_direction()) {
case Panner::SameDirection:
- _io.panner().set_link_direction (Panner::OppositeDirection);
+ _io->panner().set_link_direction (Panner::OppositeDirection);
break;
default:
- _io.panner().set_link_direction (Panner::SameDirection);
+ _io->panner().set_link_direction (Panner::SameDirection);
break;
}
}
@@ -188,7 +186,7 @@ PannerUI::update_pan_linkage ()
{
ENSURE_GUI_THREAD(mem_fun(*this, &PannerUI::update_pan_linkage));
- bool x = _io.panner().linked();
+ bool x = _io->panner().linked();
bool bx = panning_link_button.get_active();
if (x != bx) {
@@ -200,7 +198,7 @@ PannerUI::update_pan_linkage ()
panning_link_direction_button.set_sensitive (x);
- switch (_io.panner().link_direction()) {
+ switch (_io->panner().link_direction()) {
case Panner::SameDirection:
panning_link_direction_button.set_image (*(manage (new Image (get_xpm ("forwardblarrow.xpm")))));
break;
@@ -278,7 +276,7 @@ PannerUI::update_pan_state ()
void
PannerUI::setup_pan ()
{
- uint32_t nouts = _io.n_outputs ();
+ uint32_t nouts = _io->n_outputs ();
if (nouts == 0 || nouts == 1) {
@@ -292,7 +290,7 @@ PannerUI::setup_pan ()
} else if (nouts == 2) {
vector<Adjustment*>::size_type asz;
- uint32_t npans = _io.panner().size();
+ uint32_t npans = _io->panner().size();
while (!pan_adjustments.empty()) {
delete pan_bars.back();
@@ -308,34 +306,26 @@ PannerUI::setup_pan ()
/* initialize adjustment with current value of panner */
- _io.panner()[asz]->get_position (x);
+ _io->panner()[asz]->get_position (x);
pan_adjustments.push_back (new Adjustment (x, 0, 1.0, 0.05, 0.1));
pan_adjustments.back()->signal_value_changed().connect (bind (mem_fun(*this, &PannerUI::pan_adjustment_changed), (uint32_t) asz));
- _io.panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
+ _io->panner()[asz]->Changed.connect (bind (mem_fun(*this, &PannerUI::pan_value_changed), (uint32_t) asz));
bc = new BarController (*pan_adjustments[asz],
- &_io.panner()[asz]->midi_control(),
+ _io->panner()[asz]->control(),
bind (mem_fun(*this, &PannerUI::pan_printer), pan_adjustments[asz]));
- if (_session.midi_port()) {
- _io.panner()[asz]->reset_midi_control (_session.midi_port(), true);
- }
-
bc->set_name ("PanSlider");
bc->set_shadow_type (Gtk::SHADOW_NONE);
bc->set_style (BarController::Line);
- bc->StartGesture.connect (bind (mem_fun (_io, &IO::start_pan_touch), (uint32_t) asz));
- bc->StopGesture.connect (bind (mem_fun (_io, &IO::end_pan_touch), (uint32_t) asz));
+ bc->StartGesture.connect (bind (mem_fun (*_io, &IO::start_pan_touch), (uint32_t) asz));
+ bc->StopGesture.connect (bind (mem_fun (*_io, &IO::end_pan_touch), (uint32_t) asz));
char buf[64];
-#ifdef __APPLE__
- snprintf (buf, sizeof (buf), _("panner for channel %lu"), asz + 1);
-#else
- snprintf (buf, sizeof (buf), _("panner for channel %u"), asz + 1);
-#endif
+ snprintf (buf, sizeof (buf), _("panner for channel %zu"), asz + 1);
ARDOUR_UI::instance()->tooltips().set_tip (bc->event_widget(), buf);
bc->event_widget().signal_button_release_event().connect
@@ -379,13 +369,13 @@ PannerUI::setup_pan ()
}
if (panner == 0) {
- panner = new Panner2d (_io.panner(), w, 61);
+ panner = new Panner2d (_io->panner(), w, 61);
panner->set_name ("MixerPanZone");
panner->show ();
}
update_pan_sensitive ();
- panner->reset (_io.n_inputs());
+ panner->reset (_io->n_inputs());
panner->set_size_request (w, 61);
/* and finally, add it to the panner frame */
@@ -428,7 +418,7 @@ PannerUI::build_pan_menu (uint32_t which)
/* set state first, connect second */
- (dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io.panner()[which]->muted());
+ (dynamic_cast<CheckMenuItem*> (&items.back()))->set_active (_io->panner()[which]->muted());
(dynamic_cast<CheckMenuItem*> (&items.back()))->signal_toggled().connect
(bind (mem_fun(*this, &PannerUI::pan_mute), which));
@@ -437,7 +427,7 @@ PannerUI::build_pan_menu (uint32_t which)
/* set state first, connect second */
- bypass_menu_item->set_active (_io.panner().bypassed());
+ bypass_menu_item->set_active (_io->panner().bypassed());
bypass_menu_item->signal_toggled().connect (mem_fun(*this, &PannerUI::pan_bypass_toggle));
items.push_back (MenuElem (_("Reset"), mem_fun(*this, &PannerUI::pan_reset)));
@@ -448,15 +438,15 @@ PannerUI::build_pan_menu (uint32_t which)
void
PannerUI::pan_mute (uint32_t which)
{
- StreamPanner* sp = _io.panner()[which];
+ StreamPanner* sp = _io->panner()[which];
sp->set_muted (!sp->muted());
}
void
PannerUI::pan_bypass_toggle ()
{
- if (bypass_menu_item && (_io.panner().bypassed() != bypass_menu_item->get_active())) {
- _io.panner().set_bypassed (!_io.panner().bypassed());
+ if (bypass_menu_item && (_io->panner().bypassed() != bypass_menu_item->get_active())) {
+ _io->panner().set_bypassed (!_io->panner().bypassed());
}
}
@@ -468,11 +458,11 @@ PannerUI::pan_reset ()
void
PannerUI::effective_pan_display ()
{
- if (_io.panner().empty()) {
+ if (_io->panner().empty()) {
return;
}
- switch (_io.n_outputs()) {
+ switch (_io->n_outputs()) {
case 0:
case 1:
/* relax */
@@ -495,7 +485,7 @@ PannerUI::pan_changed (void *src)
return;
}
- switch (_io.panner().size()) {
+ switch (_io->panner().size()) {
case 0:
panning_link_direction_button.set_sensitive (false);
panning_link_button.set_sensitive (false);
@@ -509,7 +499,7 @@ PannerUI::pan_changed (void *src)
panning_link_button.set_sensitive (true);
}
- uint32_t nouts = _io.n_outputs();
+ uint32_t nouts = _io->n_outputs();
switch (nouts) {
case 0:
@@ -530,11 +520,11 @@ PannerUI::pan_changed (void *src)
void
PannerUI::pan_adjustment_changed (uint32_t which)
{
- if (!in_pan_update && which < _io.panner().size()) {
+ if (!in_pan_update && which < _io->panner().size()) {
float xpos;
float val = pan_adjustments[which]->get_value ();
- _io.panner()[which]->get_position (xpos);
+ _io->panner()[which]->get_position (xpos);
/* add a kinda-sorta detent for the middle */
@@ -551,7 +541,7 @@ PannerUI::pan_adjustment_changed (uint32_t which)
if (!Panner::equivalent (val, xpos)) {
- _io.panner()[which]->set_position (val);
+ _io->panner()[which]->set_position (val);
/* XXX
the panner objects have no access to the session,
so do this here. ick.
@@ -566,11 +556,11 @@ PannerUI::pan_value_changed (uint32_t which)
{
ENSURE_GUI_THREAD (bind (mem_fun(*this, &PannerUI::pan_value_changed), which));
- if (_io.n_outputs() > 1 && which < _io.panner().size()) {
+ if (_io->n_outputs() > 1 && which < _io->panner().size()) {
float xpos;
float val = pan_adjustments[which]->get_value ();
- _io.panner()[which]->get_position (xpos);
+ _io->panner()[which]->get_position (xpos);
if (!Panner::equivalent (val, xpos)) {
in_pan_update = true;
@@ -596,14 +586,14 @@ PannerUI::update_pan_bars (bool only_if_aplay)
float xpos, val;
if (only_if_aplay) {
- AutomationList& alist (_io.panner()[n]->automation());
+ AutomationList& alist (_io->panner()[n]->automation());
if (!alist.automation_playback()) {
continue;
}
}
- _io.panner()[n]->get_effective_position (xpos);
+ _io->panner()[n]->get_effective_position (xpos);
val = (*i)->get_value ();
if (!Panner::equivalent (val, xpos)) {
@@ -634,9 +624,9 @@ PannerUI::pan_printer (char *buf, uint32_t len, Adjustment* adj)
void
PannerUI::update_pan_sensitive ()
{
- bool sensitive = !(_io.panner().automation_state() & Play);
+ bool sensitive = !(_io->panner().automation_state() & Play);
- switch (_io.n_outputs()) {
+ switch (_io->n_outputs()) {
case 0:
case 1:
break;
@@ -697,10 +687,10 @@ PannerUI::pan_automation_style_changed ()
switch (_width) {
case Wide:
- pan_automation_style_button.set_label (astyle_string(_io.panner().automation_style()));
+ pan_automation_style_button.set_label (astyle_string(_io->panner().automation_style()));
break;
case Narrow:
- pan_automation_style_button.set_label (short_astyle_string(_io.panner().automation_style()));
+ pan_automation_style_button.set_label (short_astyle_string(_io->panner().automation_style()));
break;
}
}
@@ -714,10 +704,10 @@ PannerUI::pan_automation_state_changed ()
switch (_width) {
case Wide:
- pan_automation_state_button.set_label (astate_string(_io.panner().automation_state()));
+ pan_automation_state_button.set_label (astate_string(_io->panner().automation_state()));
break;
case Narrow:
- pan_automation_state_button.set_label (short_astate_string(_io.panner().automation_state()));
+ pan_automation_state_button.set_label (short_astate_string(_io->panner().automation_state()));
break;
}
@@ -726,11 +716,11 @@ PannerUI::pan_automation_state_changed ()
here.
*/
- if (_io.panner().empty()) {
+ if (_io->panner().empty()) {
return;
}
- x = (_io.panner().front()->automation().automation_state() != Off);
+ x = (_io->panner().front()->automation().automation_state() != Off);
if (pan_automation_state_button.get_active() != x) {
ignore_toggle = true;
diff --git a/gtk2_ardour/panner_ui.h b/gtk2_ardour/panner_ui.h
index 80b14465cf..7658978233 100644
--- a/gtk2_ardour/panner_ui.h
+++ b/gtk2_ardour/panner_ui.h
@@ -31,8 +31,8 @@
#include <gtkmm/togglebutton.h>
#include <gtkmm/button.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/click_box.h>
+#include <gtkmm2ext/slider_controller.h>
#include "enums.h"
@@ -55,7 +55,7 @@ namespace Gtk {
class PannerUI : public Gtk::HBox
{
public:
- PannerUI (ARDOUR::IO&, ARDOUR::Session&);
+ PannerUI (boost::shared_ptr<ARDOUR::IO>, ARDOUR::Session&);
~PannerUI ();
void pan_changed (void *);
@@ -72,7 +72,7 @@ class PannerUI : public Gtk::HBox
private:
friend class MixerStrip;
- ARDOUR::IO& _io;
+ boost::shared_ptr<ARDOUR::IO> _io;
ARDOUR::Session& _session;
bool ignore_toggle;
diff --git a/gtk2_ardour/pixmaps/tool_audition.xpm b/gtk2_ardour/pixmaps/tool_audition.xpm
new file mode 100644
index 0000000000..d6f2ccd127
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_audition.xpm
@@ -0,0 +1,19 @@
+/* XPM */
+static char * tool_audition_xpm[] = {
+"16 12 4 1",
+" c None",
+". c #000000",
+"+ c #ECECEC",
+"@ c #FFFFFF",
+" .. ",
+" .+. . ",
+" .++. .@. ",
+"....+@+... .@. ",
+".+++@@+..@. .@.",
+".+@@@@+. .@. .@.",
+".+@@@@+. .@. .@.",
+".+++@@+..@. .@.",
+"....+@+... .@. ",
+" .++. .@. ",
+" .+. . ",
+" .. "};
diff --git a/gtk2_ardour/pixmaps/tool_gain.xpm b/gtk2_ardour/pixmaps/tool_gain.xpm
new file mode 100644
index 0000000000..480426fab8
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_gain.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * tool_gain_xpm[] = {
+"16 12 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"... ",
+".++.. ",
+"...++. ",
+" ..+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+.. ",
+" .++.....",
+" ..++++.",
+" ....."};
diff --git a/gtk2_ardour/pixmaps/tool_object.xpm b/gtk2_ardour/pixmaps/tool_object.xpm
new file mode 100644
index 0000000000..3d18ab8af7
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_object.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * tool_object_xpm[] = {
+"16 12 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+" ... ",
+" .+. ",
+" .+. ",
+" .+. ",
+" .+..... ",
+" .+.+.+... ",
+" ...+.+.+.+. ",
+" .+.+++++++. ",
+" .+++++++++. ",
+" ..+++++++.. ",
+" ...+++++. ",
+" .+++++. "};
diff --git a/gtk2_ardour/pixmaps/tool_range.xpm b/gtk2_ardour/pixmaps/tool_range.xpm
new file mode 100644
index 0000000000..75ee865ca2
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_range.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * tool_range_xpm[] = {
+"16 12 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+"... ...",
+".+. .. .. .+.",
+".+. .+. .+. .+.",
+".+..+. .+..+.",
+".+.++......++.+.",
+".++++++++++++++.",
+".+.++......++.+.",
+".+..+. .+..+.",
+".+. .+. .+. .+.",
+".+. .. .. .+.",
+".+. .+.",
+"... ..."};
diff --git a/gtk2_ardour/pixmaps/tool_stretch.xpm b/gtk2_ardour/pixmaps/tool_stretch.xpm
new file mode 100644
index 0000000000..77943cd7d4
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_stretch.xpm
@@ -0,0 +1,18 @@
+/* XPM */
+static char * tool_stretch_xpm[] = {
+"16 12 3 1",
+" c None",
+". c #000000",
+"+ c #FFFFFF",
+" .. .. ",
+" .+. .+. ",
+".++..........++.",
+"++++++++++++++++",
+".++..........++.",
+" .+. .+. ",
+" .. .. ",
+" + + + + ",
+" ++ +++ + + +++ ",
+"++++++++++++++++",
+" ++ + ++ + + ",
+" + + + + "};
diff --git a/gtk2_ardour/pixmaps/tool_zoom.xpm b/gtk2_ardour/pixmaps/tool_zoom.xpm
new file mode 100644
index 0000000000..581363f3f4
--- /dev/null
+++ b/gtk2_ardour/pixmaps/tool_zoom.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * tool_zoom_xpm[] = {
+"16 12 14 1",
+" c None",
+". c #000000",
+"+ c #474747",
+"@ c #E7E7E7",
+"# c #F6F6F6",
+"$ c #DCDCDC",
+"% c #FFFFFF",
+"& c #DFDFDF",
+"* c #D7D7D7",
+"= c #D6D6D6",
+"- c #040404",
+"; c #070707",
+"> c #060606",
+", c #050505",
+" ... ",
+" +.@#$.+ ",
+" .%%%%%. ",
+" .&%%%%%*. ",
+" .#%%%%%#. ",
+" .$%%%%%&. ",
+" .%%%%%.+ ",
+" +.*#=... ",
+" ...+... ",
+" -.; ",
+" >.- ",
+" ,. "};
diff --git a/gtk2_ardour/pixmaps/zoom_full.xpm b/gtk2_ardour/pixmaps/zoom_full.xpm
new file mode 100644
index 0000000000..5564074875
--- /dev/null
+++ b/gtk2_ardour/pixmaps/zoom_full.xpm
@@ -0,0 +1,30 @@
+/* XPM */
+static char * zoom_full_xpm[] = {
+"12 12 15 1",
+" c None",
+". c #000000",
+"+ c #474747",
+"@ c #E7E7E7",
+"# c #F6F6F6",
+"$ c #DCDCDC",
+"% c #ACACAC",
+"& c #FFFFFF",
+"* c #DFDFDF",
+"= c #D7D7D7",
+"- c #D6D6D6",
+"; c #040404",
+"> c #070707",
+", c #060606",
+"' c #050505",
+" ... ",
+" +.@#$.+ ",
+" .%&&&%. ",
+".*..&..=. ",
+".#.&&&.#. ",
+".$..&..*. ",
+" .%&&&%.+ ",
+" +.=#-... ",
+" ...+... ",
+" ;.> ",
+" ,.;",
+" '."};
diff --git a/gtk2_ardour/pixmaps/zoom_in.xpm b/gtk2_ardour/pixmaps/zoom_in.xpm
new file mode 100644
index 0000000000..1f8d4e8273
--- /dev/null
+++ b/gtk2_ardour/pixmaps/zoom_in.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * zoom_in_xpm[] = {
+"12 12 14 1",
+" c None",
+". c #000000",
+"+ c #474747",
+"@ c #E7E7E7",
+"# c #F6F6F6",
+"$ c #DCDCDC",
+"% c #FFFFFF",
+"& c #DFDFDF",
+"* c #D7D7D7",
+"= c #D6D6D6",
+"- c #040404",
+"; c #070707",
+"> c #060606",
+", c #050505",
+" ... ",
+" +.@#$.+ ",
+" .%%.%%. ",
+".&%%.%%*. ",
+".#.....#. ",
+".$%%.%%&. ",
+" .%%.%%.+ ",
+" +.*#=... ",
+" ...+... ",
+" -.; ",
+" >.-",
+" ,."};
diff --git a/gtk2_ardour/pixmaps/zoom_out.xpm b/gtk2_ardour/pixmaps/zoom_out.xpm
new file mode 100644
index 0000000000..ea50d145ad
--- /dev/null
+++ b/gtk2_ardour/pixmaps/zoom_out.xpm
@@ -0,0 +1,29 @@
+/* XPM */
+static char * zoom_out_xpm[] = {
+"12 12 14 1",
+" c None",
+". c #000000",
+"+ c #474747",
+"@ c #E7E7E7",
+"# c #F6F6F6",
+"$ c #DCDCDC",
+"% c #FFFFFF",
+"& c #DFDFDF",
+"* c #D7D7D7",
+"= c #D6D6D6",
+"- c #040404",
+"; c #070707",
+"> c #060606",
+", c #050505",
+" ... ",
+" +.@#$.+ ",
+" .%%%%%. ",
+".&%%%%%*. ",
+".#.....#. ",
+".$%%%%%&. ",
+" .%%%%%.+ ",
+" +.*#=... ",
+" ...+... ",
+" -.; ",
+" >.-",
+" ,."};
diff --git a/gtk2_ardour/playlist_selector.cc b/gtk2_ardour/playlist_selector.cc
index f1a975d5dc..8eaac7cb9d 100644
--- a/gtk2_ardour/playlist_selector.cc
+++ b/gtk2_ardour/playlist_selector.cc
@@ -90,13 +90,13 @@ void
PlaylistSelector::show_for (RouteUI* ruix)
{
vector<const char*> item;
- AudioDiskstream* this_ds;
+ Diskstream* this_ds;
string str;
rui = ruix;
str = _("ardour: playlist for ");
- str += rui->route().name();
+ str += rui->route()->name();
set_title (str);
@@ -116,7 +116,7 @@ PlaylistSelector::show_for (RouteUI* ruix)
for (DSPL_Map::iterator x = dspl_map.begin(); x != dspl_map.end(); ++x) {
- AudioDiskstream* ds = session->diskstream_by_id (x->first);
+ Diskstream* ds = session->diskstream_by_id (x->first);
if (ds == 0) {
continue;
@@ -189,7 +189,7 @@ PlaylistSelector::add_playlist_to_map (Playlist *pl)
if ((x = dspl_map.find (apl->get_orig_diskstream_id())) == dspl_map.end()) {
- pair<ARDOUR::id_t,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>);
+ pair<PBD::ID,list<Playlist*>*> newp (apl->get_orig_diskstream_id(), new list<Playlist*>);
x = dspl_map.insert (dspl_map.end(), newp);
}
@@ -223,7 +223,7 @@ PlaylistSelector::selection_changed ()
TreeModel::iterator iter = tree.get_selection()->get_selected();
- if (!iter) {
+ if (!iter || rui == 0) {
/* nothing selected */
return;
}
@@ -233,7 +233,7 @@ PlaylistSelector::selection_changed ()
AudioTrack* at;
AudioPlaylist* apl;
- if ((at = dynamic_cast<AudioTrack*> (&rui->route())) == 0) {
+ if ((at = rui->audio_track()) == 0) {
/* eh? */
return;
}
@@ -243,7 +243,7 @@ PlaylistSelector::selection_changed ()
return;
}
- at->disk_stream().use_playlist (apl);
+ at->diskstream().use_playlist (apl);
hide ();
}
diff --git a/gtk2_ardour/playlist_selector.h b/gtk2_ardour/playlist_selector.h
index 863d6cc7f3..2829ba54bb 100644
--- a/gtk2_ardour/playlist_selector.h
+++ b/gtk2_ardour/playlist_selector.h
@@ -46,7 +46,7 @@ class PlaylistSelector : public ArdourDialog
void show_for (RouteUI*);
private:
- typedef std::map<ARDOUR::id_t,std::list<ARDOUR::Playlist*>*> DSPL_Map;
+ typedef std::map<PBD::ID,std::list<ARDOUR::Playlist*>*> DSPL_Map;
ARDOUR::Session* session;
Gtk::ScrolledWindow scroller;
diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc
index 16796df160..e0a62b177f 100644
--- a/gtk2_ardour/plugin_selector.cc
+++ b/gtk2_ardour/plugin_selector.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -48,8 +48,8 @@ PluginSelector::PluginSelector (PluginManager *mgr)
manager = mgr;
session = 0;
- o_selected_plug = -1;
- i_selected_plug = 0;
+
+ current_selection = PluginInfo::LADSPA;
lmodel = Gtk::ListStore::create(lcols);
ladspa_display.set_model (lmodel);
@@ -91,6 +91,25 @@ PluginSelector::PluginSelector (PluginManager *mgr)
column->set_sort_column(i);
}
#endif
+
+#ifdef HAVE_COREAUDIO
+ aumodel = ListStore::create(aucols);
+ au_display.set_model (aumodel);
+ au_display.append_column (_("Available plugins"), aucols.name);
+ au_display.append_column (_("# Inputs"), aucols.ins);
+ au_display.append_column (_("# Outputs"), aucols.outs);
+ au_display.set_headers_visible (true);
+ au_display.set_reorderable (false);
+ auscroller.set_border_width(10);
+ auscroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ auscroller.add(au_display);
+
+ for (int i = 0; i <=2; i++) {
+ Gtk::TreeView::Column* column = au_display.get_column(i);
+ column->set_sort_column(i);
+ }
+#endif
+
ascroller.set_border_width(10);
ascroller.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
ascroller.add(added_list);
@@ -124,35 +143,51 @@ PluginSelector::PluginSelector (PluginManager *mgr)
using namespace Gtk::Notebook_Helpers;
notebook.pages().push_back (TabElem (lscroller, _("LADSPA")));
+
#ifdef VST_SUPPORT
if (Config->get_use_vst()) {
notebook.pages().push_back (TabElem (vscroller, _("VST")));
}
#endif
+#ifdef HAVE_COREAUDIO
+ notebook.pages().push_back (TabElem (auscroller, _("AudioUnit")));
+#endif
+
table->set_name("PluginSelectorTable");
ladspa_display.set_name("PluginSelectorDisplay");
//ladspa_display.set_name("PluginSelectorList");
added_list.set_name("PluginSelectorList");
ladspa_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
+ ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed));
+
#ifdef VST_SUPPORT
if (Config->get_use_vst()) {
vst_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
vst_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::vst_display_selection_changed));
}
#endif
-
+
+#ifdef HAVE_COREAUDIO
+ au_display.signal_button_press_event().connect_notify (mem_fun(*this, &PluginSelector::row_clicked));
+ au_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::au_display_selection_changed));
+#endif
+
btn_update->signal_clicked().connect (mem_fun(*this, &PluginSelector::btn_update_clicked));
btn_add->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_add_clicked));
btn_remove->signal_clicked().connect(mem_fun(*this, &PluginSelector::btn_remove_clicked));
- ladspa_display.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::ladspa_display_selection_changed));
added_list.get_selection()->signal_changed().connect (mem_fun(*this, &PluginSelector::added_list_selection_changed));
input_refiller ();
+
#ifdef VST_SUPPORT
vst_refiller ();
#endif
+
+#ifdef HAVE_COREAUDIO
+ au_refiller ();
+#endif
}
void
@@ -189,13 +224,11 @@ void
PluginSelector::input_refiller ()
{
guint row;
- list<PluginInfo *> &plugs = manager->ladspa_plugin_info ();
- list<PluginInfo *>::iterator i;
+ PluginInfoList &plugs = manager->ladspa_plugin_info ();
+ PluginInfoList::iterator i;
char ibuf[16], obuf[16];
lmodel->clear();
-#ifdef VST_SUPPORT
- vmodel->clear();
-#endif
+
// Insert into GTK list
for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
@@ -224,9 +257,10 @@ void
PluginSelector::vst_refiller ()
{
guint row;
- list<PluginInfo *> &plugs = manager->vst_plugin_info ();
- list<PluginInfo *>::iterator i;
+ PluginInfoList &plugs = manager->vst_plugin_info ();
+ PluginInfoList::iterator i;
char ibuf[16], obuf[16];
+ vmodel->clear();
// Insert into GTK list
for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
@@ -242,18 +276,75 @@ PluginSelector::vst_refiller ()
}
vmodel->set_sort_column (0, Gtk::SORT_ASCENDING);
}
-#endif
void
-PluginSelector::use_plugin (PluginInfo* pi)
+PluginSelector::vst_display_selection_changed()
{
- list<PluginInfo *>::iterator i;
+ if (vst_display.get_selection()->count_selected_rows() != 0) {
+ btn_add->set_sensitive (true);
+ } else {
+ btn_add->set_sensitive (false);
+ }
+
+ current_selection = PluginInfo::VST;
+}
+
+#endif //VST_SUPPORT
- if (pi == 0 || session == 0) {
+#ifdef HAVE_COREAUDIO
+
+void
+PluginSelector::_au_refiller (void *arg)
+{
+ ((PluginSelector *) arg)->au_refiller ();
+}
+
+void
+PluginSelector::au_refiller ()
+{
+ guint row;
+ PluginInfoList plugs (AUPluginInfo::discover ());
+ PluginInfoList::iterator i;
+ char ibuf[16], obuf[16];
+ aumodel->clear();
+
+ // Insert into GTK list
+ for (row = 0, i=plugs.begin(); i != plugs.end(); ++i, ++row) {
+
+ snprintf (ibuf, sizeof(ibuf)-1, "%d", (*i)->n_inputs);
+ snprintf (obuf, sizeof(obuf)-1, "%d", (*i)->n_outputs);
+
+ Gtk::TreeModel::Row newrow = *(aumodel->append());
+ newrow[aucols.name] = (*i)->name.c_str();
+ newrow[aucols.ins] = ibuf;
+ newrow[aucols.outs] = obuf;
+ newrow[aucols.plugin] = *i;
+ }
+ aumodel->set_sort_column (0, Gtk::SORT_ASCENDING);
+}
+
+void
+PluginSelector::au_display_selection_changed()
+{
+ if (au_display.get_selection()->count_selected_rows() != 0) {
+ btn_add->set_sensitive (true);
+ } else {
+ btn_add->set_sensitive (false);
+ }
+
+ current_selection = PluginInfo::AudioUnit;
+}
+
+#endif //HAVE_COREAUDIO
+
+void
+PluginSelector::use_plugin (PluginInfoPtr pi)
+{
+ if (session == 0) {
return;
}
- Plugin *plugin = manager->load (*session, pi);
+ PluginPtr plugin = pi->load (*session);
if (plugin) {
PluginCreated (plugin);
@@ -263,46 +354,54 @@ PluginSelector::use_plugin (PluginInfo* pi)
void
PluginSelector::btn_add_clicked()
{
- bool vst = notebook.get_current_page(); // 0 = LADSPA, 1 = VST
std::string name;
- ARDOUR::PluginInfo *pi;
+ PluginInfoPtr pi;
Gtk::TreeModel::Row newrow = *(amodel->append());
- if (vst) {
+ Gtk::TreeModel::Row row;
+
+ switch (current_selection) {
+ case PluginInfo::LADSPA:
+ row = *(ladspa_display.get_selection()->get_selected());
+ name = row[lcols.name];
+ pi = row[lcols.plugin];
+ break;
+ case PluginInfo::VST:
#ifdef VST_SUPPORT
- Gtk::TreeModel::Row row = *(vst_display.get_selection()->get_selected());
- name = row[vcols.name];
- pi = row[vcols.plugin];
- added_plugins.push_back (row[vcols.plugin]);
+ row = *(vst_display.get_selection()->get_selected());
+ name = row[vcols.name];
+ pi = row[vcols.plugin];
#endif
- } else {
- Gtk::TreeModel::Row row = *(ladspa_display.get_selection()->get_selected());
- name = row[lcols.name];
- pi = row[lcols.plugin];
- added_plugins.push_back (row[lcols.plugin]);
+ break;
+ case PluginInfo::AudioUnit:
+#ifdef HAVE_COREAUDIO
+ row = *(au_display.get_selection()->get_selected());
+ name = row[aucols.name];
+ pi = row[aucols.plugin];
+#endif
+ break;
+ default:
+ error << "Programming error. Unknown plugin selected." << endmsg;
+ return;
}
+
newrow[acols.text] = name;
newrow[acols.plugin] = pi;
if (!amodel->children().empty()) {
- set_response_sensitive (RESPONSE_APPLY, true);
+ set_response_sensitive (RESPONSE_APPLY, true);
}
}
void
PluginSelector::btn_remove_clicked()
{
- list<PluginInfo*>::iterator i;
Gtk::TreeModel::iterator iter = added_list.get_selection()->get_selected();
- for (i = added_plugins.begin(); (*i) != (*iter)[acols.plugin]; ++i);
-
- added_plugins.erase(i);
+
amodel->erase(iter);
if (amodel->children().empty()) {
- set_response_sensitive (RESPONSE_APPLY, false);
+ set_response_sensitive (RESPONSE_APPLY, false);
}
-
-
}
void
@@ -313,28 +412,21 @@ PluginSelector::btn_update_clicked()
#ifdef VST_SUPPORT
vst_refiller ();
#endif
-}
-
-#ifdef VST_SUPPORT
-void
-PluginSelector::vst_display_selection_changed()
-{
- if (vst_display.get_selection()->count_selected_rows() != 0) {
- btn_add->set_sensitive (true);
- } else {
- btn_add->set_sensitive (false);
- }
-}
+#ifdef HAVE_COREAUDIO
+ au_refiller ();
#endif
+}
void
PluginSelector::ladspa_display_selection_changed()
{
- if (ladspa_display.get_selection()->count_selected_rows() != 0) {
- btn_add->set_sensitive (true);
- } else {
- btn_add->set_sensitive (false);
- }
+ if (ladspa_display.get_selection()->count_selected_rows() != 0) {
+ btn_add->set_sensitive (true);
+ } else {
+ btn_add->set_sensitive (false);
+ }
+
+ current_selection = PluginInfo::LADSPA;
}
void
@@ -351,14 +443,14 @@ int
PluginSelector::run ()
{
ResponseType r;
- list<PluginInfo*>::iterator i;
+ TreeModel::Children::iterator i;
r = (ResponseType) Dialog::run ();
switch (r) {
case RESPONSE_APPLY:
- for (i = added_plugins.begin(); i != added_plugins.end(); ++i){
- use_plugin (*i);
+ for (i = amodel->children().begin(); i != amodel->children().end(); ++i) {
+ use_plugin ((*i)[acols.plugin]);
}
break;
@@ -375,7 +467,5 @@ void
PluginSelector::cleanup ()
{
hide();
- added_plugins.clear();
amodel->clear();
}
-
diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h
index 125ce1b80a..583506972a 100644
--- a/gtk2_ardour/plugin_selector.h
+++ b/gtk2_ardour/plugin_selector.h
@@ -25,17 +25,18 @@
#include <gtkmm/treeview.h>
#include <gtkmm2ext/selector.h>
+#include <ardour/plugin.h>
+
namespace ARDOUR {
class Session;
class PluginManager;
- class Plugin;
}
class PluginSelector : public ArdourDialog
{
public:
PluginSelector (ARDOUR::PluginManager *);
- sigc::signal<void,ARDOUR::Plugin *> PluginCreated;
+ sigc::signal<void,boost::shared_ptr<ARDOUR::Plugin> > PluginCreated;
int run (); // XXX should we try not to overload the non-virtual Gtk::Dialog::run() ?
@@ -44,9 +45,12 @@ class PluginSelector : public ArdourDialog
private:
ARDOUR::Session* session;
Gtk::Notebook notebook;
- Gtk::ScrolledWindow lscroller;
- Gtk::ScrolledWindow vscroller;
- Gtk::ScrolledWindow ascroller;
+ Gtk::ScrolledWindow lscroller; // ladspa
+ Gtk::ScrolledWindow vscroller; // vst
+ Gtk::ScrolledWindow auscroller; // AudioUnit
+ Gtk::ScrolledWindow ascroller; // Added plugins
+
+ ARDOUR::PluginInfo::Type current_selection;
// page 1
struct LadspaColumns : public Gtk::TreeModel::ColumnRecord {
@@ -61,7 +65,7 @@ class PluginSelector : public ArdourDialog
Gtk::TreeModelColumn<std::string> type;
Gtk::TreeModelColumn<std::string> ins;
Gtk::TreeModelColumn<std::string> outs;
- Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin;
+ Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
};
LadspaColumns lcols;
Glib::RefPtr<Gtk::ListStore> lmodel;
@@ -76,7 +80,7 @@ class PluginSelector : public ArdourDialog
add (plugin);
}
Gtk::TreeModelColumn<std::string> text;
- Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin;
+ Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
};
AddedColumns acols;
Glib::RefPtr<Gtk::ListStore> amodel;
@@ -95,7 +99,7 @@ class PluginSelector : public ArdourDialog
Gtk::TreeModelColumn<std::string> name;
Gtk::TreeModelColumn<std::string> ins;
Gtk::TreeModelColumn<std::string> outs;
- Gtk::TreeModelColumn<ARDOUR::PluginInfo *> plugin;
+ Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
};
VstColumns vcols;
Glib::RefPtr<Gtk::ListStore> vmodel;
@@ -104,16 +108,32 @@ class PluginSelector : public ArdourDialog
static void _vst_refiller (void *);
void vst_refiller ();
void vst_display_selection_changed();
-#endif
-
- ARDOUR::PluginInfo* i_selected_plug;
+#endif // VST_SUPPORT
- // We need an integer for the output side because
- // the name isn't promised to be unique.
- gint o_selected_plug;
+#ifdef HAVE_COREAUDIO
+ // page 3
+ struct AUColumns : public Gtk::TreeModel::ColumnRecord {
+ AUColumns () {
+ add (name);
+ add (ins);
+ add (outs);
+ add (plugin);
+ }
+ Gtk::TreeModelColumn<std::string> name;
+ Gtk::TreeModelColumn<std::string> ins;
+ Gtk::TreeModelColumn<std::string> outs;
+ Gtk::TreeModelColumn<ARDOUR::PluginInfoPtr> plugin;
+ };
+ AUColumns aucols;
+ Glib::RefPtr<Gtk::ListStore> aumodel;
+ Glib::RefPtr<Gtk::TreeSelection> auselection;
+ Gtk::TreeView au_display;
+ static void _au_refiller (void *);
+ void au_refiller ();
+ void au_display_selection_changed();
+#endif //HAVE_COREAUDIO
ARDOUR::PluginManager *manager;
- list<ARDOUR::PluginInfo*> added_plugins;
static void _input_refiller (void *);
@@ -125,8 +145,9 @@ class PluginSelector : public ArdourDialog
void added_list_selection_changed();
void ladspa_display_selection_changed();
void btn_apply_clicked();
- void use_plugin (ARDOUR::PluginInfo*);
+ void use_plugin (ARDOUR::PluginInfoPtr);
void cleanup ();
};
#endif // __ardour_plugin_selector_h__
+
diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc
index 749ab9d4ac..5e5263b9ad 100644
--- a/gtk2_ardour/plugin_ui.cc
+++ b/gtk2_ardour/plugin_ui.cc
@@ -29,10 +29,10 @@
#include <gtkmm2ext/click_box.h>
#include <gtkmm2ext/fastmeter.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/barcontroller.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/doi.h>
+#include <gtkmm2ext/slider_controller.h>
#include <midi++/manager.h>
@@ -61,19 +61,19 @@ using namespace Gtkmm2ext;
using namespace Gtk;
using namespace sigc;
-PluginUIWindow::PluginUIWindow (AudioEngine &engine, PluginInsert& insert, bool scrollable)
+PluginUIWindow::PluginUIWindow (AudioEngine &engine, boost::shared_ptr<PluginInsert> insert, bool scrollable)
: ArdourDialog ("plugin ui")
{
- if (insert.plugin().has_editor()) {
+ if (insert->plugin()->has_editor()) {
#ifdef VST_SUPPORT
- VSTPlugin* vp;
+ boost::shared_ptr<VSTPlugin> vp;
- if ((vp = dynamic_cast<VSTPlugin*> (&insert.plugin())) != 0) {
+ if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (insert->plugin())) != 0) {
- VSTPluginUI* vpu = new VSTPluginUI (insert, *vp);
+ VSTPluginUI* vpu = new VSTPluginUI (insert, vp);
_pluginui = vpu;
get_vbox()->add (*vpu);
@@ -104,7 +104,7 @@ PluginUIWindow::PluginUIWindow (AudioEngine &engine, PluginInsert& insert, bool
add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast<Window*> (this)));
- insert.GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
+ insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away));
if (scrollable) {
gint h = _pluginui->get_preferred_height ();
@@ -117,7 +117,7 @@ PluginUIWindow::~PluginUIWindow ()
{
}
-PluginUI::PluginUI (AudioEngine &engine, PluginInsert& pi, bool scrollable)
+PluginUI::PluginUI (AudioEngine &engine, boost::shared_ptr<PluginInsert> pi, bool scrollable)
: PlugUIBase (pi),
engine(engine),
button_table (initial_button_rows, initial_button_cols),
@@ -165,8 +165,8 @@ PluginUI::PluginUI (AudioEngine &engine, PluginInsert& pi, bool scrollable)
pack_start (hpacker, false, false);
}
- insert.active_changed.connect (mem_fun(*this, &PluginUI::redirect_active_changed));
- bypass_button.set_active (!insert.active());
+ insert->active_changed.connect (mem_fun(*this, &PluginUI::redirect_active_changed));
+ bypass_button.set_active (!insert->active());
build (engine);
}
@@ -233,13 +233,13 @@ PluginUI::build (AudioEngine &engine)
/* find all ports. build control elements for all appropriate control ports */
- for (i = 0; i < plugin.parameter_count(); ++i) {
+ for (i = 0; i < plugin->parameter_count(); ++i) {
- if (plugin.parameter_is_control (i)) {
+ if (plugin->parameter_is_control (i)) {
/* Don't show latency control ports */
- if (plugin.describe_parameter (i) == X_("latency")) {
+ if (plugin->describe_parameter (i) == X_("latency")) {
continue;
}
@@ -263,7 +263,7 @@ PluginUI::build (AudioEngine &engine)
}
}
- if ((cui = build_control_ui (engine, i, plugin.get_nth_midi_control (i))) == 0) {
+ if ((cui = build_control_ui (engine, i, plugin->get_nth_control (i))) == 0) {
error << string_compose(_("Plugin Editor: could not build control element for port %1"), i) << endmsg;
continue;
}
@@ -326,8 +326,8 @@ PluginUI::build (AudioEngine &engine)
}
}
- n_ins = plugin.get_info().n_inputs;
- n_outs = plugin.get_info().n_outputs;
+ n_ins = plugin->get_info()->n_inputs;
+ n_outs = plugin->get_info()->n_outputs;
if (box->children().empty()) {
hpacker.remove (*frame);
@@ -387,7 +387,7 @@ PluginUI::automation_state_changed (ControlUI* cui)
{
/* update button label */
- switch (insert.get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) {
+ switch (insert->get_port_automation_state (cui->port_index) & (Off|Play|Touch|Write)) {
case Off:
cui->automate_button.set_label (_("Off"));
break;
@@ -415,17 +415,17 @@ static void integer_printer (char buf[32], Adjustment &adj, void *arg)
void
PluginUI::print_parameter (char *buf, uint32_t len, uint32_t param)
{
- plugin.print_parameter (param, buf, len);
+ plugin->print_parameter (param, buf, len);
}
PluginUI::ControlUI*
-PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Controllable* mcontrol)
+PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, PBD::Controllable* mcontrol)
{
ControlUI* control_ui;
Plugin::ParameterDescriptor desc;
- plugin.get_parameter_descriptor (port_index, desc);
+ plugin->get_parameter_descriptor (port_index, desc);
control_ui = manage (new ControlUI ());
control_ui->adjustment = 0;
@@ -439,11 +439,11 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
control_ui->set_spacing (5);
- if (plugin.parameter_is_input (port_index)) {
+ if (plugin->parameter_is_input (port_index)) {
- LadspaPlugin* lp;
+ boost::shared_ptr<LadspaPlugin> lp;
- if ((lp = dynamic_cast<LadspaPlugin*>(&plugin)) != 0) {
+ if ((lp = boost::dynamic_pointer_cast<LadspaPlugin>(plugin)) != 0) {
lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index);
@@ -453,7 +453,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
//control_ui->combo->set_value_in_list(true, false);
set_popdown_strings (*control_ui->combo, setup_scale_values(port_index, control_ui));
control_ui->combo->signal_changed().connect (bind (mem_fun(*this, &PluginUI::control_combo_changed), control_ui));
- plugin.ParameterChanged.connect (bind (mem_fun (*this, &PluginUI::parameter_changed), control_ui));
+ plugin->ParameterChanged.connect (bind (mem_fun (*this, &PluginUI::parameter_changed), control_ui));
control_ui->pack_start(control_ui->label, true, true);
control_ui->pack_start(*control_ui->combo, false, true);
@@ -478,7 +478,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
control_ui->button->signal_clicked().connect (bind (mem_fun(*this, &PluginUI::control_port_toggled), control_ui));
- if(plugin.get_parameter (port_index) == 1){
+ if(plugin->get_parameter (port_index) == 1){
control_ui->button->set_active(true);
}
@@ -516,7 +516,7 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
} else {
sigc::slot<void,char*,uint32_t> pslot = sigc::bind (mem_fun(*this, &PluginUI::print_parameter), (uint32_t) port_index);
- control_ui->control = new BarController (*control_ui->adjustment, mcontrol, pslot);
+ control_ui->control = new BarController (*control_ui->adjustment, *mcontrol, pslot);
// should really match the height of the text in the automation button+label
control_ui->control->set_size_request (200, 22);
control_ui->control->set_name (X_("PluginSlider"));
@@ -529,9 +529,9 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
}
if (control_ui->logarithmic) {
- control_ui->adjustment->set_value(log(plugin.get_parameter(port_index)));
+ control_ui->adjustment->set_value(log(plugin->get_parameter(port_index)));
} else{
- control_ui->adjustment->set_value(plugin.get_parameter(port_index));
+ control_ui->adjustment->set_value(plugin->get_parameter(port_index));
}
/* XXX memory leak: SliderController not destroyed by ControlUI
@@ -552,11 +552,11 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
automation_state_changed (control_ui);
- plugin.ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
- insert.automation_list (port_index).automation_state_changed.connect
+ plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
+ insert->automation_list (port_index).automation_state_changed.connect
(bind (mem_fun(*this, &PluginUI::automation_state_changed), control_ui));
- } else if (plugin.parameter_is_output (port_index)) {
+ } else if (plugin->parameter_is_output (port_index)) {
control_ui->display = manage (new EventBox);
control_ui->display->set_name ("ParameterValueDisplay");
@@ -603,20 +603,20 @@ PluginUI::build_control_ui (AudioEngine &engine, guint32 port_index, MIDI::Contr
output_controls.push_back (control_ui);
}
- plugin.ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
+ plugin->ParameterChanged.connect (bind (mem_fun(*this, &PluginUI::parameter_changed), control_ui));
return control_ui;
}
void
PluginUI::start_touch (PluginUI::ControlUI* cui)
{
- insert.automation_list (cui->port_index).start_touch ();
+ insert->automation_list (cui->port_index).start_touch ();
}
void
PluginUI::stop_touch (PluginUI::ControlUI* cui)
{
- insert.automation_list (cui->port_index).stop_touch ();
+ insert->automation_list (cui->port_index).stop_touch ();
}
void
@@ -647,7 +647,7 @@ PluginUI::astate_clicked (ControlUI* cui, uint32_t port)
void
PluginUI::set_automation_state (AutoState state, ControlUI* cui)
{
- insert.set_port_automation_state (cui->port_index, state);
+ insert->set_port_automation_state (cui->port_index, state);
}
void
@@ -663,7 +663,7 @@ PluginUI::control_adjustment_changed (ControlUI* cui)
value = exp(value);
}
- insert.set_parameter (cui->port_index, (float) value);
+ insert->set_parameter (cui->port_index, (float) value);
}
void
@@ -684,7 +684,7 @@ PluginUI::update_control_display (ControlUI* cui)
cui->update_pending = false;
- float val = plugin.get_parameter (cui->port_index);
+ float val = plugin->get_parameter (cui->port_index);
cui->ignore_change++;
if (cui->combo) {
@@ -718,7 +718,7 @@ void
PluginUI::control_port_toggled (ControlUI* cui)
{
if (!cui->ignore_change) {
- insert.set_parameter (cui->port_index, cui->button->get_active());
+ insert->set_parameter (cui->port_index, cui->button->get_active());
}
}
@@ -728,7 +728,7 @@ PluginUI::control_combo_changed (ControlUI* cui)
if (!cui->ignore_change) {
string value = cui->combo->get_active_text();
std::map<string,float> mapping = *cui->combo_map;
- insert.set_parameter (cui->port_index, mapping[value]);
+ insert->set_parameter (cui->port_index, mapping[value]);
}
}
@@ -774,7 +774,7 @@ void
PluginUI::output_update ()
{
for (vector<ControlUI*>::iterator i = output_controls.begin(); i != output_controls.end(); ++i) {
- float val = plugin.get_parameter ((*i)->port_index);
+ float val = plugin->get_parameter ((*i)->port_index);
char buf[32];
snprintf (buf, sizeof(buf), "%.2f", val);
(*i)->display_label->set_text (buf);
@@ -808,7 +808,7 @@ vector<string>
PluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
{
vector<string> enums;
- LadspaPlugin* lp = dynamic_cast<LadspaPlugin*> (&plugin);
+ boost::shared_ptr<LadspaPlugin> lp = boost::dynamic_pointer_cast<LadspaPlugin> (plugin);
cui->combo_map = new std::map<string, float>;
lrdf_defaults* defaults = lrdf_get_scale_values(lp->unique_id(), port_index);
@@ -827,14 +827,14 @@ PluginUI::setup_scale_values(guint32 port_index, ControlUI* cui)
return enums;
}
-PlugUIBase::PlugUIBase (PluginInsert& pi)
+PlugUIBase::PlugUIBase (boost::shared_ptr<PluginInsert> pi)
: insert (pi),
- plugin (insert.plugin()),
+ plugin (insert->plugin()),
save_button(_("Add")),
bypass_button (_("Bypass"))
{
//combo.set_use_arrows_always(true);
- set_popdown_strings (combo, plugin.get_presets());
+ set_popdown_strings (combo, plugin->get_presets());
combo.set_size_request (100, -1);
combo.set_active_text ("");
combo.signal_changed().connect(mem_fun(*this, &PlugUIBase::setting_selected));
@@ -850,7 +850,7 @@ void
PlugUIBase::setting_selected()
{
if (combo.get_active_text().length() > 0) {
- if (!plugin.load_preset(combo.get_active_text())) {
+ if (!plugin->load_preset(combo.get_active_text())) {
warning << string_compose(_("Plugin preset %1 not found"), combo.get_active_text()) << endmsg;
}
}
@@ -875,8 +875,8 @@ PlugUIBase::save_plugin_setting ()
prompter.get_result(name);
if (name.length()) {
- if(plugin.save_preset(name)){
- set_popdown_strings (combo, plugin.get_presets());
+ if(plugin->save_preset(name)){
+ set_popdown_strings (combo, plugin->get_presets());
combo.set_active_text (name);
}
}
@@ -889,8 +889,8 @@ PlugUIBase::bypass_toggled ()
{
bool x;
- if ((x = bypass_button.get_active()) == insert.active()) {
- insert.set_active (!x, this);
+ if ((x = bypass_button.get_active()) == insert->active()) {
+ insert->set_active (!x, this);
}
}
diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h
index e5800e8ece..570a224b66 100644
--- a/gtk2_ardour/plugin_ui.h
+++ b/gtk2_ardour/plugin_ui.h
@@ -52,7 +52,7 @@ namespace ARDOUR {
class Redirect;
}
-namespace MIDI {
+namespace PBD {
class Controllable;
}
@@ -67,7 +67,7 @@ namespace Gtkmm2ext {
class PlugUIBase : public virtual sigc::trackable
{
public:
- PlugUIBase (ARDOUR::PluginInsert&);
+ PlugUIBase (boost::shared_ptr<ARDOUR::PluginInsert>);
virtual ~PlugUIBase() {}
virtual gint get_preferred_height () = 0;
@@ -75,8 +75,8 @@ class PlugUIBase : public virtual sigc::trackable
virtual bool stop_updating(GdkEventAny*) = 0;
protected:
- ARDOUR::PluginInsert& insert;
- ARDOUR::Plugin& plugin;
+ boost::shared_ptr<ARDOUR::PluginInsert> insert;
+ boost::shared_ptr<ARDOUR::Plugin> plugin;
Gtk::ComboBoxText combo;
Gtk::Button save_button;
Gtk::ToggleButton bypass_button;
@@ -89,7 +89,7 @@ class PlugUIBase : public virtual sigc::trackable
class PluginUI : public PlugUIBase, public Gtk::VBox
{
public:
- PluginUI (ARDOUR::AudioEngine &, ARDOUR::PluginInsert& plug, bool scrollable=false);
+ PluginUI (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> plug, bool scrollable=false);
~PluginUI ();
gint get_preferred_height () { return prefheight; }
@@ -174,7 +174,7 @@ class PluginUI : public PlugUIBase, public Gtk::VBox
void output_update();
void build (ARDOUR::AudioEngine &);
- ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, MIDI::Controllable *);
+ ControlUI* build_control_ui (ARDOUR::AudioEngine &, guint32 port_index, PBD::Controllable *);
std::vector<string> setup_scale_values(guint32 port_index, ControlUI* cui);
void control_adjustment_changed (ControlUI* cui);
void parameter_changed (uint32_t, float, ControlUI* cui);
@@ -196,7 +196,7 @@ class PluginUI : public PlugUIBase, public Gtk::VBox
class PluginUIWindow : public ArdourDialog
{
public:
- PluginUIWindow (ARDOUR::AudioEngine &, ARDOUR::PluginInsert& insert, bool scrollable=false);
+ PluginUIWindow (ARDOUR::AudioEngine &, boost::shared_ptr<ARDOUR::PluginInsert> insert, bool scrollable=false);
~PluginUIWindow ();
PlugUIBase& pluginui() { return *_pluginui; }
@@ -213,7 +213,7 @@ class PluginUIWindow : public ArdourDialog
class VSTPluginUI : public PlugUIBase, public Gtk::VBox
{
public:
- VSTPluginUI (ARDOUR::PluginInsert&, ARDOUR::VSTPlugin&);
+ VSTPluginUI (boost::shared_ptr<ARDOUR::PluginInsert>, boost::shared_ptr<ARDOUR::VSTPlugin>);
~VSTPluginUI ();
gint get_preferred_height ();
@@ -223,7 +223,7 @@ class VSTPluginUI : public PlugUIBase, public Gtk::VBox
int package (Gtk::Window&);
private:
- ARDOUR::VSTPlugin& vst;
+ boost::shared_ptr<ARDOUR::VSTPlugin> vst;
Gtk::Socket socket;
Gtk::HBox preset_box;
Gtk::VBox vpacker;
diff --git a/gtk2_ardour/po/SConscript b/gtk2_ardour/po/SConscript
index 868f123988..d7e957b3eb 100644
--- a/gtk2_ardour/po/SConscript
+++ b/gtk2_ardour/po/SConscript
@@ -27,7 +27,7 @@ print "Updating pot file: "
domain = gtkardour['DOMAIN']
potfile = gtkardour['POTFILE']
-poaction = Action('intltool-update -p -g=' + domain)
+poaction = env.Action('intltool-update -p -g=' + domain)
Execute(poaction)
diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h
index 4c12b99d7c..f70e4c20bd 100644
--- a/gtk2_ardour/public_editor.h
+++ b/gtk2_ardour/public_editor.h
@@ -39,7 +39,7 @@ class AutomationLine;
class ControlPoint;
class SelectionRect;
class CrossfadeView;
-class AudioTimeAxisView;
+class RouteTimeAxisView;
class AudioRegionView;
class TempoMarker;
class MeterMarker;
@@ -145,10 +145,10 @@ class PublicEditor : public Gtk::Window, public Stateful {
virtual bool canvas_fade_in_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
virtual bool canvas_fade_out_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
virtual bool canvas_fade_out_handle_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
- virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
- virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
- virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, AudioRegionView*) = 0;
- virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, AudioTimeAxisView*) = 0;
+ virtual bool canvas_region_view_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
+ virtual bool canvas_region_view_name_highlight_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
+ virtual bool canvas_region_view_name_event (GdkEvent* event,ArdourCanvas::Item*, RegionView*) = 0;
+ virtual bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*) = 0;
virtual bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*) = 0;
virtual bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*) = 0;
virtual bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*) = 0;
diff --git a/gtk2_ardour/redirect_automation_line.cc b/gtk2_ardour/redirect_automation_line.cc
index 8971e8ff10..1ea5013295 100644
--- a/gtk2_ardour/redirect_automation_line.cc
+++ b/gtk2_ardour/redirect_automation_line.cc
@@ -55,7 +55,7 @@ RedirectAutomationLine::RedirectAutomationLine (const string & name, Redirect& r
/*NOTREACHED*/
}
- pi->plugin().get_parameter_descriptor (_port, desc);
+ pi->plugin()->get_parameter_descriptor (_port, desc);
upper = desc.upper;
lower = desc.lower;
diff --git a/gtk2_ardour/redirect_automation_time_axis.cc b/gtk2_ardour/redirect_automation_time_axis.cc
index e3ce4b08c6..e527fd1d5e 100644
--- a/gtk2_ardour/redirect_automation_time_axis.cc
+++ b/gtk2_ardour/redirect_automation_time_axis.cc
@@ -33,7 +33,8 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Gtk;
-RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, Route& r, PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
+RedirectAutomationTimeAxisView::RedirectAutomationTimeAxisView (Session& s, boost::shared_ptr<Route> r,
+ PublicEditor& e, TimeAxisView& parent, Canvas& canvas, std::string n,
uint32_t prt, Redirect& rd, string state_name)
: AxisView (s),
diff --git a/gtk2_ardour/redirect_automation_time_axis.h b/gtk2_ardour/redirect_automation_time_axis.h
index b8d94b2a3e..6976dc2358 100644
--- a/gtk2_ardour/redirect_automation_time_axis.h
+++ b/gtk2_ardour/redirect_automation_time_axis.h
@@ -14,7 +14,7 @@ class RedirectAutomationTimeAxisView : public AutomationTimeAxisView
{
public:
RedirectAutomationTimeAxisView (ARDOUR::Session&,
- ARDOUR::Route&,
+ boost::shared_ptr<ARDOUR::Route>,
PublicEditor&,
TimeAxisView& parent,
ArdourCanvas::Canvas& canvas,
diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc
index f5cb9522e0..74198265d9 100644
--- a/gtk2_ardour/redirect_box.cc
+++ b/gtk2_ardour/redirect_box.cc
@@ -76,7 +76,7 @@ bool RedirectBox::get_colors = true;
Gdk::Color* RedirectBox::active_redirect_color;
Gdk::Color* RedirectBox::inactive_redirect_color;
-RedirectBox::RedirectBox (Placement pcmnt, Session& sess, Route& rt, PluginSelector &plugsel,
+RedirectBox::RedirectBox (Placement pcmnt, Session& sess, boost::shared_ptr<Route> rt, PluginSelector &plugsel,
RouteRedirectSelection & rsel, bool owner_is_mixer)
: _route(rt),
_session(sess),
@@ -132,7 +132,7 @@ RedirectBox::RedirectBox (Placement pcmnt, Session& sess, Route& rt, PluginSelec
pack_start (redirect_eventbox, true, true);
- _route.redirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects));
+ _route->redirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects));
redirect_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (RedirectBox::enter_box), this));
@@ -161,10 +161,10 @@ RedirectBox::object_drop (string type, uint32_t cnt, void** ptr)
/* do something with the dropped redirects */
- list<Redirect*> redirects;
-
+ list<boost::shared_ptr<Redirect> > redirects;
+
for (uint32_t n = 0; n < cnt; ++n) {
- redirects.push_back ((Redirect*) ptr[n]);
+ redirects.push_back (boost::shared_ptr<Redirect> ((Redirect*) ptr[n]));
}
paste_redirect_list (redirects);
@@ -189,21 +189,21 @@ RedirectBox::set_width (Width w)
}
void
-RedirectBox::remove_redirect_gui (Redirect *redirect)
+RedirectBox::remove_redirect_gui (boost::shared_ptr<Redirect> redirect)
{
- Insert *insert = 0;
- Send *send = 0;
- PortInsert *port_insert = 0;
+ boost::shared_ptr<Insert> insert;
+ boost::shared_ptr<Send> send;
+ boost::shared_ptr<PortInsert> port_insert;
- if ((insert = dynamic_cast<Insert *> (redirect)) != 0) {
+ if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) != 0) {
- if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
+ if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
PortInsertUI *io_selector = reinterpret_cast<PortInsertUI *> (port_insert->get_gui());
port_insert->set_gui (0);
delete io_selector;
}
- } else if ((send = dynamic_cast<Send *> (insert)) != 0) {
+ } else if ((send = boost::dynamic_pointer_cast<Send> (insert)) != 0) {
SendUIWindow *sui = reinterpret_cast<SendUIWindow*> (send->get_gui());
send->set_gui (0);
delete sui;
@@ -268,7 +268,7 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev)
TreeViewColumn* column;
int cellx;
int celly;
- Redirect* redirect = 0;
+ boost::shared_ptr<Redirect> redirect;
int ret = false;
bool selected = false;
@@ -353,32 +353,32 @@ RedirectBox::choose_plugin ()
}
void
-RedirectBox::insert_plugin_chosen (Plugin *plugin)
+RedirectBox::insert_plugin_chosen (boost::shared_ptr<Plugin> plugin)
{
if (plugin) {
- Redirect *redirect = new PluginInsert (_session, *plugin, _placement);
+ boost::shared_ptr<Redirect> redirect (new PluginInsert (_session, plugin, _placement));
redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active));
uint32_t err_streams;
- if (_route.add_redirect (redirect, this, &err_streams)) {
+ if (_route->add_redirect (redirect, this, &err_streams)) {
wierd_plugin_dialog (*plugin, err_streams, _route);
- delete redirect;
+ // XXX SHAREDPTR delete plugin here .. do we even need to care?
}
}
}
void
-RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io)
+RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr<IO> io)
{
ArdourDialog dialog ("wierd plugin dialog");
Label label;
/* i hate this kind of code */
- if (streams > p.get_info().n_inputs) {
+ if (streams > p.get_info()->n_inputs) {
label.set_text (string_compose (_(
"You attempted to add a plugin (%1).\n"
"The plugin has %2 inputs\n"
@@ -388,9 +388,9 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io)
"This makes no sense - you are throwing away\n"
"part of the signal."),
p.name(),
- p.get_info().n_inputs,
+ p.get_info()->n_inputs,
streams));
- } else if (streams < p.get_info().n_inputs) {
+ } else if (streams < p.get_info()->n_inputs) {
label.set_text (string_compose (_(
"You attempted to add a plugin (%1).\n"
"The plugin has %2 inputs\n"
@@ -401,7 +401,7 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io)
"side-chain inputs. A future version of Ardour will\n"
"support this type of configuration."),
p.name(),
- p.get_info().n_inputs,
+ p.get_info()->n_inputs,
streams));
} else {
label.set_text (string_compose (_(
@@ -415,10 +415,10 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io)
"\n"
"Ardour does not understand what to do in such situations.\n"),
p.name(),
- p.get_info().n_inputs,
- p.get_info().n_outputs,
- io.n_inputs(),
- io.n_outputs(),
+ p.get_info()->n_inputs,
+ p.get_info()->n_outputs,
+ io->n_inputs(),
+ io->n_outputs(),
streams));
}
@@ -436,36 +436,36 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, IO& io)
void
RedirectBox::choose_insert ()
{
- Redirect *redirect = new PortInsert (_session, _placement);
+ boost::shared_ptr<Redirect> redirect (new PortInsert (_session, _placement));
redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active));
- _route.add_redirect (redirect, this);
+ _route->add_redirect (redirect, this);
}
void
RedirectBox::choose_send ()
{
- Send *send = new Send (_session, _placement);
+ boost::shared_ptr<Send> send (new Send (_session, _placement));
/* XXX need redirect lock on route */
- send->ensure_io (0, _route.max_redirect_outs(), false, this);
+ send->ensure_io (0, _route->max_redirect_outs(), false, this);
- IOSelectorWindow *ios = new IOSelectorWindow (_session, *send, false, true);
+ IOSelectorWindow *ios = new IOSelectorWindow (_session, send, false, true);
ios->show_all ();
- ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), static_cast<Redirect*>(send), ios));
+ ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::static_pointer_cast<Redirect>(send), ios));
}
void
-RedirectBox::send_io_finished (IOSelector::Result r, Redirect* redirect, IOSelectorWindow* ios)
+RedirectBox::send_io_finished (IOSelector::Result r, boost::shared_ptr<Redirect> redirect, IOSelectorWindow* ios)
{
switch (r) {
case IOSelector::Cancelled:
- delete redirect;
+ // delete redirect; XXX SHAREDPTR HOW TO DESTROY THE REDIRECT ? do we even need to think about it?
break;
case IOSelector::Accepted:
- _route.add_redirect (redirect, this);
+ _route->add_redirect (redirect, this);
break;
}
@@ -488,7 +488,8 @@ RedirectBox::redisplay_redirects (void *src)
redirect_active_connections.clear ();
redirect_name_connections.clear ();
- _route.foreach_redirect (this, &RedirectBox::add_redirect_to_display);
+ void (RedirectBox::*pmf)(boost::shared_ptr<Redirect>) = &RedirectBox::add_redirect_to_display;
+ _route->foreach_redirect (this, pmf);
switch (_placement) {
case PreFader:
@@ -501,33 +502,33 @@ RedirectBox::redisplay_redirects (void *src)
}
void
-RedirectBox::add_redirect_to_display (Redirect *redirect)
+RedirectBox::add_redirect_to_display (boost::shared_ptr<Redirect> redirect)
{
if (redirect->placement() != _placement) {
return;
}
Gtk::TreeModel::Row row = *(model->append());
- row[columns.text] = redirect_name (*redirect);
+ row[columns.text] = redirect_name (redirect);
row[columns.redirect] = redirect;
- show_redirect_active (redirect, this);
+ show_redirect_active (redirect.get(), this);
redirect_active_connections.push_back (redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)));
redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), redirect)));
}
string
-RedirectBox::redirect_name (Redirect& redirect)
+RedirectBox::redirect_name (boost::shared_ptr<Redirect> redirect)
{
- Send *send;
+ boost::shared_ptr<Send> send;
string name_display;
- if (!redirect.active()) {
+ if (!redirect->active()) {
name_display = " (";
}
- if ((send = dynamic_cast<Send *> (&redirect)) != 0) {
+ if ((send = boost::dynamic_pointer_cast<Send> (redirect)) != 0) {
name_display += '>';
@@ -550,16 +551,16 @@ RedirectBox::redirect_name (Redirect& redirect)
switch (_width) {
case Wide:
- name_display += redirect.name();
+ name_display += redirect->name();
break;
case Narrow:
- name_display += PBD::short_version (redirect.name(), 5);
+ name_display += PBD::short_version (redirect->name(), 5);
break;
}
}
- if (!redirect.active()) {
+ if (!redirect->active()) {
name_display += ')';
}
@@ -581,34 +582,36 @@ RedirectBox::build_redirect_tooltip (EventBox& box, string start)
}
void
-RedirectBox::show_redirect_name (void* src, Redirect *redirect)
+RedirectBox::show_redirect_name (void* src, boost::shared_ptr<Redirect> redirect)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_name), src, redirect));
-
- show_redirect_active (redirect, src);
+ show_redirect_active (redirect.get(), src);
}
void
-RedirectBox::show_redirect_active (Redirect *redirect, void *src)
+RedirectBox::show_redirect_active (Redirect* redirect, void *src)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), redirect, src));
Gtk::TreeModel::Children children = model->children();
Gtk::TreeModel::Children::iterator iter = children.begin();
- while( iter != children.end())
- {
- if ((*iter)[columns.redirect] == redirect)
- break;
- iter++;
- }
+ while (iter != children.end()) {
- (*iter)[columns.text] = redirect_name (*redirect);
+ boost::shared_ptr<Redirect> r = (*iter)[columns.redirect];
- if (redirect->active()) {
- (*iter)[columns.color] = *active_redirect_color;
- } else {
- (*iter)[columns.color] = *inactive_redirect_color;
+ if (r.get() == redirect) {
+ (*iter)[columns.text] = redirect_name (r);
+
+ if (redirect->active()) {
+ (*iter)[columns.color] = *active_redirect_color;
+ } else {
+ (*iter)[columns.color] = *inactive_redirect_color;
+ }
+ break;
+ }
+
+ iter++;
}
}
@@ -627,12 +630,12 @@ RedirectBox::compute_redirect_sort_keys ()
Gtk::TreeModel::Children children = model->children();
for (Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) {
- Redirect *redirect = (*iter)[columns.redirect];
- redirect->set_sort_key (sort_key);
+ boost::shared_ptr<Redirect> r = (*iter)[columns.redirect];
+ r->set_sort_key (sort_key);
sort_key++;
}
- if (_route.sort_redirects ()) {
+ if (_route->sort_redirects ()) {
redisplay_redirects (0);
@@ -661,7 +664,7 @@ outputs do not work correctly."));
void
RedirectBox::rename_redirects ()
{
- vector<Redirect*> to_be_renamed;
+ vector<boost::shared_ptr<Redirect> > to_be_renamed;
get_selected_redirects (to_be_renamed);
@@ -669,7 +672,7 @@ RedirectBox::rename_redirects ()
return;
}
- for (vector<Redirect*>::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) {
+ for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_renamed.begin(); i != to_be_renamed.end(); ++i) {
rename_redirect (*i);
}
}
@@ -677,7 +680,7 @@ RedirectBox::rename_redirects ()
void
RedirectBox::cut_redirects ()
{
- vector<Redirect*> to_be_removed;
+ vector<boost::shared_ptr<Redirect> > to_be_removed;
get_selected_redirects (to_be_removed);
@@ -692,7 +695,7 @@ RedirectBox::cut_redirects ()
_rr_selection.set (to_be_removed);
- for (vector<Redirect*>::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
+ for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) {
void* gui = (*i)->get_gui ();
@@ -700,7 +703,7 @@ RedirectBox::cut_redirects ()
static_cast<Gtk::Widget*>(gui)->hide ();
}
- if (_route.remove_redirect (*i, this)) {
+ if (_route->remove_redirect (*i, this)) {
/* removal failed */
_rr_selection.remove (*i);
}
@@ -711,8 +714,8 @@ RedirectBox::cut_redirects ()
void
RedirectBox::copy_redirects ()
{
- vector<Redirect*> to_be_copied;
- vector<Redirect*> copies;
+ vector<boost::shared_ptr<Redirect> > to_be_copied;
+ vector<boost::shared_ptr<Redirect> > copies;
get_selected_redirects (to_be_copied);
@@ -720,29 +723,24 @@ RedirectBox::copy_redirects ()
return;
}
- for (vector<Redirect*>::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) {
- copies.push_back (Redirect::clone (**i));
+ for (vector<boost::shared_ptr<Redirect> >::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) {
+ copies.push_back (Redirect::clone (*i));
}
_rr_selection.set (copies);
}
gint
-RedirectBox::idle_delete_redirect (Redirect *redirect)
+RedirectBox::idle_delete_redirect (boost::shared_ptr<Redirect> redirect)
{
/* NOT copied to _mixer.selection() */
- if (_route.remove_redirect (redirect, this)) {
- /* removal failed */
- return FALSE;
- }
-
- delete redirect;
+ _route->remove_redirect (redirect, this);
return FALSE;
}
void
-RedirectBox::rename_redirect (Redirect* redirect)
+RedirectBox::rename_redirect (boost::shared_ptr<Redirect> redirect)
{
ArdourPrompter name_prompter (true);
string result;
@@ -767,7 +765,7 @@ RedirectBox::rename_redirect (Redirect* redirect)
}
void
-RedirectBox::cut_redirect (Redirect *redirect)
+RedirectBox::cut_redirect (boost::shared_ptr<Redirect> redirect)
{
/* this essentially transfers ownership of the redirect
of the redirect from the route to the mixer
@@ -782,15 +780,15 @@ RedirectBox::cut_redirect (Redirect *redirect)
static_cast<Gtk::Widget*>(gui)->hide ();
}
- if (_route.remove_redirect (redirect, this)) {
+ if (_route->remove_redirect (redirect, this)) {
_rr_selection.remove (redirect);
}
}
void
-RedirectBox::copy_redirect (Redirect *redirect)
+RedirectBox::copy_redirect (boost::shared_ptr<Redirect> redirect)
{
- Redirect* copy = Redirect::clone (*redirect);
+ boost::shared_ptr<Redirect> copy = Redirect::clone (redirect);
_rr_selection.add (copy);
}
@@ -805,22 +803,19 @@ RedirectBox::paste_redirects ()
}
void
-RedirectBox::paste_redirect_list (list<Redirect*>& redirects)
+RedirectBox::paste_redirect_list (list<boost::shared_ptr<Redirect> >& redirects)
{
- list<Redirect*> copies;
+ list<boost::shared_ptr<Redirect> > copies;
- for (list<Redirect*>::iterator i = redirects.begin(); i != redirects.end(); ++i) {
+ for (list<boost::shared_ptr<Redirect> >::iterator i = redirects.begin(); i != redirects.end(); ++i) {
- Redirect* copy = Redirect::clone (**i);
+ boost::shared_ptr<Redirect> copy = Redirect::clone (*i);
copy->set_placement (_placement, this);
copies.push_back (copy);
}
- if (_route.add_redirects (copies, this)) {
- for (list<Redirect*>::iterator i = copies.begin(); i != copies.end(); ++i) {
- delete *i;
- }
+ if (_route->add_redirects (copies, this)) {
string msg = _(
"Copying the set of redirects on the clipboard failed,\n\
@@ -832,19 +827,19 @@ could not match the configuration of this track.");
}
void
-RedirectBox::activate_redirect (Redirect *r)
+RedirectBox::activate_redirect (boost::shared_ptr<Redirect> r)
{
r->set_active (true, 0);
}
void
-RedirectBox::deactivate_redirect (Redirect *r)
+RedirectBox::deactivate_redirect (boost::shared_ptr<Redirect> r)
{
r->set_active (false, 0);
}
void
-RedirectBox::get_selected_redirects (vector<Redirect*>& redirects)
+RedirectBox::get_selected_redirects (vector<boost::shared_ptr<Redirect> >& redirects)
{
vector<Gtk::TreeModel::Path> pathlist = redirect_display.get_selection()->get_selected_rows();
@@ -853,12 +848,12 @@ RedirectBox::get_selected_redirects (vector<Redirect*>& redirects)
}
void
-RedirectBox::for_selected_redirects (void (RedirectBox::*pmf)(Redirect*))
+RedirectBox::for_selected_redirects (void (RedirectBox::*pmf)(boost::shared_ptr<Redirect>))
{
vector<Gtk::TreeModel::Path> pathlist = redirect_display.get_selection()->get_selected_rows();
for (vector<Gtk::TreeModel::Path>::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) {
- Redirect* redirect = (*(model->get_iter(*iter)))[columns.redirect];
+ boost::shared_ptr<Redirect> redirect = (*(model->get_iter(*iter)))[columns.redirect];
(this->*pmf)(redirect);
}
}
@@ -869,7 +864,7 @@ RedirectBox::clone_redirects ()
RouteSelection& routes (_rr_selection.routes);
if (!routes.empty()) {
- if (_route.copy_redirects (*routes.front(), _placement)) {
+ if (_route->copy_redirects (*routes.front(), _placement)) {
string msg = _(
"Copying the set of redirects on the clipboard failed,\n\
probably because the I/O configuration of the plugins\n\
@@ -883,7 +878,7 @@ could not match the configuration of this track.");
void
RedirectBox::all_redirects_active (bool state)
{
- _route.all_redirects_active (state);
+ _route->all_redirects_active (state);
}
void
@@ -892,7 +887,7 @@ RedirectBox::clear_redirects()
string prompt;
vector<string> choices;
- if (dynamic_cast<AudioTrack*>(&_route) != 0) {
+ if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) {
prompt = _("Do you really want to remove all redirects from this track?\n"
"(this cannot be undone)");
} else {
@@ -906,23 +901,23 @@ RedirectBox::clear_redirects()
Gtkmm2ext::Choice prompter (prompt, choices);
if (prompter.run () == 1) {
- _route.clear_redirects (this);
+ _route->clear_redirects (this);
}
}
void
-RedirectBox::edit_redirect (Redirect* redirect)
+RedirectBox::edit_redirect (boost::shared_ptr<Redirect> redirect)
{
- Insert *insert;
+ boost::shared_ptr<Insert> insert;
- if (dynamic_cast<AudioTrack*>(&_route) != 0) {
+ if (boost::dynamic_pointer_cast<AudioTrack>(_route) != 0) {
- if (dynamic_cast<AudioTrack*> (&_route)->freeze_state() == AudioTrack::Frozen) {
+ if (boost::dynamic_pointer_cast<AudioTrack> (_route)->freeze_state() == AudioTrack::Frozen) {
return;
}
}
- if ((insert = dynamic_cast<Insert *> (redirect)) == 0) {
+ if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) == 0) {
/* its a send */
@@ -930,7 +925,7 @@ RedirectBox::edit_redirect (Redirect* redirect)
return;
}
- Send *send = dynamic_cast<Send*> (redirect);
+ boost::shared_ptr<Send> send = boost::dynamic_pointer_cast<Send> (redirect);
SendUIWindow *send_ui;
@@ -939,7 +934,7 @@ RedirectBox::edit_redirect (Redirect* redirect)
string title;
title = string_compose(_("ardour: %1"), send->name());
- send_ui = new SendUIWindow (*send, _session);
+ send_ui = new SendUIWindow (send, _session);
send_ui->set_title (title);
send->set_gui (send_ui);
@@ -957,17 +952,17 @@ RedirectBox::edit_redirect (Redirect* redirect)
/* its an insert */
- PluginInsert *plugin_insert;
- PortInsert *port_insert;
+ boost::shared_ptr<PluginInsert> plugin_insert;
+ boost::shared_ptr<PortInsert> port_insert;
- if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
+ if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
PluginUIWindow *plugin_ui;
if (plugin_insert->get_gui() == 0) {
string title;
- string maker = plugin_insert->plugin().maker();
+ string maker = plugin_insert->plugin()->maker();
string::size_type email_pos;
if ((email_pos = maker.find_first_of ('<')) != string::npos) {
@@ -979,9 +974,9 @@ RedirectBox::edit_redirect (Redirect* redirect)
maker += " ...";
}
- title = string_compose(_("ardour: %1: %2 (by %3)"), _route.name(), plugin_insert->name(), maker);
+ title = string_compose(_("ardour: %1: %2 (by %3)"), _route->name(), plugin_insert->name(), maker);
- plugin_ui = new PluginUIWindow (_session.engine(), *plugin_insert);
+ plugin_ui = new PluginUIWindow (_session.engine(), plugin_insert);
if (_owner_is_mixer) {
ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui);
} else {
@@ -1000,7 +995,7 @@ RedirectBox::edit_redirect (Redirect* redirect)
plugin_ui->show_all ();
}
- } else if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
if (!_session.engine().connected()) {
MessageDialog msg ( _("Not connected to JACK - no I/O changes are possible"));
@@ -1011,7 +1006,7 @@ RedirectBox::edit_redirect (Redirect* redirect)
PortInsertWindow *io_selector;
if (port_insert->get_gui() == 0) {
- io_selector = new PortInsertWindow (_session, *port_insert);
+ io_selector = new PortInsertWindow (_session, port_insert);
port_insert->set_gui (io_selector);
} else {
diff --git a/gtk2_ardour/redirect_box.h b/gtk2_ardour/redirect_box.h
index bc162fac17..51c17cad51 100644
--- a/gtk2_ardour/redirect_box.h
+++ b/gtk2_ardour/redirect_box.h
@@ -33,11 +33,12 @@
#include <gtkmm2ext/click_box.h>
#include <gtkmm2ext/dndtreeview.h>
+#include <pbd/stateful.h>
+
#include <ardour/types.h>
#include <ardour/ardour.h>
#include <ardour/io.h>
#include <ardour/insert.h>
-#include <ardour/stateful.h>
#include <ardour/redirect.h>
#include <pbd/fastlog.h>
@@ -64,7 +65,8 @@ namespace ARDOUR {
class RedirectBox : public Gtk::HBox
{
public:
- RedirectBox (ARDOUR::Placement, ARDOUR::Session&, ARDOUR::Route &, PluginSelector &, RouteRedirectSelection &, bool owner_is_mixer = false);
+ RedirectBox (ARDOUR::Placement, ARDOUR::Session&,
+ boost::shared_ptr<ARDOUR::Route>, PluginSelector &, RouteRedirectSelection &, bool owner_is_mixer = false);
~RedirectBox ();
void set_width (Width);
@@ -77,8 +79,8 @@ class RedirectBox : public Gtk::HBox
void select_all_inserts ();
void select_all_sends ();
- sigc::signal<void,ARDOUR::Redirect *> RedirectSelected;
- sigc::signal<void,ARDOUR::Redirect *> RedirectUnselected;
+ sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectSelected;
+ sigc::signal<void,boost::shared_ptr<ARDOUR::Redirect> > RedirectUnselected;
static void register_actions();
@@ -86,7 +88,7 @@ class RedirectBox : public Gtk::HBox
void set_stuff_from_route ();
private:
- ARDOUR::Route & _route;
+ boost::shared_ptr<ARDOUR::Route> _route;
ARDOUR::Session & _session;
bool _owner_is_mixer;
@@ -102,7 +104,7 @@ class RedirectBox : public Gtk::HBox
add (color);
}
Gtk::TreeModelColumn<std::string> text;
- Gtk::TreeModelColumn<ARDOUR::Redirect*> redirect;
+ Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Redirect> > redirect;
Gtk::TreeModelColumn<Gdk::Color> color;
};
@@ -137,24 +139,29 @@ class RedirectBox : public Gtk::HBox
void show_redirect_menu (gint arg);
void choose_send ();
- void send_io_finished (IOSelector::Result, ARDOUR::Redirect*, IOSelectorWindow*);
+ void send_io_finished (IOSelector::Result, boost::shared_ptr<ARDOUR::Redirect>, IOSelectorWindow*);
void choose_insert ();
void choose_plugin ();
- void insert_plugin_chosen (ARDOUR::Plugin *);
+ void insert_plugin_chosen (boost::shared_ptr<ARDOUR::Plugin>);
bool no_redirect_redisplay;
bool ignore_delete;
bool redirect_button_press_event (GdkEventButton *);
void redisplay_redirects (void* src);
- void show_redirect_active (ARDOUR::Redirect *, void *);
- void show_redirect_name (void*, ARDOUR::Redirect *);
- void add_redirect_to_display (ARDOUR::Redirect *);
+ void add_redirect_to_display (boost::shared_ptr<ARDOUR::Redirect>);
void row_deleted (const Gtk::TreeModel::Path& path);
+ void show_redirect_name (void*, boost::shared_ptr<ARDOUR::Redirect>);
+
+ /* these are handlers for Redirect signals, so they take Redirect*
+ directly, rather than shared_ptr<Redirect>
+ */
+
+ void show_redirect_active (ARDOUR::Redirect*, void *);
- string redirect_name (ARDOUR::Redirect&);
+ string redirect_name (boost::shared_ptr<ARDOUR::Redirect>);
- void remove_redirect_gui (ARDOUR::Redirect *);
+ void remove_redirect_gui (boost::shared_ptr<ARDOUR::Redirect>);
void redirects_reordered (const Gtk::TreeModel::Path&, const Gtk::TreeModel::iterator&, int*);
void compute_redirect_sort_keys ();
@@ -173,23 +180,23 @@ class RedirectBox : public Gtk::HBox
void clone_redirects ();
void rename_redirects ();
- void for_selected_redirects (void (RedirectBox::*pmf)(ARDOUR::Redirect*));
- void get_selected_redirects (vector<ARDOUR::Redirect*>&);
+ void for_selected_redirects (void (RedirectBox::*pmf)(boost::shared_ptr<ARDOUR::Redirect>));
+ void get_selected_redirects (vector<boost::shared_ptr<ARDOUR::Redirect> >&);
static Glib::RefPtr<Gtk::Action> paste_action;
- void paste_redirect_list (std::list<ARDOUR::Redirect*>& redirects);
+ void paste_redirect_list (std::list<boost::shared_ptr<ARDOUR::Redirect> >& redirects);
- void activate_redirect (ARDOUR::Redirect*);
- void deactivate_redirect (ARDOUR::Redirect*);
- void cut_redirect (ARDOUR::Redirect*);
- void copy_redirect (ARDOUR::Redirect*);
- void edit_redirect (ARDOUR::Redirect*);
- void hide_redirect_editor (ARDOUR::Redirect*);
- void rename_redirect (ARDOUR::Redirect*);
+ void activate_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+ void deactivate_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+ void cut_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+ void copy_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+ void edit_redirect (boost::shared_ptr<ARDOUR::Redirect>);
+ void hide_redirect_editor (boost::shared_ptr<ARDOUR::Redirect>);
+ void rename_redirect (boost::shared_ptr<ARDOUR::Redirect>);
- gint idle_delete_redirect (ARDOUR::Redirect *);
+ gint idle_delete_redirect (boost::shared_ptr<ARDOUR::Redirect>);
- void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, ARDOUR::IO& io);
+ void wierd_plugin_dialog (ARDOUR::Plugin& p, uint32_t streams, boost::shared_ptr<ARDOUR::IO> io);
static RedirectBox* _current_redirect_box;
static bool enter_box (GdkEventCrossing*, RedirectBox*);
diff --git a/gtk2_ardour/redirect_selection.h b/gtk2_ardour/redirect_selection.h
index 3695f85c60..5bcd77cfe4 100644
--- a/gtk2_ardour/redirect_selection.h
+++ b/gtk2_ardour/redirect_selection.h
@@ -2,11 +2,12 @@
#define __ardour_gtk_redirect_selection_h__
#include <list>
+#include <boost/shared_ptr.hpp>
namespace ARDOUR {
class Redirect;
}
-struct RedirectSelection : list<ARDOUR::Redirect*> {};
+struct RedirectSelection : list<boost::shared_ptr<ARDOUR::Redirect> > {};
#endif /* __ardour_gtk_redirect_selection_h__ */
diff --git a/gtk2_ardour/region_editor.h b/gtk2_ardour/region_editor.h
index 65b0bbaa94..70590b0db5 100644
--- a/gtk2_ardour/region_editor.h
+++ b/gtk2_ardour/region_editor.h
@@ -15,172 +15,29 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
+ $Id: /local/undo/gtk2_ardour/region_editor.h 5 2006-05-31T02:48:48.738745Z paul $
*/
#ifndef __gtk_ardour_region_edit_h__
#define __gtk_ardour_region_edit_h__
-#include <map>
-
-#include <gtkmm/label.h>
-#include <gtkmm/entry.h>
-#include <gtkmm/box.h>
-#include <gtkmm/togglebutton.h>
-#include <gtkmm/button.h>
-#include <gtkmm/arrow.h>
-#include <gtkmm/frame.h>
-#include <gtkmm/table.h>
-#include <gtkmm/alignment.h>
-#include <gtkmm/adjustment.h>
-#include <gtkmm/separator.h>
-#include <gtkmm/spinbutton.h>
-
-#include <libgnomecanvas/libgnomecanvas.h>
-#include <sigc++/signal.h>
-
-#include "audio_clock.h"
#include "ardour_dialog.h"
-namespace ARDOUR {
- class AudioRegion;
- class Session;
-}
-
-class AudioRegionView;
+namespace ARDOUR { class Session; }
-class AudioRegionEditor : public ArdourDialog
+/** Just a useless stub for now... */
+class RegionEditor : public ArdourDialog
{
public:
- AudioRegionEditor (ARDOUR::Session&, ARDOUR::AudioRegion&, AudioRegionView& rv);
- ~AudioRegionEditor ();
-
- private:
- ARDOUR::Session& _session;
- ARDOUR::AudioRegion& _region;
- AudioRegionView& _region_view;
-
- void connect_editor_events ();
-
- Gtk::Label name_label;
- Gtk::Entry name_entry;
- Gtk::HBox name_hbox;
-
- Gtk::HBox top_row_hbox;
- Gtk::HBox top_row_button_hbox;
-
- Gtk::ToggleButton lock_button;
- Gtk::ToggleButton mute_button;
- Gtk::ToggleButton opaque_button;
- Gtk::ToggleButton envelope_active_button;
- Gtk::ToggleButton envelope_view_button;
-
- Gtk::Button raise_button;
- Gtk::Arrow raise_arrow;
- Gtk::Button lower_button;
- Gtk::Arrow lower_arrow;
- Gtk::Frame layer_frame;
- Gtk::Label layer_value_label;
- Gtk::Label layer_label;
- Gtk::HBox layer_hbox;
-
- Gtk::ToggleButton audition_button;
-
- Gtk::HBox lower_hbox;
-
- Gtk::Table time_table;
-
- Gtk::Label start_label;
- Gtk::Label end_label;
- Gtk::Label length_label;
- Gtk::Alignment start_alignment;
- Gtk::Alignment end_alignment;
- Gtk::Alignment length_alignment;
-
- AudioClock start_clock;
- AudioClock end_clock;
- AudioClock length_clock;
- AudioClock sync_offset_clock;
-
- Gtk::Table envelope_loop_table;
- Gtk::Button loop_button;
- Gtk::Label loop_label;
- Gtk::Label envelope_label;
-
- Gtk::Table fade_in_table;
- Gtk::Label fade_in_label;
- Gtk::Alignment fade_in_label_align;
- Gtk::Label fade_in_active_button_label;
- Gtk::ToggleButton fade_in_active_button;
- Gtk::Label fade_in_length_label;
-
- Gtk::Adjustment fade_in_length_adjustment;
- Gtk::SpinButton fade_in_length_spinner;
-
- Gtk::Table fade_out_table;
- Gtk::Label fade_out_label;
- Gtk::Alignment fade_out_label_align;
- Gtk::Label fade_out_active_button_label;
- Gtk::ToggleButton fade_out_active_button;
- Gtk::Label fade_out_length_label;
-
- Gtk::Adjustment fade_out_length_adjustment;
- Gtk::SpinButton fade_out_length_spinner;
-
- Gtk::HSeparator sep3;
- Gtk::VSeparator sep1;
- Gtk::VSeparator sep2;
-
- void region_changed (ARDOUR::Change);
- void bounds_changed (ARDOUR::Change);
- void name_changed ();
- void opacity_changed ();
- void mute_changed ();
- void envelope_active_changed ();
- void lock_changed ();
- void layer_changed ();
-
- void fade_in_length_adjustment_changed ();
- void fade_out_length_adjustment_changed ();
- void fade_in_changed ();
- void fade_out_changed ();
- void audition_state_changed (bool);
-
- void activation ();
-
- void name_entry_changed ();
- void start_clock_changed ();
- void end_clock_changed ();
- void length_clock_changed ();
-
- gint envelope_active_button_press (GdkEventButton *);
- gint envelope_active_button_release (GdkEventButton *);
-
- void audition_button_toggled ();
- void envelope_view_button_toggled ();
- void lock_button_clicked ();
- void mute_button_clicked ();
- void opaque_button_clicked ();
- void raise_button_clicked ();
- void lower_button_clicked ();
-
- void fade_in_active_toggled ();
- void fade_out_active_toggled ();
- void fade_in_active_changed ();
- void fade_out_active_changed ();
-
- void fade_in_realized ();
- void fade_out_realized ();
-
- void start_editing_fade_in ();
- void start_editing_fade_out ();
- void stop_editing_fade_in ();
- void stop_editing_fade_out ();
+ RegionEditor(ARDOUR::Session& s)
+ : ArdourDialog ("region editor")
+ , _session(s)
+ {}
- gint bpressed (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)());
- gint breleased (GdkEventButton* ev, Gtk::SpinButton* but, void (AudioRegionEditor::*pmf)());
+ virtual ~RegionEditor () {}
- bool spin_arrow_grab;
+ protected:
+ ARDOUR::Session& _session;
};
#endif /* __gtk_ardour_region_edit_h__ */
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index ebcf65cedd..920d2cdca9 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -3,7 +3,7 @@
#include <pbd/memento_command.h>
#include "region_gain_line.h"
-#include "regionview.h"
+#include "audio_region_view.h"
#include "utils.h"
#include "time_axis_view.h"
@@ -47,8 +47,8 @@ void
AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction)
{
AutomationLine::start_drag(cp,fraction);
- if (!rv.region.envelope_active()) {
- trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.region, rv.region.get_state()));
+ if (!rv.audio_region().envelope_active()) {
+ trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
rv.region.set_envelope_active(false);
}
}
@@ -64,11 +64,11 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
XMLNode &before = get_state();
- if (!rv.region.envelope_active()) {
- XMLNode &before = rv.region.get_state();
- rv.region.set_envelope_active(true);
- XMLNode &after = rv.region.get_state();
- trackview.session().add_command(new MementoCommand<AudioRegion>(rv.region, before, after));
+ if (!rv.audio_region().envelope_active()) {
+ XMLNode &before = rv.audio_region().get_state();
+ rv.audio_region().set_envelope_active(true);
+ XMLNode &after = rv.audio_region().get_state();
+ trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), before, after));
}
alist.erase (mr.start, mr.end);
@@ -81,9 +81,9 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
void
AudioRegionGainLine::end_drag (ControlPoint* cp)
{
- if (!rv.region.envelope_active()) {
- rv.region.set_envelope_active(true);
- trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.region, rv.region.get_state()));
+ if (!rv.audio_region().envelope_active()) {
+ rv.audio_region().set_envelope_active(true);
+ trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
}
AutomationLine::end_drag(cp);
}
diff --git a/gtk2_ardour/region_selection.cc b/gtk2_ardour/region_selection.cc
index 751584cab7..f8c9f384a9 100644
--- a/gtk2_ardour/region_selection.cc
+++ b/gtk2_ardour/region_selection.cc
@@ -1,8 +1,26 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
#include <algorithm>
-#include <ardour/audioregion.h>
+#include <ardour/region.h>
-#include "regionview.h"
+#include "region_view.h"
#include "region_selection.h"
using namespace ARDOUR;
@@ -11,7 +29,7 @@ using namespace sigc;
bool
-AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionView* b) const
+RegionComparator::operator() (const RegionView* a, const RegionView* b) const
{
if (a == b) {
return false;
@@ -20,16 +38,16 @@ AudioRegionComparator::operator() (const AudioRegionView* a, const AudioRegionVi
}
}
-AudioRegionSelection::AudioRegionSelection ()
+RegionSelection::RegionSelection ()
{
_current_start = 0;
_current_end = 0;
}
-AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other)
+RegionSelection::RegionSelection (const RegionSelection& other)
{
- for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
+ for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
add (*i, false);
}
_current_start = other._current_start;
@@ -38,14 +56,14 @@ AudioRegionSelection::AudioRegionSelection (const AudioRegionSelection& other)
-AudioRegionSelection&
-AudioRegionSelection::operator= (const AudioRegionSelection& other)
+RegionSelection&
+RegionSelection::operator= (const RegionSelection& other)
{
if (this != &other) {
clear_all();
- for (AudioRegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
+ for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
add (*i, false);
}
@@ -57,13 +75,13 @@ AudioRegionSelection::operator= (const AudioRegionSelection& other)
}
void
-AudioRegionSelection::clear_all()
+RegionSelection::clear_all()
{
clear();
_bylayer.clear();
}
-bool AudioRegionSelection::contains (AudioRegionView* rv)
+bool RegionSelection::contains (RegionView* rv)
{
if (this->find (rv) != end()) {
return true;
@@ -75,21 +93,21 @@ bool AudioRegionSelection::contains (AudioRegionView* rv)
}
void
-AudioRegionSelection::add (AudioRegionView* rv, bool dosort)
+RegionSelection::add (RegionView* rv, bool dosort)
{
if (this->find (rv) != end()) {
/* we already have it */
return;
}
- rv->AudioRegionViewGoingAway.connect (mem_fun(*this, &AudioRegionSelection::remove_it));
+ rv->RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it));
- if (rv->region.first_frame() < _current_start || empty()) {
- _current_start = rv->region.first_frame();
+ if (rv->region().first_frame() < _current_start || empty()) {
+ _current_start = rv->region().first_frame();
}
- if (rv->region.last_frame() > _current_end || empty()) {
- _current_end = rv->region.last_frame();
+ if (rv->region().last_frame() > _current_end || empty()) {
+ _current_end = rv->region().last_frame();
}
insert (rv);
@@ -100,15 +118,15 @@ AudioRegionSelection::add (AudioRegionView* rv, bool dosort)
}
void
-AudioRegionSelection::remove_it (AudioRegionView *rv)
+RegionSelection::remove_it (RegionView *rv)
{
remove (rv);
}
bool
-AudioRegionSelection::remove (AudioRegionView* rv)
+RegionSelection::remove (RegionView* rv)
{
- AudioRegionSelection::iterator i;
+ RegionSelection::iterator i;
if ((i = this->find (rv)) != end()) {
@@ -124,7 +142,7 @@ AudioRegionSelection::remove (AudioRegionView* rv)
} else {
- AudioRegion& region ((*i)->region);
+ Region& region ((*i)->region());
if (region.first_frame() == _current_start) {
@@ -165,15 +183,15 @@ AudioRegionSelection::remove (AudioRegionView* rv)
}
void
-AudioRegionSelection::add_to_layer (AudioRegionView * rv)
+RegionSelection::add_to_layer (RegionView * rv)
{
// insert it into layer sorted position
- list<AudioRegionView*>::iterator i;
+ list<RegionView*>::iterator i;
for (i = _bylayer.begin(); i != _bylayer.end(); ++i)
{
- if (rv->region.layer() < (*i)->region.layer()) {
+ if (rv->region().layer() < (*i)->region().layer()) {
_bylayer.insert(i, rv);
return;
}
@@ -184,16 +202,16 @@ AudioRegionSelection::add_to_layer (AudioRegionView * rv)
}
struct RegionSortByTime {
- bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
- return a->region.position() < b->region.position();
+ bool operator() (const RegionView* a, const RegionView* b) {
+ return a->region().position() < b->region().position();
}
};
void
-AudioRegionSelection::by_position (list<AudioRegionView*>& foo) const
+RegionSelection::by_position (list<RegionView*>& foo) const
{
- list<AudioRegionView*>::const_iterator i;
+ list<RegionView*>::const_iterator i;
RegionSortByTime sorter;
for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
diff --git a/gtk2_ardour/region_selection.h b/gtk2_ardour/region_selection.h
index 0c2b7be025..2192442cb0 100644
--- a/gtk2_ardour/region_selection.h
+++ b/gtk2_ardour/region_selection.h
@@ -1,3 +1,21 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
#ifndef __ardour_gtk_region_selection_h__
#define __ardour_gtk_region_selection_h__
@@ -9,23 +27,23 @@
using std::list;
using std::set;
-class AudioRegionView;
+class RegionView;
-struct AudioRegionComparator {
- bool operator() (const AudioRegionView* a, const AudioRegionView* b) const;
+struct RegionComparator {
+ bool operator() (const RegionView* a, const RegionView* b) const;
};
-class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator>, public sigc::trackable
+class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::trackable
{
public:
- AudioRegionSelection();
- AudioRegionSelection (const AudioRegionSelection&);
+ RegionSelection();
+ RegionSelection (const RegionSelection&);
- AudioRegionSelection& operator= (const AudioRegionSelection&);
+ RegionSelection& operator= (const RegionSelection&);
- void add (AudioRegionView*, bool dosort = true);
- bool remove (AudioRegionView*);
- bool contains (AudioRegionView*);
+ void add (RegionView*, bool dosort = true);
+ bool remove (RegionView*);
+ bool contains (RegionView*);
void clear_all();
@@ -39,18 +57,18 @@ class AudioRegionSelection : public set<AudioRegionView*, AudioRegionComparator>
return _current_end;
}
- const list<AudioRegionView *> & by_layer() const { return _bylayer; }
- void by_position (list<AudioRegionView*>&) const;
+ const list<RegionView *> & by_layer() const { return _bylayer; }
+ void by_position (list<RegionView*>&) const;
private:
- void remove_it (AudioRegionView*);
+ void remove_it (RegionView*);
- void add_to_layer (AudioRegionView *);
+ void add_to_layer (RegionView *);
jack_nframes_t _current_start;
jack_nframes_t _current_end;
- list<AudioRegionView *> _bylayer;
+ list<RegionView *> _bylayer;
};
#endif /* __ardour_gtk_region_selection_h__ */
diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc
new file mode 100644
index 0000000000..ebec4261ac
--- /dev/null
+++ b/gtk2_ardour/region_view.cc
@@ -0,0 +1,494 @@
+/*
+ Copyright (C) 2001-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: regionview.cc 691 2006-07-23 12:03:19Z drobilla $
+*/
+
+#include <cmath>
+#include <cassert>
+#include <algorithm>
+
+#include <gtkmm.h>
+
+#include <gtkmm2ext/gtk_ui.h>
+
+#include <ardour/playlist.h>
+#include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
+#include <ardour/audio_diskstream.h>
+
+#include "streamview.h"
+#include "region_view.h"
+#include "route_time_axis.h"
+#include "simplerect.h"
+#include "simpleline.h"
+#include "waveview.h"
+#include "public_editor.h"
+#include "region_editor.h"
+#include "ghostregion.h"
+#include "route_time_axis.h"
+#include "utils.h"
+#include "rgb_macros.h"
+#include "gui_thread.h"
+
+#include "i18n.h"
+
+using namespace sigc;
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Editing;
+using namespace ArdourCanvas;
+
+static const int32_t sync_mark_width = 9;
+
+sigc::signal<void,RegionView*> RegionView::RegionViewGoingAway;
+
+RegionView::RegionView (ArdourCanvas::Group* parent,
+ TimeAxisView& tv,
+ ARDOUR::Region& r,
+ double spu,
+ Gdk::Color& basic_color)
+ : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(),
+ TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameText|
+ TimeAxisViewItem::ShowNameHighlight|
+ TimeAxisViewItem::ShowFrame))
+ , _region (r)
+ , sync_mark(0)
+ , no_wave_msg(0)
+ , editor(0)
+ , current_visible_sync_position(0.0)
+ , valid(false)
+ , _pixel_width(1.0)
+ , _height(1.0)
+ , in_destructor(false)
+ , wait_for_data(false)
+{
+}
+
+RegionView::RegionView (ArdourCanvas::Group* parent,
+ TimeAxisView& tv,
+ ARDOUR::Region& r,
+ double spu,
+ Gdk::Color& basic_color,
+ TimeAxisViewItem::Visibility visibility)
+ : TimeAxisViewItem (r.name(), *parent, tv, spu, basic_color, r.position(), r.length(), visibility)
+ , _region (r)
+ , sync_mark(0)
+ , no_wave_msg(0)
+ , editor(0)
+ , current_visible_sync_position(0.0)
+ , valid(false)
+ , _pixel_width(1.0)
+ , _height(1.0)
+ , in_destructor(false)
+ , wait_for_data(false)
+{
+}
+
+void
+RegionView::init (Gdk::Color& basic_color, bool wfd)
+{
+ editor = 0;
+ valid = true;
+ in_destructor = false;
+ _height = 0;
+ wait_for_data = wfd;
+
+ compute_colors (basic_color);
+
+ name_highlight->set_data ("regionview", this);
+ name_text->set_data ("regionview", this);
+
+ /* an equilateral triangle */
+ ArdourCanvas::Points shape;
+ shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1));
+ shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1));
+ shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1));
+ shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1));
+
+ sync_mark = new ArdourCanvas::Polygon (*group);
+ sync_mark->property_points() = shape;
+ sync_mark->property_fill_color_rgba() = fill_color;
+ sync_mark->hide();
+
+ reset_width_dependent_items ((double) _region.length() / samples_per_unit);
+
+ set_height (trackview.height);
+
+ region_muted ();
+ region_sync_changed ();
+ region_resized (BoundsChanged);
+ region_locked ();
+
+ _region.StateChanged.connect (mem_fun(*this, &RegionView::region_changed));
+
+ group->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_event), group, this));
+ name_highlight->signal_event().connect (bind (mem_fun (PublicEditor::instance(), &PublicEditor::canvas_region_view_name_highlight_event), name_highlight, this));
+
+ set_colors ();
+
+ ColorChanged.connect (mem_fun (*this, &RegionView::color_handler));
+
+ /* XXX sync mark drag? */
+}
+
+RegionView::~RegionView ()
+{
+ in_destructor = true;
+
+ RegionViewGoingAway (this); /* EMIT_SIGNAL */
+
+ for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
+ delete *g;
+ }
+
+ if (editor) {
+ delete editor;
+ }
+}
+
+gint
+RegionView::_lock_toggle (ArdourCanvas::Item* item, GdkEvent* ev, void* arg)
+{
+ switch (ev->type) {
+ case GDK_BUTTON_RELEASE:
+ static_cast<RegionView*>(arg)->lock_toggle ();
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+void
+RegionView::lock_toggle ()
+{
+ _region.set_locked (!_region.locked());
+}
+
+void
+RegionView::region_changed (Change what_changed)
+{
+ ENSURE_GUI_THREAD (bind (mem_fun(*this, &RegionView::region_changed), what_changed));
+
+ if (what_changed & BoundsChanged) {
+ region_resized (what_changed);
+ region_sync_changed ();
+ }
+ if (what_changed & Region::MuteChanged) {
+ region_muted ();
+ }
+ if (what_changed & Region::OpacityChanged) {
+ region_opacity ();
+ }
+ if (what_changed & ARDOUR::NameChanged) {
+ region_renamed ();
+ }
+ if (what_changed & Region::SyncOffsetChanged) {
+ region_sync_changed ();
+ }
+ if (what_changed & Region::LayerChanged) {
+ region_layered ();
+ }
+ if (what_changed & Region::LockChanged) {
+ region_locked ();
+ }
+}
+
+void
+RegionView::region_locked ()
+{
+ /* name will show locked status */
+ region_renamed ();
+}
+
+void
+RegionView::region_resized (Change what_changed)
+{
+ double unit_length;
+
+ if (what_changed & ARDOUR::PositionChanged) {
+ set_position (_region.position(), 0);
+ }
+
+ if (what_changed & Change (StartChanged|LengthChanged)) {
+
+ set_duration (_region.length(), 0);
+
+ unit_length = _region.length() / samples_per_unit;
+
+ reset_width_dependent_items (unit_length);
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+
+ (*i)->set_duration (unit_length);
+
+ }
+ }
+}
+
+void
+RegionView::reset_width_dependent_items (double pixel_width)
+{
+ TimeAxisViewItem::reset_width_dependent_items (pixel_width);
+ _pixel_width = pixel_width;
+}
+
+void
+RegionView::region_layered ()
+{
+ RouteTimeAxisView *rtv = dynamic_cast<RouteTimeAxisView*>(&get_time_axis_view());
+ assert(rtv);
+ rtv->view()->region_layered (this);
+}
+
+void
+RegionView::region_muted ()
+{
+ set_frame_color ();
+ region_renamed ();
+}
+
+void
+RegionView::region_opacity ()
+{
+ set_frame_color ();
+}
+
+void
+RegionView::raise ()
+{
+ _region.raise ();
+}
+
+void
+RegionView::raise_to_top ()
+{
+ _region.raise_to_top ();
+}
+
+void
+RegionView::lower ()
+{
+ _region.lower ();
+}
+
+void
+RegionView::lower_to_bottom ()
+{
+ _region.lower_to_bottom ();
+}
+
+bool
+RegionView::set_position (jack_nframes_t pos, void* src, double* ignored)
+{
+ double delta;
+ bool ret;
+
+ if (!(ret = TimeAxisViewItem::set_position (pos, this, &delta))) {
+ return false;
+ }
+
+ if (ignored) {
+ *ignored = delta;
+ }
+
+ if (delta) {
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ (*i)->group->move (delta, 0.0);
+ }
+ }
+
+ return ret;
+}
+
+void
+RegionView::set_samples_per_unit (gdouble spu)
+{
+ TimeAxisViewItem::set_samples_per_unit (spu);
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ (*i)->set_samples_per_unit (spu);
+ (*i)->set_duration (_region.length() / samples_per_unit);
+ }
+
+ region_sync_changed ();
+}
+
+bool
+RegionView::set_duration (jack_nframes_t frames, void *src)
+{
+ if (!TimeAxisViewItem::set_duration (frames, src)) {
+ return false;
+ }
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ (*i)->set_duration (_region.length() / samples_per_unit);
+ }
+
+ return true;
+}
+
+void
+RegionView::compute_colors (Gdk::Color& basic_color)
+{
+ TimeAxisViewItem::compute_colors (basic_color);
+}
+
+void
+RegionView::set_colors ()
+{
+ TimeAxisViewItem::set_colors ();
+
+ if (sync_mark) {
+ sync_mark->property_fill_color_rgba() = fill_color;
+ }
+}
+
+void
+RegionView::set_frame_color ()
+{
+ if (_region.opaque()) {
+ fill_opacity = 180;
+ } else {
+ fill_opacity = 100;
+ }
+
+ TimeAxisViewItem::set_frame_color ();
+}
+
+void
+RegionView::hide_region_editor()
+{
+ if (editor) {
+ editor->hide_all ();
+ }
+}
+
+void
+RegionView::region_renamed ()
+{
+ string str;
+
+ if (_region.locked()) {
+ str += '>';
+ str += _region.name();
+ str += '<';
+ } else {
+ str = _region.name();
+ }
+
+ if (_region.speed_mismatch (trackview.session().frame_rate())) {
+ str = string ("*") + str;
+ }
+
+ if (_region.muted()) {
+ str = string ("!") + str;
+ }
+
+ set_item_name (str, this);
+ set_name_text (str);
+}
+
+void
+RegionView::region_sync_changed ()
+{
+ if (sync_mark == 0) {
+ return;
+ }
+
+ int sync_dir;
+ jack_nframes_t sync_offset;
+
+ sync_offset = _region.sync_offset (sync_dir);
+
+ /* this has to handle both a genuine change of position, a change of samples_per_unit,
+ and a change in the bounds of the _region.
+ */
+
+ if (sync_offset == 0) {
+
+ /* no sync mark - its the start of the region */
+
+ sync_mark->hide();
+
+ } else {
+
+ if ((sync_dir < 0) || ((sync_dir > 0) && (sync_offset > _region.length()))) {
+
+ /* no sync mark - its out of the bounds of the region */
+
+ sync_mark->hide();
+
+ } else {
+
+ /* lets do it */
+
+ Points points;
+
+ //points = sync_mark->property_points().get_value();
+
+ double offset = sync_offset / samples_per_unit;
+ points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1));
+ points.push_back (Gnome::Art::Point (offset + ((sync_mark_width-1)/2), 1));
+ points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1));
+ points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1));
+ sync_mark->property_points().set_value (points);
+ sync_mark->show();
+
+ }
+ }
+}
+
+void
+RegionView::move (double x_delta, double y_delta)
+{
+ if (_region.locked() || (x_delta == 0 && y_delta == 0)) {
+ return;
+ }
+
+ get_canvas_group()->move (x_delta, y_delta);
+
+ /* note: ghosts never leave their tracks so y_delta for them is always zero */
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ (*i)->group->move (x_delta, 0.0);
+ }
+}
+
+void
+RegionView::remove_ghost (GhostRegion* ghost)
+{
+ if (in_destructor) {
+ return;
+ }
+
+ for (vector<GhostRegion*>::iterator i = ghosts.begin(); i != ghosts.end(); ++i) {
+ if (*i == ghost) {
+ ghosts.erase (i);
+ break;
+ }
+ }
+}
+
+uint32_t
+RegionView::get_fill_color ()
+{
+ return fill_color;
+}
+
diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h
new file mode 100644
index 0000000000..fdc69ea70e
--- /dev/null
+++ b/gtk2_ardour/region_view.h
@@ -0,0 +1,140 @@
+/*
+ Copyright (C) 2001-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __gtk_ardour_region_view_h__
+#define __gtk_ardour_region_view_h__
+
+#include <vector>
+
+#include <libgnomecanvasmm.h>
+#include <libgnomecanvasmm/polygon.h>
+#include <sigc++/signal.h>
+#include <ardour/region.h>
+
+#include "time_axis_view_item.h"
+#include "automation_line.h"
+#include "enums.h"
+#include "waveview.h"
+#include "canvas.h"
+#include "color.h"
+
+class TimeAxisView;
+class RegionEditor;
+class GhostRegion;
+class AutomationTimeAxisView;
+
+class RegionView : public TimeAxisViewItem
+{
+ public:
+ RegionView (ArdourCanvas::Group* parent,
+ TimeAxisView& time_view,
+ ARDOUR::Region& region,
+ double samples_per_unit,
+ Gdk::Color& basic_color);
+
+ ~RegionView ();
+
+ virtual void init (Gdk::Color& base_color, bool wait_for_data);
+
+ ARDOUR::Region& region() const { return _region; }
+
+ bool is_valid() const { return valid; }
+ void set_valid (bool yn) { valid = yn; }
+
+ virtual void set_height (double) = 0;
+ virtual void set_samples_per_unit (double);
+ virtual bool set_duration (jack_nframes_t, void*);
+
+ void move (double xdelta, double ydelta);
+
+ void raise ();
+ void raise_to_top ();
+ void lower ();
+ void lower_to_bottom ();
+
+ bool set_position(jack_nframes_t pos, void* src, double* delta = 0);
+
+ virtual void show_region_editor () = 0;
+ virtual void hide_region_editor();
+
+ virtual void region_changed (ARDOUR::Change);
+
+ virtual GhostRegion* add_ghost (AutomationTimeAxisView&) = 0;
+ void remove_ghost (GhostRegion*);
+
+ uint32_t get_fill_color ();
+
+ virtual void entered () {}
+ virtual void exited () {}
+
+ static sigc::signal<void,RegionView*> RegionViewGoingAway;
+ sigc::signal<void> GoingAway;
+
+ protected:
+
+ /** Allows derived types to specify their visibility requirements
+ * to the TimeAxisViewItem parent class
+ */
+ RegionView (ArdourCanvas::Group *,
+ TimeAxisView&,
+ ARDOUR::Region&,
+ double samples_per_unit,
+ Gdk::Color& basic_color,
+ TimeAxisViewItem::Visibility);
+
+ virtual void region_resized (ARDOUR::Change);
+ void region_moved (void *);
+ virtual void region_muted ();
+ void region_locked ();
+ void region_opacity ();
+ void region_layered ();
+ void region_renamed ();
+ void region_sync_changed ();
+
+ static gint _lock_toggle (ArdourCanvas::Item*, GdkEvent*, void*);
+ void lock_toggle ();
+
+ virtual void set_colors ();
+ virtual void compute_colors (Gdk::Color&);
+ virtual void set_frame_color ();
+ virtual void reset_width_dependent_items (double pixel_width);
+
+ virtual void color_handler (ColorID, uint32_t) {}
+
+ ARDOUR::Region& _region;
+
+ ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position
+ ArdourCanvas::Text* no_wave_msg;
+
+ RegionEditor* editor;
+
+ vector<ControlPoint *> control_points;
+ double current_visible_sync_position;
+
+ bool valid; ///< see StreamView::redisplay_diskstream()
+ double _pixel_width;
+ double _height;
+ bool in_destructor;
+
+ bool wait_for_data;
+ sigc::connection data_ready_connection;
+
+ vector<GhostRegion*> ghosts;
+};
+
+#endif /* __gtk_ardour_region_view_h__ */
diff --git a/gtk2_ardour/route_params_ui.cc b/gtk2_ardour/route_params_ui.cc
index d6ec7eab6c..8b47a17511 100644
--- a/gtk2_ardour/route_params_ui.cc
+++ b/gtk2_ardour/route_params_ui.cc
@@ -59,14 +59,10 @@ using namespace sigc;
RouteParams_UI::RouteParams_UI (AudioEngine& eng)
: ArdourDialog ("track/bus inspector"),
engine (eng),
- _route(0),
track_menu(0)
{
pre_redirect_box = 0;
post_redirect_box = 0;
- _route = 0;
- _pre_redirect = 0;
- _post_redirect = 0;
_input_iosel = 0;
_output_iosel = 0;
_active_pre_view = 0;
@@ -163,7 +159,7 @@ RouteParams_UI::~RouteParams_UI ()
}
void
-RouteParams_UI::add_route (Route* route)
+RouteParams_UI::add_route (boost::shared_ptr<Route> route)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::add_route), route));
@@ -183,22 +179,22 @@ RouteParams_UI::add_route (Route* route)
void
-RouteParams_UI::route_name_changed (void *src, Route *route)
+RouteParams_UI::route_name_changed (void *src, boost::shared_ptr<Route> route)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_name_changed), src, route));
bool found = false ;
TreeModel::Children rows = route_display_model->children();
for(TreeModel::Children::iterator iter = rows.begin(); iter != rows.end(); ++iter) {
- if((*iter)[route_display_columns.route] == route) {
+ boost::shared_ptr<Route> r =(*iter)[route_display_columns.route];
+ if (r == route) {
(*iter)[route_display_columns.text] = route->name() ;
found = true ;
break;
}
}
- if(!found)
- {
+ if(!found) {
error << _("route display list item for renamed route not found!") << endmsg;
}
@@ -217,8 +213,8 @@ RouteParams_UI::setup_redirect_boxes()
cleanup_redirect_boxes();
// construct new redirect boxes
- pre_redirect_box = new RedirectBox(PreFader, *session, *_route, *_plugin_selector, _rr_selection);
- post_redirect_box = new RedirectBox(PostFader, *session, *_route, *_plugin_selector, _rr_selection);
+ pre_redirect_box = new RedirectBox(PreFader, *session, _route, *_plugin_selector, _rr_selection);
+ post_redirect_box = new RedirectBox(PostFader, *session, _route, *_plugin_selector, _rr_selection);
pre_redir_hpane.pack1 (*pre_redirect_box);
post_redir_hpane.pack1 (*post_redirect_box);
@@ -256,13 +252,13 @@ RouteParams_UI::setup_io_frames()
cleanup_io_frames();
// input
- _input_iosel = new IOSelector (*session, *_route, true);
+ _input_iosel = new IOSelector (*session, _route, true);
_input_iosel->redisplay ();
input_frame.add (*_input_iosel);
input_frame.show_all();
// output
- _output_iosel = new IOSelector (*session, *_route, false);
+ _output_iosel = new IOSelector (*session, _route, false);
_output_iosel->redisplay ();
output_frame.add (*_output_iosel);
output_frame.show_all();
@@ -322,36 +318,31 @@ RouteParams_UI::cleanup_post_view (bool stopupdate)
void
-RouteParams_UI::route_removed (Route *route)
+RouteParams_UI::route_removed (boost::shared_ptr<Route> route)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::route_removed), route));
- /*
- route_select_list.freeze ();
- route_select_list.clear ();
- session->foreach_route (this, &RouteParams_UI::add_route);
- route_select_list.thaw ();
- */
TreeModel::Children rows = route_display_model->children();
TreeModel::Children::iterator ri;
for(TreeModel::Children::iterator iter = rows.begin(); iter != rows.end(); ++iter) {
- if((*iter)[route_display_columns.route] == route) {
+ boost::shared_ptr<Route> r =(*iter)[route_display_columns.route];
+
+ if (r == route) {
route_display_model->erase(iter);
break;
}
}
- if (route == _route)
- {
+ if (route == _route) {
cleanup_io_frames();
cleanup_pre_view();
cleanup_post_view();
cleanup_redirect_boxes();
- _route = 0;
- _pre_redirect = 0;
- _post_redirect = 0;
+ _route.reset ((Route*) 0);
+ _pre_redirect.reset ((Redirect*) 0);
+ _post_redirect.reset ((Redirect*) 0);
update_title();
}
}
@@ -390,9 +381,9 @@ RouteParams_UI::session_gone ()
cleanup_post_view();
cleanup_redirect_boxes();
- _route = 0;
- _pre_redirect = 0;
- _post_redirect = 0;
+ _route.reset ((Route*) 0);
+ _pre_redirect.reset ((Redirect*) 0);
+ _post_redirect.reset ((Redirect*) 0);
update_title();
ArdourDialog::session_gone();
@@ -406,7 +397,7 @@ RouteParams_UI::route_selected()
TreeModel::iterator iter = selection->get_selected(); // only used with Gtk::SELECTION_SINGLE
if(iter) {
//If anything is selected
- Route* route = (*iter)[route_display_columns.route] ;
+ boost::shared_ptr<Route> route = (*iter)[route_display_columns.route] ;
if (_route == route) {
// do nothing
@@ -447,9 +438,9 @@ RouteParams_UI::route_selected()
cleanup_post_view();
cleanup_redirect_boxes();
- _route = 0;
- _pre_redirect = 0;
- _post_redirect = 0;
+ _route.reset ((Route*) 0);
+ _pre_redirect.reset ((Redirect*) 0);
+ _post_redirect.reset ((Redirect *) 0);
track_input_label.set_text(_("NO TRACK"));
update_title();
}
@@ -468,7 +459,7 @@ RouteParams_UI::route_selected()
// cleanup_post_view();
// cleanup_redirect_boxes();
-// _route = 0;
+// _route.reset ((Route*)0);
// _pre_redirect = 0;
// _post_redirect = 0;
// track_input_label.set_text(_("NO TRACK"));
@@ -495,8 +486,8 @@ RouteParams_UI::redirects_changed (void *src)
cleanup_pre_view();
cleanup_post_view();
- _pre_redirect = 0;
- _post_redirect = 0;
+ _pre_redirect.reset ((Redirect*) 0);
+ _post_redirect.reset ((Redirect*) 0);
//update_title();
}
@@ -520,24 +511,24 @@ RouteParams_UI::show_track_menu()
void
-RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement place)
+RouteParams_UI::redirect_selected (boost::shared_ptr<ARDOUR::Redirect> redirect, ARDOUR::Placement place)
{
- Insert *insert;
+ boost::shared_ptr<Insert> insert;
if ((place == PreFader && _pre_redirect == redirect)
|| (place == PostFader && _post_redirect == redirect)){
return;
}
- if ((insert = dynamic_cast<Insert *> (redirect)) == 0) {
-
- Send *send;
+ if ((insert = boost::dynamic_pointer_cast<Insert> (redirect)) == 0) {
- if ((send = dynamic_cast<Send *> (redirect)) != 0) {
+ boost::shared_ptr<Send> send;
+
+ if ((send = boost::dynamic_pointer_cast<Send> (redirect)) != 0) {
/* its a send */
- SendUI *send_ui = new SendUI (*send, *session);
+ SendUI *send_ui = new SendUI (send, *session);
if (place == PreFader) {
cleanup_pre_view();
@@ -560,16 +551,16 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement
} else {
/* its an insert, though we don't know what kind yet. */
- PluginInsert *plugin_insert;
- PortInsert *port_insert;
+ boost::shared_ptr<PluginInsert> plugin_insert;
+ boost::shared_ptr<PortInsert> port_insert;
- if ((plugin_insert = dynamic_cast<PluginInsert *> (insert)) != 0) {
+ if ((plugin_insert = boost::dynamic_pointer_cast<PluginInsert> (insert)) != 0) {
- PluginUI *plugin_ui = new PluginUI (session->engine(), *plugin_insert, true);
+ PluginUI *plugin_ui = new PluginUI (session->engine(), plugin_insert, true);
if (place == PreFader) {
cleanup_pre_view();
- _pre_plugin_conn = plugin_insert->plugin().GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader));
+ _pre_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PreFader));
plugin_ui->start_updating (0);
_active_pre_view = plugin_ui;
pre_redir_hpane.pack2 (*_active_pre_view);
@@ -577,16 +568,16 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement
}
else {
cleanup_post_view();
- _post_plugin_conn = plugin_insert->plugin().GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader));
+ _post_plugin_conn = plugin_insert->plugin()->GoingAway.connect (bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), PostFader));
plugin_ui->start_updating (0);
_active_post_view = plugin_ui;
post_redir_hpane.pack2 (*_active_post_view);
post_redir_hpane.show_all();
}
- } else if ((port_insert = dynamic_cast<PortInsert *> (insert)) != 0) {
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (insert)) != 0) {
- PortInsertUI *portinsert_ui = new PortInsertUI (*session, *port_insert);
+ PortInsertUI *portinsert_ui = new PortInsertUI (*session, port_insert);
if (place == PreFader) {
cleanup_pre_view();
@@ -610,8 +601,7 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement
if (place == PreFader) {
_pre_redirect = redirect;
- }
- else {
+ } else {
_post_redirect = redirect;
}
@@ -620,23 +610,6 @@ RouteParams_UI::redirect_selected (ARDOUR::Redirect *redirect, ARDOUR::Placement
}
void
-RouteParams_UI::redirect_unselected (ARDOUR::Redirect *redirect)
-{
- // not called anymore
-
- if (redirect == _pre_redirect) {
- cleanup_pre_view();
- _pre_redirect = 0;
- }
- else if (redirect == _post_redirect) {
- cleanup_post_view();
- _post_redirect = 0;
- }
-}
-
-
-
-void
RouteParams_UI::plugin_going_away (Plugin *plugin, Placement place)
{
ENSURE_GUI_THREAD(bind (mem_fun(*this, &RouteParams_UI::plugin_going_away), plugin, place));
@@ -645,11 +618,11 @@ RouteParams_UI::plugin_going_away (Plugin *plugin, Placement place)
if (place == PreFader) {
cleanup_pre_view (false);
- _pre_redirect = 0;
+ _pre_redirect.reset ((Redirect*) 0);
}
else {
cleanup_post_view (false);
- _post_redirect = 0;
+ _post_redirect.reset ((Redirect*) 0);
}
}
@@ -661,13 +634,13 @@ RouteParams_UI::redirect_going_away (ARDOUR::Redirect *plugin)
printf ("redirect going away\n");
// delete the current view without calling finish
- if (plugin == _pre_redirect) {
+ if (plugin == _pre_redirect.get()) {
cleanup_pre_view (false);
- _pre_redirect = 0;
+ _pre_redirect.reset ((Redirect*) 0);
}
- else if (plugin == _post_redirect) {
+ else if (plugin == _post_redirect.get()) {
cleanup_post_view (false);
- _post_redirect = 0;
+ _post_redirect.reset ((Redirect*) 0);
}
}
diff --git a/gtk2_ardour/route_params_ui.h b/gtk2_ardour/route_params_ui.h
index 96b2041db4..5f487d6e5c 100644
--- a/gtk2_ardour/route_params_ui.h
+++ b/gtk2_ardour/route_params_ui.h
@@ -33,8 +33,9 @@
#include <gtkmm/togglebutton.h>
#include <gtkmm/treeview.h>
+#include <pbd/stateful.h>
+
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
#include <ardour/io.h>
#include <ardour/redirect.h>
@@ -120,14 +121,14 @@ class RouteParams_UI : public ArdourDialog
PluginSelector *_plugin_selector;
RouteRedirectSelection _rr_selection;
- ARDOUR::Route *_route;
+ boost::shared_ptr<ARDOUR::Route> _route;
sigc::connection _route_conn;
sigc::connection _route_ds_conn;
- ARDOUR::Redirect * _pre_redirect;
+ boost::shared_ptr<ARDOUR::Redirect> _pre_redirect;
sigc::connection _pre_plugin_conn;
- ARDOUR::Redirect * _post_redirect;
+ boost::shared_ptr<ARDOUR::Redirect> _post_redirect;
sigc::connection _post_plugin_conn;
@@ -150,7 +151,7 @@ class RouteParams_UI : public ArdourDialog
add(route);
}
Gtk::TreeModelColumn<Glib::ustring> text;
- Gtk::TreeModelColumn<ARDOUR::Route*> route;
+ Gtk::TreeModelColumn<boost::shared_ptr<ARDOUR::Route> > route;
};
RouteDisplayModelColumns route_display_columns ;
@@ -158,10 +159,10 @@ class RouteParams_UI : public ArdourDialog
Glib::RefPtr<Gtk::ListStore> route_display_model;
- void add_route (ARDOUR::Route*);
+ void add_route (boost::shared_ptr<ARDOUR::Route>);
- void route_name_changed (void *src, ARDOUR::Route *route);
- void route_removed (ARDOUR::Route *route);
+ void route_name_changed (void *src, boost::shared_ptr<ARDOUR::Route> route);
+ void route_removed (boost::shared_ptr<ARDOUR::Route> route);
void route_selected();
@@ -179,8 +180,7 @@ class RouteParams_UI : public ArdourDialog
void setup_redirect_boxes();
void cleanup_redirect_boxes();
- void redirect_selected (ARDOUR::Redirect *, ARDOUR::Placement);
- void redirect_unselected (ARDOUR::Redirect *);
+ void redirect_selected (boost::shared_ptr<ARDOUR::Redirect>, ARDOUR::Placement);
void plugin_going_away (ARDOUR::Plugin *foo, ARDOUR::Placement);
void redirect_going_away (ARDOUR::Redirect *foo);
diff --git a/gtk2_ardour/route_redirect_selection.cc b/gtk2_ardour/route_redirect_selection.cc
index 6d315e0aae..76f202dd92 100644
--- a/gtk2_ardour/route_redirect_selection.cc
+++ b/gtk2_ardour/route_redirect_selection.cc
@@ -61,17 +61,6 @@ RouteRedirectSelection::clear ()
void
RouteRedirectSelection::clear_redirects ()
{
- for (RedirectSelection::iterator i = redirects.begin(); i != redirects.end(); ) {
- RedirectSelection::iterator tmp;
-
- tmp = i;
- ++tmp;
-
- delete *i;
-
- i = tmp;
- }
-
redirects.clear ();
RedirectsChanged ();
}
@@ -84,29 +73,32 @@ RouteRedirectSelection::clear_routes ()
}
void
-RouteRedirectSelection::add (Redirect* r)
+RouteRedirectSelection::add (boost::shared_ptr<Redirect> r)
{
if (find (redirects.begin(), redirects.end(), r) == redirects.end()) {
redirects.push_back (r);
-
- void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove;
- r->GoingAway.connect (mem_fun(*this, pmf));
+
+ // XXX SHAREDPTR FIXME
+ // void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove;
+ // r->GoingAway.connect (mem_fun(*this, pmf));
RedirectsChanged();
}
}
void
-RouteRedirectSelection::add (const vector<Redirect*>& rlist)
+RouteRedirectSelection::add (const vector<boost::shared_ptr<Redirect> >& rlist)
{
bool changed = false;
- for (vector<Redirect*>::const_iterator i = rlist.begin(); i != rlist.end(); ++i) {
+ for (vector<boost::shared_ptr<Redirect> >::const_iterator i = rlist.begin(); i != rlist.end(); ++i) {
if (find (redirects.begin(), redirects.end(), *i) == redirects.end()) {
redirects.push_back (*i);
- void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove;
- (*i)->GoingAway.connect (mem_fun(*this, pmf));
+ // XXX SHAREDPTR FIXME
+
+ //void (RouteRedirectSelection::*pmf)(Redirect*) = &RouteRedirectSelection::remove;
+ // (*i)->GoingAway.connect (mem_fun(*this, pmf));
changed = true;
}
}
@@ -117,9 +109,9 @@ RouteRedirectSelection::add (const vector<Redirect*>& rlist)
}
void
-RouteRedirectSelection::remove (Redirect* r)
+RouteRedirectSelection::remove (boost::shared_ptr<Redirect> r)
{
- list<Redirect*>::iterator i;
+ list<boost::shared_ptr<Redirect> >::iterator i;
if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) {
redirects.erase (i);
RedirectsChanged ();
@@ -127,36 +119,37 @@ RouteRedirectSelection::remove (Redirect* r)
}
void
-RouteRedirectSelection::set (Redirect *r)
+RouteRedirectSelection::set (boost::shared_ptr<Redirect> r)
{
clear_redirects ();
add (r);
}
void
-RouteRedirectSelection::set (const vector<Redirect*>& rlist)
+RouteRedirectSelection::set (const vector<boost::shared_ptr<Redirect> >& rlist)
{
clear_redirects ();
add (rlist);
}
void
-RouteRedirectSelection::add (Route* r)
+RouteRedirectSelection::add (boost::shared_ptr<Route> r)
{
if (find (routes.begin(), routes.end(), r) == routes.end()) {
routes.push_back (r);
- void (RouteRedirectSelection::*pmf)(Route*) = &RouteRedirectSelection::remove;
- r->GoingAway.connect (bind (mem_fun(*this, pmf), r));
+ // XXX SHAREDPTR FIXME
+ // void (RouteRedirectSelection::*pmf)(Route*) = &RouteRedirectSelection::remove;
+ // r->GoingAway.connect (bind (mem_fun(*this, pmf), r));
RoutesChanged();
}
}
void
-RouteRedirectSelection::remove (Route* r)
+RouteRedirectSelection::remove (boost::shared_ptr<Route> r)
{
- list<Route*>::iterator i;
+ list<boost::shared_ptr<Route> >::iterator i;
if ((i = find (routes.begin(), routes.end(), r)) != routes.end()) {
routes.erase (i);
RoutesChanged ();
@@ -164,16 +157,16 @@ RouteRedirectSelection::remove (Route* r)
}
void
-RouteRedirectSelection::set (Route *r)
+RouteRedirectSelection::set (boost::shared_ptr<Route> r)
{
clear_routes ();
add (r);
}
bool
-RouteRedirectSelection::selected (Route* ms)
+RouteRedirectSelection::selected (boost::shared_ptr<Route> r)
{
- return find (routes.begin(), routes.end(), ms) != routes.end();
+ return find (routes.begin(), routes.end(), r) != routes.end();
}
bool
diff --git a/gtk2_ardour/route_redirect_selection.h b/gtk2_ardour/route_redirect_selection.h
index 9e2b866171..60d301e762 100644
--- a/gtk2_ardour/route_redirect_selection.h
+++ b/gtk2_ardour/route_redirect_selection.h
@@ -43,20 +43,20 @@ class RouteRedirectSelection : public sigc::trackable
void clear ();
bool empty();
- void set (ARDOUR::Redirect*);
- void set (const std::vector<ARDOUR::Redirect*>&);
- void add (ARDOUR::Redirect*);
- void add (const std::vector<ARDOUR::Redirect*>&);
- void remove (ARDOUR::Redirect*);
+ void set (boost::shared_ptr<ARDOUR::Redirect>);
+ void set (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&);
+ void add (boost::shared_ptr<ARDOUR::Redirect>);
+ void add (const std::vector<boost::shared_ptr<ARDOUR::Redirect> >&);
+ void remove (boost::shared_ptr<ARDOUR::Redirect>);
- void set (ARDOUR::Route*);
- void add (ARDOUR::Route*);
- void remove (ARDOUR::Route*);
+ void set (boost::shared_ptr<ARDOUR::Route>);
+ void add (boost::shared_ptr<ARDOUR::Route>);
+ void remove (boost::shared_ptr<ARDOUR::Route>);
void clear_redirects ();
void clear_routes ();
- bool selected (ARDOUR::Route*);
+ bool selected (boost::shared_ptr<ARDOUR::Route>);
};
bool operator==(const RouteRedirectSelection& a, const RouteRedirectSelection& b);
diff --git a/gtk2_ardour/route_selection.h b/gtk2_ardour/route_selection.h
index 50797deed3..8d5673a2ef 100644
--- a/gtk2_ardour/route_selection.h
+++ b/gtk2_ardour/route_selection.h
@@ -1,12 +1,14 @@
#ifndef __ardour_gtk_route_selection_h__
#define __ardour_gtk_route_selection_h__
+
+#include <boost/shared_ptr.hpp>
#include <list>
namespace ARDOUR {
class Route;
}
-struct RouteSelection : list<ARDOUR::Route*> {};
+struct RouteSelection : std::list<boost::shared_ptr<ARDOUR::Route> > {};
#endif /* __ardour_gtk_route_selection_h__ */
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
new file mode 100644
index 0000000000..8dca7be480
--- /dev/null
+++ b/gtk2_ardour/route_time_axis.cc
@@ -0,0 +1,1601 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <cstdlib>
+#include <cmath>
+#include <cassert>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <sigc++/bind.h>
+
+#include <pbd/error.h>
+#include <pbd/stl_delete.h>
+#include <pbd/whitespace.h>
+
+#include <gtkmm/menu.h>
+#include <gtkmm/menuitem.h>
+#include <gtkmm2ext/gtk_ui.h>
+#include <gtkmm2ext/selector.h>
+#include <gtkmm2ext/stop_signal.h>
+#include <gtkmm2ext/bindable_button.h>
+#include <gtkmm2ext/utils.h>
+
+#include <ardour/playlist.h>
+#include <ardour/diskstream.h>
+#include <ardour/insert.h>
+#include <ardour/ladspa_plugin.h>
+#include <ardour/location.h>
+#include <ardour/panner.h>
+#include <ardour/playlist.h>
+#include <ardour/session.h>
+#include <ardour/session_playlist.h>
+#include <ardour/utils.h>
+
+#include "ardour_ui.h"
+#include "route_time_axis.h"
+#include "automation_time_axis.h"
+#include "redirect_automation_time_axis.h"
+#include "redirect_automation_line.h"
+#include "canvas_impl.h"
+#include "crossfade_view.h"
+#include "enums.h"
+#include "gui_thread.h"
+#include "keyboard.h"
+#include "playlist_selector.h"
+#include "plugin_selector.h"
+#include "plugin_ui.h"
+#include "point_selection.h"
+#include "prompter.h"
+#include "public_editor.h"
+#include "region_view.h"
+#include "rgb_macros.h"
+#include "selection.h"
+#include "simplerect.h"
+#include "streamview.h"
+#include "utils.h"
+
+#include <ardour/track.h>
+
+#include "i18n.h"
+
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Gtk;
+using namespace Editing;
+
+
+RouteTimeAxisView::RouteTimeAxisView (PublicEditor& ed, Session& sess, boost::shared_ptr<Route> rt, Canvas& canvas)
+ : AxisView(sess),
+ RouteUI(rt, sess, _("m"), _("s"), _("r")), // mute, solo, and record
+ TimeAxisView(sess,ed,(TimeAxisView*) 0, canvas),
+ parent_canvas (canvas),
+ button_table (3, 3),
+ edit_group_button (_("g")), // group
+ playlist_button (_("p")),
+ size_button (_("h")), // height
+ automation_button (_("a")),
+ visual_button (_("v"))
+
+{
+ _has_state = true;
+ playlist_menu = 0;
+ playlist_action_menu = 0;
+ automation_action_menu = 0;
+ _view = 0;
+ timestretch_rect = 0;
+ no_redraw = false;
+
+ ignore_toggle = false;
+
+ mute_button->set_active (false);
+ solo_button->set_active (false);
+
+ mute_button->set_name ("TrackMuteButton");
+ solo_button->set_name ("SoloButton");
+ edit_group_button.set_name ("TrackGroupButton");
+ playlist_button.set_name ("TrackPlaylistButton");
+ automation_button.set_name ("TrackAutomationButton");
+ size_button.set_name ("TrackSizeButton");
+ visual_button.set_name ("TrackVisualButton");
+ hide_button.set_name ("TrackRemoveButton");
+
+ hide_button.add (*(manage (new Image (get_xpm("small_x.xpm")))));
+
+ solo_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ mute_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ playlist_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ automation_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ size_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ visual_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ hide_button.signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+
+ solo_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::solo_press), false);
+ solo_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::solo_release), false);
+ mute_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::mute_press), false);
+ mute_button->signal_button_release_event().connect (mem_fun(*this, &RouteUI::mute_release), false);
+ edit_group_button.signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::edit_click), false);
+ playlist_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::playlist_click));
+ automation_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::automation_click));
+ size_button.signal_button_release_event().connect (mem_fun(*this, &RouteTimeAxisView::size_click), false);
+ visual_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::visual_click));
+ hide_button.signal_clicked().connect (mem_fun(*this, &RouteTimeAxisView::hide_click));
+
+ if (is_track()) {
+ rec_enable_button->set_active (false);
+ rec_enable_button->set_name ("TrackRecordEnableButton");
+ rec_enable_button->signal_button_press_event().connect (mem_fun (*this, &RouteTimeAxisView::select_me), false);
+ rec_enable_button->signal_button_press_event().connect (mem_fun(*this, &RouteUI::rec_enable_press));
+ controls_table.attach (*rec_enable_button, 5, 6, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
+ ARDOUR_UI::instance()->tooltips().set_tip(*rec_enable_button, _("Record"));
+ }
+
+ controls_table.attach (*mute_button, 6, 7, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
+ controls_table.attach (*solo_button, 7, 8, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::FILL|Gtk::EXPAND, 0, 0);
+
+ controls_table.attach (edit_group_button, 6, 7, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND, 0, 0);
+
+ ARDOUR_UI::instance()->tooltips().set_tip(*solo_button,_("Solo"));
+ ARDOUR_UI::instance()->tooltips().set_tip(*mute_button,_("Mute"));
+ ARDOUR_UI::instance()->tooltips().set_tip(edit_group_button,_("Edit Group"));
+ ARDOUR_UI::instance()->tooltips().set_tip(size_button,_("Display Height"));
+ ARDOUR_UI::instance()->tooltips().set_tip(playlist_button,_("Playlist"));
+ ARDOUR_UI::instance()->tooltips().set_tip(automation_button, _("Automation"));
+ ARDOUR_UI::instance()->tooltips().set_tip(visual_button, _("Visual options"));
+ ARDOUR_UI::instance()->tooltips().set_tip(hide_button, _("Hide this track"));
+
+ label_view ();
+
+ controls_table.attach (hide_button, 0, 1, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ controls_table.attach (visual_button, 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ controls_table.attach (size_button, 2, 3, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ controls_table.attach (automation_button, 3, 4, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+
+ if (is_track() && track()->mode() == ARDOUR::Normal) {
+ controls_table.attach (playlist_button, 5, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
+ }
+
+ /* remove focus from the buttons */
+
+ automation_button.unset_flags (Gtk::CAN_FOCUS);
+ solo_button->unset_flags (Gtk::CAN_FOCUS);
+ mute_button->unset_flags (Gtk::CAN_FOCUS);
+ edit_group_button.unset_flags (Gtk::CAN_FOCUS);
+ size_button.unset_flags (Gtk::CAN_FOCUS);
+ playlist_button.unset_flags (Gtk::CAN_FOCUS);
+ hide_button.unset_flags (Gtk::CAN_FOCUS);
+ visual_button.unset_flags (Gtk::CAN_FOCUS);
+
+ /* map current state of the route */
+
+ update_diskstream_display ();
+ solo_changed(0);
+ mute_changed(0);
+ //redirects_changed (0);
+ //reset_redirect_automation_curves ();
+ y_position = -1;
+
+ _route->mute_changed.connect (mem_fun(*this, &RouteUI::mute_changed));
+ _route->solo_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
+ _route->redirects_changed.connect (mem_fun(*this, &RouteTimeAxisView::redirects_changed));
+ _route->name_changed.connect (mem_fun(*this, &RouteTimeAxisView::route_name_changed));
+ _route->solo_safe_changed.connect (mem_fun(*this, &RouteUI::solo_changed));
+
+ if (is_track()) {
+
+ track()->FreezeChange.connect (mem_fun(*this, &RouteTimeAxisView::map_frozen));
+ track()->DiskstreamChanged.connect (mem_fun(*this, &RouteTimeAxisView::diskstream_changed));
+ get_diskstream()->SpeedChanged.connect (mem_fun(*this, &RouteTimeAxisView::speed_changed));
+
+ /* ask for notifications of any new RegionViews */
+ // FIXME: _view is NULL, but it would be nice to attach this here :/
+ //_view->RegionViewAdded.connect (mem_fun(*this, &RouteTimeAxisView::region_view_added));
+ //_view->attach ();
+
+ /* pick up the correct freeze state */
+ map_frozen ();
+
+ }
+
+ editor.ZoomChanged.connect (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
+ ColorChanged.connect (mem_fun (*this, &RouteTimeAxisView::color_handler));
+}
+
+RouteTimeAxisView::~RouteTimeAxisView ()
+{
+ GoingAway (); /* EMIT_SIGNAL */
+
+ vector_delete (&redirect_automation_curves);
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+ delete *i;
+ }
+
+ if (playlist_menu) {
+ delete playlist_menu;
+ playlist_menu = 0;
+ }
+
+ if (playlist_action_menu) {
+ delete playlist_action_menu;
+ playlist_action_menu = 0;
+ }
+
+ if (_view) {
+ delete _view;
+ _view = 0;
+ }
+}
+
+void
+RouteTimeAxisView::set_playlist (Playlist *newplaylist)
+{
+ Playlist *pl = playlist();
+ assert(pl);
+
+ modified_connection.disconnect ();
+ state_changed_connection.disconnect ();
+
+ state_changed_connection = pl->StateChanged.connect (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed));
+ modified_connection = pl->Modified.connect (mem_fun(*this, &RouteTimeAxisView::playlist_modified));
+}
+
+void
+RouteTimeAxisView::playlist_modified ()
+{
+}
+
+gint
+RouteTimeAxisView::edit_click (GdkEventButton *ev)
+{
+ if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
+ _route->set_edit_group (0, this);
+ return FALSE;
+ }
+
+ using namespace Menu_Helpers;
+
+ MenuList& items = edit_group_menu.items ();
+ RadioMenuItem::Group group;
+
+ items.clear ();
+ items.push_back (RadioMenuElem (group, _("No group"),
+ bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), (RouteGroup *) 0)));
+
+ if (_route->edit_group() == 0) {
+ static_cast<RadioMenuItem*>(&items.back())->set_active ();
+ }
+
+ _session.foreach_edit_group (bind (mem_fun (*this, &RouteTimeAxisView::add_edit_group_menu_item), &group));
+ edit_group_menu.popup (ev->button, ev->time);
+
+ return FALSE;
+}
+
+void
+RouteTimeAxisView::add_edit_group_menu_item (RouteGroup *eg, RadioMenuItem::Group* group)
+{
+ using namespace Menu_Helpers;
+
+ MenuList &items = edit_group_menu.items();
+
+ cerr << "adding edit group " << eg->name() << endl;
+
+ items.push_back (RadioMenuElem (*group, eg->name(), bind (mem_fun(*this, &RouteTimeAxisView::set_edit_group_from_menu), eg)));
+ if (_route->edit_group() == eg) {
+ static_cast<RadioMenuItem*>(&items.back())->set_active ();
+ }
+}
+
+void
+RouteTimeAxisView::set_edit_group_from_menu (RouteGroup *eg)
+
+{
+ _route->set_edit_group (eg, this);
+}
+
+void
+RouteTimeAxisView::playlist_state_changed (Change ignored)
+{
+ // ENSURE_GUI_THREAD (bind (mem_fun(*this, &RouteTimeAxisView::playlist_state_changed), ignored));
+ // why are we here ?
+}
+
+void
+RouteTimeAxisView::playlist_changed ()
+
+{
+ label_view ();
+
+ if (is_track()) {
+ set_playlist (dynamic_cast<Playlist*>(get_diskstream()->playlist()));
+ }
+}
+
+void
+RouteTimeAxisView::label_view ()
+{
+ string x = _route->name();
+
+ if (x != name_entry.get_text()) {
+ name_entry.set_text (x);
+ }
+
+ ARDOUR_UI::instance()->tooltips().set_tip (name_entry, x);
+}
+
+void
+RouteTimeAxisView::route_name_changed (void *src)
+{
+ editor.route_name_changed (this);
+ label_view ();
+}
+
+void
+RouteTimeAxisView::take_name_changed (void *src)
+
+{
+ if (src != this) {
+ label_view ();
+ }
+}
+
+void
+RouteTimeAxisView::playlist_click ()
+{
+ // always build a new action menu
+
+ if (playlist_action_menu == 0) {
+ playlist_action_menu = new Menu;
+ playlist_action_menu->set_name ("ArdourContextMenu");
+ }
+
+ build_playlist_menu(playlist_action_menu);
+
+ playlist_action_menu->popup (1, 0);
+}
+
+void
+RouteTimeAxisView::automation_click ()
+{
+ if (automation_action_menu == 0) {
+ /* this seems odd, but the automation action
+ menu is built as part of the display menu.
+ */
+ build_display_menu ();
+ }
+ automation_action_menu->popup (1, 0);
+}
+
+void
+RouteTimeAxisView::build_automation_action_menu ()
+{
+ using namespace Menu_Helpers;
+
+ automation_action_menu = manage (new Menu);
+ MenuList& automation_items = automation_action_menu->items();
+ automation_action_menu->set_name ("ArdourContextMenu");
+
+ automation_items.push_back (MenuElem (_("Show all automation"),
+ mem_fun(*this, &RouteTimeAxisView::show_all_automation)));
+
+ automation_items.push_back (MenuElem (_("Show existing automation"),
+ mem_fun(*this, &RouteTimeAxisView::show_existing_automation)));
+
+ automation_items.push_back (MenuElem (_("Hide all automation"),
+ mem_fun(*this, &RouteTimeAxisView::hide_all_automation)));
+
+ automation_items.push_back (MenuElem (_("Plugins"), subplugin_menu));
+}
+
+void
+RouteTimeAxisView::build_display_menu ()
+{
+ using namespace Menu_Helpers;
+
+ /* get the size menu ready */
+
+ build_size_menu ();
+
+ /* prepare it */
+
+ TimeAxisView::build_display_menu ();
+
+ /* now fill it with our stuff */
+
+ MenuList& items = display_menu->items();
+ display_menu->set_name ("ArdourContextMenu");
+
+ items.push_back (MenuElem (_("Height"), *size_menu));
+ items.push_back (MenuElem (_("Color"), mem_fun(*this, &RouteTimeAxisView::select_track_color)));
+
+ items.push_back (SeparatorElem());
+
+ build_remote_control_menu ();
+ items.push_back (MenuElem (_("Remote Control ID"), *remote_control_menu));
+
+ build_automation_action_menu ();
+ items.push_back (MenuElem (_("Automation"), *automation_action_menu));
+
+ // Hook for derived classes to add type specific stuff
+ items.push_back (SeparatorElem());
+ append_extra_display_menu_items ();
+ items.push_back (SeparatorElem());
+
+ if (is_track()) {
+
+ Menu* alignment_menu = manage (new Menu);
+ MenuList& alignment_items = alignment_menu->items();
+ alignment_menu->set_name ("ArdourContextMenu");
+
+ RadioMenuItem::Group align_group;
+
+ alignment_items.push_back (RadioMenuElem (align_group, _("Align with existing material"),
+ bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), ExistingMaterial)));
+ align_existing_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
+ if (get_diskstream()->alignment_style() == ExistingMaterial)
+ align_existing_item->set_active();
+
+ alignment_items.push_back (RadioMenuElem (align_group, _("Align with capture time"),
+ bind (mem_fun(*this, &RouteTimeAxisView::set_align_style), CaptureTime)));
+ align_capture_item = dynamic_cast<RadioMenuItem*>(&alignment_items.back());
+ if (get_diskstream()->alignment_style() == CaptureTime)
+ align_capture_item->set_active();
+
+ items.push_back (MenuElem (_("Alignment"), *alignment_menu));
+
+ get_diskstream()->AlignmentStyleChanged.connect (
+ mem_fun(*this, &RouteTimeAxisView::align_style_changed));
+ }
+
+ items.push_back (SeparatorElem());
+ items.push_back (CheckMenuElem (_("Active"), mem_fun(*this, &RouteUI::toggle_route_active)));
+ route_active_menu_item = dynamic_cast<CheckMenuItem *> (&items.back());
+ route_active_menu_item->set_active (_route->active());
+
+ items.push_back (SeparatorElem());
+ items.push_back (MenuElem (_("Remove"), mem_fun(*this, &RouteUI::remove_this_route)));
+}
+
+
+void
+RouteTimeAxisView::show_timestretch (jack_nframes_t start, jack_nframes_t end)
+{
+ double x1;
+ double x2;
+ double y2;
+
+ TimeAxisView::show_timestretch (start, end);
+
+ hide_timestretch ();
+
+#if 0
+ if (ts.empty()) {
+ return;
+ }
+
+
+ /* check that the time selection was made in our route, or our edit group.
+ remember that edit_group() == 0 implies the route is *not* in a edit group.
+ */
+
+ if (!(ts.track == this || (ts.group != 0 && ts.group == _route->edit_group()))) {
+ /* this doesn't apply to us */
+ return;
+ }
+
+ /* ignore it if our edit group is not active */
+
+ if ((ts.track != this) && _route->edit_group() && !_route->edit_group()->is_active()) {
+ return;
+ }
+#endif
+
+ if (timestretch_rect == 0) {
+ timestretch_rect = new SimpleRect (*canvas_display);
+ timestretch_rect->property_x1() = 0.0;
+ timestretch_rect->property_y1() = 0.0;
+ timestretch_rect->property_x2() = 0.0;
+ timestretch_rect->property_y2() = 0.0;
+ timestretch_rect->property_fill_color_rgba() = color_map[cTimeStretchFill];
+ timestretch_rect->property_outline_color_rgba() = color_map[cTimeStretchOutline];
+ }
+
+ timestretch_rect->show ();
+ timestretch_rect->raise_to_top ();
+
+ x1 = start / editor.get_current_zoom();
+ x2 = (end - 1) / editor.get_current_zoom();
+ y2 = height - 2;
+
+ timestretch_rect->property_x1() = x1;
+ timestretch_rect->property_y1() = 1.0;
+ timestretch_rect->property_x2() = x2;
+ timestretch_rect->property_y2() = y2;
+}
+
+void
+RouteTimeAxisView::hide_timestretch ()
+{
+ TimeAxisView::hide_timestretch ();
+
+ if (timestretch_rect) {
+ timestretch_rect->hide ();
+ }
+}
+
+void
+RouteTimeAxisView::show_selection (TimeSelection& ts)
+{
+
+#if 0
+ /* ignore it if our edit group is not active or if the selection was started
+ in some other track or edit group (remember that edit_group() == 0 means
+ that the track is not in an edit group).
+ */
+
+ if (((ts.track != this && !is_child (ts.track)) && _route->edit_group() && !_route->edit_group()->is_active()) ||
+ (!(ts.track == this || is_child (ts.track) || (ts.group != 0 && ts.group == _route->edit_group())))) {
+ hide_selection ();
+ return;
+ }
+#endif
+
+ TimeAxisView::show_selection (ts);
+}
+
+void
+RouteTimeAxisView::set_height (TrackHeight h)
+{
+ bool height_changed = (height == 0) || (h != height_style);
+
+ TimeAxisView::set_height (h);
+
+ ensure_xml_node ();
+
+ _view->set_height ((double) height);
+
+ switch (height_style) {
+ case Largest:
+ xml_node->add_property ("track_height", "largest");
+ break;
+
+ case Large:
+ xml_node->add_property ("track_height", "large");
+ break;
+
+ case Larger:
+ xml_node->add_property ("track_height", "larger");
+ break;
+
+ case Normal:
+ xml_node->add_property ("track_height", "normal");
+ break;
+
+ case Smaller:
+ xml_node->add_property ("track_height", "smaller");
+ break;
+
+ case Small:
+ xml_node->add_property ("track_height", "small");
+ break;
+ }
+
+ switch (height_style) {
+ case Largest:
+ case Large:
+ case Larger:
+ case Normal:
+ show_name_entry ();
+ hide_name_label ();
+
+ mute_button->show_all();
+ solo_button->show_all();
+ if (rec_enable_button)
+ rec_enable_button->show_all();
+
+ edit_group_button.show_all();
+ hide_button.show_all();
+ visual_button.show_all();
+ size_button.show_all();
+ automation_button.show_all();
+
+ if (is_track() && track()->mode() == ARDOUR::Normal) {
+ playlist_button.show_all();
+ }
+ break;
+
+ case Smaller:
+ show_name_entry ();
+ hide_name_label ();
+
+ mute_button->show_all();
+ solo_button->show_all();
+ if (rec_enable_button)
+ rec_enable_button->show_all();
+
+ edit_group_button.hide ();
+ hide_button.hide ();
+ visual_button.hide ();
+ size_button.hide ();
+ automation_button.hide ();
+
+ if (is_track() && track()->mode() == ARDOUR::Normal) {
+ playlist_button.hide ();
+ }
+ break;
+
+ case Small:
+ hide_name_entry ();
+ show_name_label ();
+
+ mute_button->hide();
+ solo_button->hide();
+ if (rec_enable_button)
+ rec_enable_button->hide();
+
+ edit_group_button.hide ();
+ hide_button.hide ();
+ visual_button.hide ();
+ size_button.hide ();
+ automation_button.hide ();
+ playlist_button.hide ();
+ name_label.set_text (_route->name());
+ break;
+ }
+
+ if (height_changed) {
+ /* only emit the signal if the height really changed */
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+ }
+}
+
+void
+RouteTimeAxisView::select_track_color ()
+{
+ if (RouteUI::choose_color ()) {
+
+ if (_view) {
+ _view->apply_color (_color, StreamView::RegionColor);
+ }
+ }
+}
+
+void
+RouteTimeAxisView::reset_samples_per_unit ()
+{
+ set_samples_per_unit (editor.get_current_zoom());
+}
+
+void
+RouteTimeAxisView::set_samples_per_unit (double spu)
+{
+ double speed = 1.0;
+
+ if (get_diskstream() != 0) {
+ speed = get_diskstream()->speed();
+ }
+
+ if (_view) {
+ _view->set_samples_per_unit (spu * speed);
+ }
+
+ TimeAxisView::set_samples_per_unit (spu * speed);
+}
+
+void
+RouteTimeAxisView::align_style_changed ()
+{
+ switch (get_diskstream()->alignment_style()) {
+ case ExistingMaterial:
+ if (!align_existing_item->get_active()) {
+ align_existing_item->set_active();
+ }
+ break;
+ case CaptureTime:
+ if (!align_capture_item->get_active()) {
+ align_capture_item->set_active();
+ }
+ break;
+ }
+}
+
+void
+RouteTimeAxisView::set_align_style (AlignStyle style)
+{
+ get_diskstream()->set_align_style (style);
+}
+
+void
+RouteTimeAxisView::rename_current_playlist ()
+{
+ ArdourPrompter prompter (true);
+ string name;
+
+ Diskstream *const ds = get_diskstream();
+ if (!ds || ds->destructive())
+ return;
+
+ Playlist *const pl = ds->playlist();
+ if (!pl)
+ return;
+
+ prompter.set_prompt (_("Name for playlist"));
+ prompter.set_initial_text (pl->name());
+ prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
+ prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+
+ switch (prompter.run ()) {
+ case Gtk::RESPONSE_ACCEPT:
+ prompter.get_result (name);
+ if (name.length()) {
+ pl->set_name (name);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+RouteTimeAxisView::use_copy_playlist (bool prompt)
+{
+ string name;
+
+ Diskstream *const ds = get_diskstream();
+ if (!ds || ds->destructive())
+ return;
+
+ Playlist *const pl = ds->playlist();
+ if (!pl)
+ return;
+
+ name = Playlist::bump_name (pl->name(), _session);
+
+ if (prompt) {
+
+ ArdourPrompter prompter (true);
+
+ prompter.set_prompt (_("Name for Playlist"));
+ prompter.set_initial_text (name);
+ prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
+ prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+ prompter.show_all ();
+
+ switch (prompter.run ()) {
+ case Gtk::RESPONSE_ACCEPT:
+ prompter.get_result (name);
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ if (name.length()) {
+ ds->use_copy_playlist ();
+ pl->set_name (name);
+ }
+}
+
+void
+RouteTimeAxisView::use_new_playlist (bool prompt)
+{
+ string name;
+
+ Diskstream *const ds = get_diskstream();
+ if (!ds || ds->destructive())
+ return;
+
+ Playlist *const pl = ds->playlist();
+ if (!pl)
+ return;
+
+ name = Playlist::bump_name (pl->name(), _session);
+
+ if (prompt) {
+
+ ArdourPrompter prompter (true);
+
+ prompter.set_prompt (_("Name for Playlist"));
+ prompter.set_initial_text (name);
+ prompter.add_button (Gtk::Stock::NEW, Gtk::RESPONSE_ACCEPT);
+ prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
+
+ switch (prompter.run ()) {
+ case Gtk::RESPONSE_ACCEPT:
+ prompter.get_result (name);
+ break;
+
+ default:
+ return;
+ }
+ }
+
+ if (name.length()) {
+ ds->use_new_playlist ();
+ pl->set_name (name);
+ }
+}
+
+void
+RouteTimeAxisView::clear_playlist ()
+{
+ Diskstream *const ds = get_diskstream();
+ if (!ds || ds->destructive())
+ return;
+
+ Playlist *const pl = ds->playlist();
+ if (!pl)
+ return;
+
+ editor.clear_playlist (*pl);
+}
+
+void
+RouteTimeAxisView::speed_changed ()
+{
+ Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::reset_samples_per_unit));
+}
+
+void
+RouteTimeAxisView::diskstream_changed ()
+{
+ Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &RouteTimeAxisView::update_diskstream_display));
+}
+
+void
+RouteTimeAxisView::update_diskstream_display ()
+{
+ if (!get_diskstream()) // bus
+ return;
+
+ set_playlist (get_diskstream()->playlist());
+ map_frozen ();
+}
+
+void
+RouteTimeAxisView::selection_click (GdkEventButton* ev)
+{
+ PublicEditor::TrackViewList* tracks = editor.get_valid_views (this, _route->edit_group());
+
+ switch (Keyboard::selection_type (ev->state)) {
+ case Selection::Toggle:
+ /* XXX this is not right */
+ editor.get_selection().add (*tracks);
+ break;
+
+ case Selection::Set:
+ editor.get_selection().set (*tracks);
+ break;
+
+ case Selection::Extend:
+ /* not defined yet */
+ break;
+ }
+
+ delete tracks;
+}
+
+void
+RouteTimeAxisView::set_selected_points (PointSelection& points)
+{
+ for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+ (*i)->set_selected_points (points);
+ }
+}
+
+void
+RouteTimeAxisView::set_selected_regionviews (RegionSelection& regions)
+{
+ _view->set_selected_regionviews (regions);
+}
+
+void
+RouteTimeAxisView::get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable*>& results)
+{
+ double speed = 1.0;
+
+ if (get_diskstream() != 0) {
+ speed = get_diskstream()->speed();
+ }
+
+ jack_nframes_t start_adjusted = session_frame_to_track_frame(start, speed);
+ jack_nframes_t end_adjusted = session_frame_to_track_frame(end, speed);
+
+ if (_view && ((top < 0.0 && bot < 0.0)) || touched (top, bot)) {
+ _view->get_selectables (start_adjusted, end_adjusted, results);
+ }
+
+ /* pick up visible automation tracks */
+
+ for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+ if (!(*i)->hidden()) {
+ (*i)->get_selectables (start_adjusted, end_adjusted, top, bot, results);
+ }
+ }
+}
+
+void
+RouteTimeAxisView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
+{
+ if (_view) {
+ _view->get_inverted_selectables (sel, results);
+ }
+
+ for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+ if (!(*i)->hidden()) {
+ (*i)->get_inverted_selectables (sel, results);
+ }
+ }
+
+ return;
+}
+
+RouteGroup*
+RouteTimeAxisView::edit_group() const
+{
+ return _route->edit_group();
+}
+
+string
+RouteTimeAxisView::name() const
+{
+ return _route->name();
+}
+
+Playlist *
+RouteTimeAxisView::playlist () const
+{
+ Diskstream *ds;
+
+ if ((ds = get_diskstream()) != 0) {
+ return ds->playlist();
+ } else {
+ return 0;
+ }
+}
+
+void
+RouteTimeAxisView::name_entry_changed ()
+{
+ string x;
+
+ x = name_entry.get_text ();
+
+ if (x == _route->name()) {
+ return;
+ }
+
+ if (x.length() == 0) {
+ name_entry.set_text (_route->name());
+ return;
+ }
+
+ strip_whitespace_edges(x);
+
+ if (_session.route_name_unique (x)) {
+ _route->set_name (x, this);
+ } else {
+ ARDOUR_UI::instance()->popup_error (_("a track already exists with that name"));
+ name_entry.set_text (_route->name());
+ }
+}
+
+void
+RouteTimeAxisView::visual_click ()
+{
+ popup_display_menu (0);
+}
+
+void
+RouteTimeAxisView::hide_click ()
+{
+ editor.hide_track_in_display (*this);
+}
+
+Region*
+RouteTimeAxisView::find_next_region (jack_nframes_t pos, RegionPoint point, int32_t dir)
+{
+ Diskstream *stream;
+ Playlist *playlist;
+
+ if ((stream = get_diskstream()) != 0 && (playlist = stream->playlist()) != 0) {
+ return playlist->find_next_region (pos, point, dir);
+ }
+
+ return 0;
+}
+
+bool
+RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
+{
+ Playlist* what_we_got;
+ Diskstream* ds = get_diskstream();
+ Playlist* playlist;
+ bool ret = false;
+
+ if (ds == 0) {
+ /* route is a bus, not a track */
+ return false;
+ }
+
+ playlist = ds->playlist();
+
+
+ TimeSelection time (selection.time);
+ float speed = ds->speed();
+ if (speed != 1.0f) {
+ for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) {
+ (*i).start = session_frame_to_track_frame((*i).start, speed);
+ (*i).end = session_frame_to_track_frame((*i).end, speed);
+ }
+ }
+
+ switch (op) {
+ case Cut:
+ _session.add_undo (playlist->get_memento());
+ if ((what_we_got = playlist->cut (time)) != 0) {
+ editor.get_cut_buffer().add (what_we_got);
+ _session.add_redo_no_execute (playlist->get_memento());
+ ret = true;
+ }
+ break;
+ case Copy:
+ if ((what_we_got = playlist->copy (time)) != 0) {
+ editor.get_cut_buffer().add (what_we_got);
+ }
+ break;
+
+ case Clear:
+ _session.add_undo (playlist->get_memento());
+ if ((what_we_got = playlist->cut (time)) != 0) {
+ _session.add_redo_no_execute (playlist->get_memento());
+ what_we_got->unref ();
+ ret = true;
+ }
+ break;
+ }
+
+ return ret;
+}
+
+bool
+RouteTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection, size_t nth)
+{
+ if (!is_track()) {
+ return false;
+ }
+
+ Playlist* playlist = get_diskstream()->playlist();
+ PlaylistSelection::iterator p;
+
+ for (p = selection.playlists.begin(); p != selection.playlists.end() && nth; ++p, --nth);
+
+ if (p == selection.playlists.end()) {
+ return false;
+ }
+
+ if (get_diskstream()->speed() != 1.0f)
+ pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
+
+ _session.add_undo (playlist->get_memento());
+ playlist->paste (**p, pos, times);
+ _session.add_redo_no_execute (playlist->get_memento());
+
+ return true;
+}
+
+
+list<TimeAxisView*>
+RouteTimeAxisView::get_child_list()
+{
+
+ list<TimeAxisView*>redirect_children;
+
+ for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+ if (!(*i)->hidden()) {
+ redirect_children.push_back(*i);
+ }
+ }
+ return redirect_children;
+}
+
+
+void
+RouteTimeAxisView::build_playlist_menu (Gtk::Menu * menu)
+{
+ using namespace Menu_Helpers;
+
+ if (!menu || !is_track()) {
+ return;
+ }
+
+ MenuList& playlist_items = menu->items();
+ menu->set_name ("ArdourContextMenu");
+ playlist_items.clear();
+
+ if (playlist_menu) {
+ delete playlist_menu;
+ }
+ playlist_menu = new Menu;
+ playlist_menu->set_name ("ArdourContextMenu");
+
+ playlist_items.push_back (MenuElem (string_compose (_("Current: %1"), get_diskstream()->playlist()->name())));
+ playlist_items.push_back (SeparatorElem());
+
+ playlist_items.push_back (MenuElem (_("Rename"), mem_fun(*this, &RouteTimeAxisView::rename_current_playlist)));
+ playlist_items.push_back (SeparatorElem());
+
+ playlist_items.push_back (MenuElem (_("New"), mem_fun(editor, &PublicEditor::new_playlists)));
+ playlist_items.push_back (MenuElem (_("New Copy"), mem_fun(editor, &PublicEditor::copy_playlists)));
+ playlist_items.push_back (SeparatorElem());
+ playlist_items.push_back (MenuElem (_("Clear Current"), mem_fun(editor, &PublicEditor::clear_playlists)));
+ playlist_items.push_back (SeparatorElem());
+ playlist_items.push_back (MenuElem(_("Select"), mem_fun(*this, &RouteTimeAxisView::show_playlist_selector)));
+
+}
+
+void
+RouteTimeAxisView::show_playlist_selector ()
+{
+ editor.playlist_selector().show_for (this);
+}
+
+void
+RouteTimeAxisView::map_frozen ()
+{
+ if (!is_track()) {
+ return;
+ }
+
+ ENSURE_GUI_THREAD (mem_fun(*this, &RouteTimeAxisView::map_frozen));
+
+ switch (track()->freeze_state()) {
+ case Track::Frozen:
+ playlist_button.set_sensitive (false);
+ rec_enable_button->set_sensitive (false);
+ break;
+ default:
+ playlist_button.set_sensitive (true);
+ rec_enable_button->set_sensitive (true);
+ break;
+ }
+}
+
+void
+RouteTimeAxisView::color_handler (ColorID id, uint32_t val)
+{
+ switch (id) {
+ case cTimeStretchOutline:
+ timestretch_rect->property_outline_color_rgba() = val;
+ break;
+ case cTimeStretchFill:
+ timestretch_rect->property_fill_color_rgba() = val;
+ break;
+ default:
+ break;
+ }
+}
+
+bool
+RouteTimeAxisView::select_me (GdkEventButton* ev)
+{
+ editor.get_selection().add (this);
+ return false;
+}
+
+void
+RouteTimeAxisView::show_all_automation ()
+{
+ no_redraw = true;
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+ for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
+ if ((*ii)->view == 0) {
+ add_redirect_automation_curve ((*i)->redirect, (*ii)->what);
+ }
+
+ (*ii)->menu_item->set_active (true);
+ }
+ }
+
+ no_redraw = false;
+
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+}
+
+void
+RouteTimeAxisView::show_existing_automation ()
+{
+ no_redraw = true;
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+ for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
+ if ((*ii)->view != 0) {
+ (*ii)->menu_item->set_active (true);
+ }
+ }
+ }
+
+ no_redraw = false;
+
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+}
+
+void
+RouteTimeAxisView::hide_all_automation ()
+{
+ no_redraw = true;
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+ for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
+ (*ii)->menu_item->set_active (false);
+ }
+ }
+
+ no_redraw = false;
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+}
+
+
+void
+RouteTimeAxisView::region_view_added (RegionView* rv)
+{
+ for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
+ AutomationTimeAxisView* atv;
+
+ if ((atv = dynamic_cast<AutomationTimeAxisView*> (*i)) != 0) {
+ rv->add_ghost (*atv);
+ }
+ }
+}
+
+void
+RouteTimeAxisView::add_ghost_to_redirect (RegionView* rv, AutomationTimeAxisView* atv)
+{
+ rv->add_ghost (*atv);
+}
+
+RouteTimeAxisView::RedirectAutomationInfo::~RedirectAutomationInfo ()
+{
+ for (vector<RedirectAutomationNode*>::iterator i = lines.begin(); i != lines.end(); ++i) {
+ delete *i;
+ }
+}
+
+
+RouteTimeAxisView::RedirectAutomationNode::~RedirectAutomationNode ()
+{
+ parent.remove_ran (this);
+
+ if (view) {
+ delete view;
+ }
+}
+
+void
+RouteTimeAxisView::remove_ran (RedirectAutomationNode* ran)
+{
+ if (ran->view) {
+ remove_child (ran->view);
+ }
+}
+
+RouteTimeAxisView::RedirectAutomationNode*
+RouteTimeAxisView::find_redirect_automation_node (boost::shared_ptr<Redirect> redirect, uint32_t what)
+{
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+
+ if ((*i)->redirect == redirect) {
+
+ for (vector<RedirectAutomationNode*>::iterator ii = (*i)->lines.begin(); ii != (*i)->lines.end(); ++ii) {
+ if ((*ii)->what == what) {
+ return *ii;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+// FIXME: duplicated in midi_time_axis.cc
+static string
+legalize_for_xml_node (string str)
+{
+ string::size_type pos;
+ string legal_chars = "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_+=:";
+ string legal;
+
+ legal = str;
+ pos = 0;
+
+ while ((pos = legal.find_first_not_of (legal_chars, pos)) != string::npos) {
+ legal.replace (pos, 1, "_");
+ pos += 1;
+ }
+
+ return legal;
+}
+
+
+void
+RouteTimeAxisView::add_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
+{
+ RedirectAutomationLine* ral;
+ string name;
+ RedirectAutomationNode* ran;
+
+ if ((ran = find_redirect_automation_node (redirect, what)) == 0) {
+ fatal << _("programming error: ")
+ << string_compose (X_("redirect automation curve for %1:%2 not registered with audio track!"),
+ redirect->name(), what)
+ << endmsg;
+ /*NOTREACHED*/
+ return;
+ }
+
+ if (ran->view) {
+ return;
+ }
+
+ name = redirect->describe_parameter (what);
+
+ /* create a string that is a legal XML node name that can be used to refer to this redirect+port combination */
+
+ char state_name[256];
+ snprintf (state_name, sizeof (state_name), "Redirect-%s-%" PRIu32, legalize_for_xml_node (redirect->name()).c_str(), what);
+
+ ran->view = new RedirectAutomationTimeAxisView (_session, _route, editor, *this, parent_canvas, name, what, *redirect, state_name);
+
+ ral = new RedirectAutomationLine (name,
+ *redirect, what, _session, *ran->view,
+ *ran->view->canvas_display, redirect->automation_list (what));
+
+ ral->set_line_color (color_map[cRedirectAutomationLine]);
+ ral->queue_reset ();
+
+ ran->view->add_line (*ral);
+
+ ran->view->Hiding.connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_automation_track_hidden), ran, redirect));
+
+ if (!ran->view->marked_for_display()) {
+ ran->view->hide ();
+ } else {
+ ran->menu_item->set_active (true);
+ }
+
+ add_child (ran->view);
+
+ _view->foreach_regionview (bind (mem_fun(*this, &RouteTimeAxisView::add_ghost_to_redirect), ran->view));
+
+ redirect->mark_automation_visible (what, true);
+}
+
+void
+RouteTimeAxisView::redirect_automation_track_hidden (RouteTimeAxisView::RedirectAutomationNode* ran, boost::shared_ptr<Redirect> r)
+{
+ if (!_hidden) {
+ ran->menu_item->set_active (false);
+ }
+
+ r->mark_automation_visible (ran->what, false);
+
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+}
+
+void
+RouteTimeAxisView::add_existing_redirect_automation_curves (boost::shared_ptr<Redirect> redirect)
+{
+ set<uint32_t> s;
+ RedirectAutomationLine *ral;
+
+ redirect->what_has_visible_automation (s);
+
+ for (set<uint32_t>::iterator i = s.begin(); i != s.end(); ++i) {
+
+ if ((ral = find_redirect_automation_curve (redirect, *i)) != 0) {
+ ral->queue_reset ();
+ } else {
+ add_redirect_automation_curve (redirect, (*i));
+ }
+ }
+}
+
+void
+RouteTimeAxisView::add_redirect_to_subplugin_menu (boost::shared_ptr<Redirect> r)
+{
+ using namespace Menu_Helpers;
+ RedirectAutomationInfo *rai;
+ list<RedirectAutomationInfo*>::iterator x;
+
+ const std::set<uint32_t>& automatable = r->what_can_be_automated ();
+ std::set<uint32_t> has_visible_automation;
+
+ r->what_has_visible_automation(has_visible_automation);
+
+ if (automatable.empty()) {
+ return;
+ }
+
+ for (x = redirect_automation.begin(); x != redirect_automation.end(); ++x) {
+ if ((*x)->redirect == r) {
+ break;
+ }
+ }
+
+ if (x == redirect_automation.end()) {
+
+ rai = new RedirectAutomationInfo (r);
+ redirect_automation.push_back (rai);
+
+ } else {
+
+ rai = *x;
+
+ }
+
+ /* any older menu was deleted at the top of redirects_changed()
+ when we cleared the subplugin menu.
+ */
+
+ rai->menu = manage (new Menu);
+ MenuList& items = rai->menu->items();
+ rai->menu->set_name ("ArdourContextMenu");
+
+ items.clear ();
+
+ for (std::set<uint32_t>::const_iterator i = automatable.begin(); i != automatable.end(); ++i) {
+
+ RedirectAutomationNode* ran;
+ CheckMenuItem* mitem;
+
+ string name = r->describe_parameter (*i);
+
+ items.push_back (CheckMenuElem (name));
+ mitem = dynamic_cast<CheckMenuItem*> (&items.back());
+
+ if (has_visible_automation.find((*i)) != has_visible_automation.end()) {
+ mitem->set_active(true);
+ }
+
+ if ((ran = find_redirect_automation_node (r, *i)) == 0) {
+
+ /* new item */
+
+ ran = new RedirectAutomationNode (*i, mitem, *this);
+
+ rai->lines.push_back (ran);
+
+ } else {
+
+ ran->menu_item = mitem;
+
+ }
+
+ mitem->signal_toggled().connect (bind (mem_fun(*this, &RouteTimeAxisView::redirect_menu_item_toggled), rai, ran));
+ }
+
+ /* add the menu for this redirect, because the subplugin
+ menu is always cleared at the top of redirects_changed().
+ this is the result of some poor design in gtkmm and/or
+ GTK+.
+ */
+
+ subplugin_menu.items().push_back (MenuElem (r->name(), *rai->menu));
+ rai->valid = true;
+}
+
+void
+RouteTimeAxisView::redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo* rai,
+ RouteTimeAxisView::RedirectAutomationNode* ran)
+{
+ bool showit = ran->menu_item->get_active();
+ bool redraw = false;
+
+ if (ran->view == 0 && showit) {
+ add_redirect_automation_curve (rai->redirect, ran->what);
+ redraw = true;
+ }
+
+ if (showit != ran->view->marked_for_display()) {
+
+ if (showit) {
+ ran->view->set_marked_for_display (true);
+ ran->view->canvas_display->show();
+ } else {
+ rai->redirect->mark_automation_visible (ran->what, true);
+ ran->view->set_marked_for_display (false);
+ ran->view->hide ();
+ }
+
+ redraw = true;
+
+ }
+
+ if (redraw && !no_redraw) {
+
+ /* now trigger a redisplay */
+
+ _route->gui_changed ("track_height", (void *) 0); /* EMIT_SIGNAL */
+
+ }
+}
+
+void
+RouteTimeAxisView::redirects_changed (void *src)
+{
+ using namespace Menu_Helpers;
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ++i) {
+ (*i)->valid = false;
+ }
+
+ subplugin_menu.items().clear ();
+
+ _route->foreach_redirect (this, &RouteTimeAxisView::add_redirect_to_subplugin_menu);
+ _route->foreach_redirect (this, &RouteTimeAxisView::add_existing_redirect_automation_curves);
+
+ for (list<RedirectAutomationInfo*>::iterator i = redirect_automation.begin(); i != redirect_automation.end(); ) {
+
+ list<RedirectAutomationInfo*>::iterator tmp;
+
+ tmp = i;
+ ++tmp;
+
+ if (!(*i)->valid) {
+
+ delete *i;
+ redirect_automation.erase (i);
+
+ }
+
+ i = tmp;
+ }
+
+ /* change in visibility was possible */
+
+ _route->gui_changed ("track_height", this);
+}
+
+RedirectAutomationLine *
+RouteTimeAxisView::find_redirect_automation_curve (boost::shared_ptr<Redirect> redirect, uint32_t what)
+{
+ RedirectAutomationNode* ran;
+
+ if ((ran = find_redirect_automation_node (redirect, what)) != 0) {
+ if (ran->view) {
+ return dynamic_cast<RedirectAutomationLine*> (ran->view->lines.front());
+ }
+ }
+
+ return 0;
+}
+
+void
+RouteTimeAxisView::reset_redirect_automation_curves ()
+{
+ for (vector<RedirectAutomationLine*>::iterator i = redirect_automation_curves.begin(); i != redirect_automation_curves.end(); ++i) {
+ (*i)->reset();
+ }
+}
+
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
new file mode 100644
index 0000000000..d305fd390c
--- /dev/null
+++ b/gtk2_ardour/route_time_axis.h
@@ -0,0 +1,256 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: audio_time_axis.h 664 2006-07-05 19:47:25Z drobilla $
+*/
+
+#ifndef __ardour_route_time_axis_h__
+#define __ardour_route_time_axis_h__
+
+#include <gtkmm/table.h>
+#include <gtkmm/button.h>
+#include <gtkmm/box.h>
+#include <gtkmm/menu.h>
+#include <gtkmm/menuitem.h>
+#include <gtkmm/radiomenuitem.h>
+#include <gtkmm/checkmenuitem.h>
+
+#include <gtkmm2ext/selector.h>
+#include <list>
+
+#include <ardour/types.h>
+
+#include "ardour_dialog.h"
+#include "route_ui.h"
+#include "enums.h"
+#include "time_axis_view.h"
+#include "canvas.h"
+#include "color.h"
+
+namespace ARDOUR {
+ class Session;
+ class Region;
+ class Diskstream;
+ class RouteGroup;
+ class Redirect;
+ class Insert;
+ class Location;
+ class Playlist;
+}
+
+class PublicEditor;
+class RegionView;
+class StreamView;
+class Selection;
+class RegionSelection;
+class Selectable;
+class AutomationTimeAxisView;
+class AutomationLine;
+class RedirectAutomationLine;
+class TimeSelection;
+
+class RouteTimeAxisView : public RouteUI, public TimeAxisView
+{
+public:
+ RouteTimeAxisView (PublicEditor&, ARDOUR::Session&, boost::shared_ptr<ARDOUR::Route>, ArdourCanvas::Canvas& canvas);
+ virtual ~RouteTimeAxisView ();
+
+ void show_selection (TimeSelection&);
+
+ void set_samples_per_unit (double);
+ void set_height (TimeAxisView::TrackHeight);
+ void show_timestretch (jack_nframes_t start, jack_nframes_t end);
+ void hide_timestretch ();
+ void selection_click (GdkEventButton*);
+ void set_selected_points (PointSelection&);
+ void set_selected_regionviews (RegionSelection&);
+ void get_selectables (jack_nframes_t start, jack_nframes_t end, double top, double bot, list<Selectable *>&);
+ void get_inverted_selectables (Selection&, list<Selectable*>&);
+
+ ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir);
+
+ /* Editing operations */
+ bool cut_copy_clear (Selection&, Editing::CutCopyOp);
+ bool paste (jack_nframes_t, float times, Selection&, size_t nth);
+
+ list<TimeAxisView*> get_child_list();
+
+ /* The editor calls these when mapping an operation across multiple tracks */
+ void use_new_playlist (bool prompt);
+ void use_copy_playlist (bool prompt);
+ void clear_playlist ();
+
+ void build_playlist_menu (Gtk::Menu *);
+
+ string name() const;
+ StreamView* view() const { return _view; }
+ ARDOUR::RouteGroup* edit_group() const;
+ ARDOUR::Playlist* playlist() const;
+
+protected:
+ friend class StreamView;
+
+ struct RedirectAutomationNode {
+ uint32_t what;
+ Gtk::CheckMenuItem* menu_item;
+ AutomationTimeAxisView* view;
+ RouteTimeAxisView& parent;
+
+ RedirectAutomationNode (uint32_t w, Gtk::CheckMenuItem* mitem, RouteTimeAxisView& p)
+ : what (w), menu_item (mitem), view (0), parent (p) {}
+
+ ~RedirectAutomationNode ();
+ };
+
+ struct RedirectAutomationInfo {
+ boost::shared_ptr<ARDOUR::Redirect> redirect;
+ bool valid;
+ Gtk::Menu* menu;
+ vector<RedirectAutomationNode*> lines;
+
+ RedirectAutomationInfo (boost::shared_ptr<ARDOUR::Redirect> r)
+ : redirect (r), valid (true), menu (0) {}
+
+ ~RedirectAutomationInfo ();
+ };
+
+
+ void diskstream_changed ();
+ void update_diskstream_display ();
+
+ gint edit_click (GdkEventButton *);
+
+ void build_redirect_window ();
+ void redirect_click ();
+ void redirect_add ();
+ void redirect_remove ();
+ void redirect_edit ();
+ void redirect_relist ();
+ void redirect_row_selected (gint row, gint col, GdkEvent *ev);
+ void add_to_redirect_display (ARDOUR::Redirect *);
+ void redirects_changed (void *);
+
+ void add_redirect_to_subplugin_menu (boost::shared_ptr<ARDOUR::Redirect>);
+ void remove_ran (RedirectAutomationNode* ran);
+
+ void redirect_menu_item_toggled (RouteTimeAxisView::RedirectAutomationInfo*,
+ RouteTimeAxisView::RedirectAutomationNode*);
+
+ void redirect_automation_track_hidden (RedirectAutomationNode*,
+ boost::shared_ptr<ARDOUR::Redirect>);
+
+ RedirectAutomationNode*
+ find_redirect_automation_node (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
+
+ RedirectAutomationLine*
+ find_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
+
+ void add_redirect_automation_curve (boost::shared_ptr<ARDOUR::Redirect> r, uint32_t);
+ void add_existing_redirect_automation_curves (boost::shared_ptr<ARDOUR::Redirect>);
+
+ void reset_redirect_automation_curves ();
+
+ void update_automation_view (ARDOUR::AutomationType);
+
+ void take_name_changed (void *);
+ void route_name_changed (void *);
+ void name_entry_changed ();
+
+ void on_area_realize ();
+
+ virtual void label_view ();
+
+ void add_edit_group_menu_item (ARDOUR::RouteGroup *, Gtk::RadioMenuItem::Group*);
+ void set_edit_group_from_menu (ARDOUR::RouteGroup *);
+
+ void reset_samples_per_unit ();
+
+ void select_track_color();
+
+ virtual void build_automation_action_menu ();
+ virtual void append_extra_display_menu_items () {}
+ void build_display_menu ();
+
+ void align_style_changed ();
+ void set_align_style (ARDOUR::AlignStyle);
+
+ virtual void set_playlist (ARDOUR::Playlist *);
+ void playlist_click ();
+ void show_playlist_selector ();
+ void playlist_changed ();
+ void playlist_state_changed (ARDOUR::Change);
+ void playlist_modified ();
+
+ void add_playlist_to_playlist_menu (ARDOUR::Playlist*);
+ void rename_current_playlist ();
+
+ void automation_click ();
+ virtual void show_all_automation ();
+ virtual void show_existing_automation ();
+ virtual void hide_all_automation ();
+
+ void timestretch (jack_nframes_t start, jack_nframes_t end);
+
+ void visual_click ();
+ void hide_click ();
+ gint when_displayed (GdkEventAny*);
+
+ void speed_changed ();
+
+ void map_frozen ();
+
+ void color_handler (ColorID, uint32_t);
+ bool select_me (GdkEventButton*);
+
+ void region_view_added (RegionView*);
+ void add_ghost_to_redirect (RegionView*, AutomationTimeAxisView*);
+
+
+ StreamView* _view;
+ ArdourCanvas::Canvas& parent_canvas;
+ bool no_redraw;
+
+ Gtk::HBox other_button_hbox;
+ Gtk::Table button_table;
+ Gtk::Button redirect_button;
+ Gtk::Button edit_group_button;
+ Gtk::Button playlist_button;
+ Gtk::Button size_button;
+ Gtk::Button automation_button;
+ Gtk::Button hide_button;
+ Gtk::Button visual_button;
+
+ Gtk::Menu subplugin_menu;
+ Gtk::Menu* automation_action_menu;
+ Gtk::Menu edit_group_menu;
+ Gtk::RadioMenuItem* align_existing_item;
+ Gtk::RadioMenuItem* align_capture_item;
+ Gtk::Menu* playlist_menu;
+ Gtk::Menu* playlist_action_menu;
+ Gtk::MenuItem* playlist_item;
+
+ ArdourCanvas::SimpleRect* timestretch_rect;
+
+ list<RedirectAutomationInfo*> redirect_automation;
+ vector<RedirectAutomationLine*> redirect_automation_curves;
+
+ sigc::connection modified_connection;
+ sigc::connection state_changed_connection;
+};
+
+#endif /* __ardour_route_time_axis_h__ */
+
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 988d6c8b19..8a1fb1c21a 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2002 Paul Davis
+ Copyright (C) 2002-2006 Paul Davis
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
@@ -21,8 +21,8 @@
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/stop_signal.h>
#include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/bindable_button.h>
#include <gtkmm2ext/doi.h>
+#include <gtkmm2ext/bindable_button.h>
#include <ardour/route_group.h>
#include <pbd/memento_command.h>
@@ -45,9 +45,9 @@ using namespace ARDOUR;
using namespace PBD;
-RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name,
+RouteUI::RouteUI (boost::shared_ptr<ARDOUR::Route> rt, ARDOUR::Session& sess, const char* m_name,
const char* s_name, const char* r_name)
- : AxisView(sess),
+ : AxisView(sess),
_route(rt),
mute_button(0),
solo_button(0),
@@ -65,35 +65,31 @@ RouteUI::RouteUI (ARDOUR::Route& rt, ARDOUR::Session& sess, const char* m_name,
set_color (unique_random_color());
}
- _route.GoingAway.connect (mem_fun (*this, &RouteUI::route_removed));
- _route.active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed));
+ _route->GoingAway.connect (mem_fun (*this, &RouteUI::route_removed));
+ _route->active_changed.connect (mem_fun (*this, &RouteUI::route_active_changed));
- mute_button = manage (new BindableToggleButton (& _route.midi_mute_control(), m_name ));
- mute_button->set_bind_button_state (2, GDK_CONTROL_MASK);
- solo_button = manage (new BindableToggleButton (& _route.midi_solo_control(), s_name ));
- solo_button->set_bind_button_state (2, GDK_CONTROL_MASK);
-
- if (is_audio_track()) {
- AudioTrack* at = dynamic_cast<AudioTrack*>(&_route);
+ mute_button = manage (new BindableToggleButton (_route->mute_control(), m_name ));
+ solo_button = manage (new BindableToggleButton (_route->solo_control(), s_name ));
+
+ if (is_track()) {
+ boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track>(_route);
- get_diskstream()->record_enable_changed.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed));
+ t->diskstream().RecordEnableChanged.connect (mem_fun (*this, &RouteUI::route_rec_enable_changed));
_session.RecordStateChanged.connect (mem_fun (*this, &RouteUI::session_rec_enable_changed));
- rec_enable_button = manage (new BindableToggleButton (& at->midi_rec_enable_control(), r_name ));
- rec_enable_button->set_bind_button_state (2, GDK_CONTROL_MASK);
+ rec_enable_button = manage (new BindableToggleButton (t->rec_enable_control(), r_name ));
- } else {
- rec_enable_button = manage (new BindableToggleButton (0, r_name ));
- }
+ rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
+
+ update_rec_display ();
+ }
mute_button->unset_flags (Gtk::CAN_FOCUS);
solo_button->unset_flags (Gtk::CAN_FOCUS);
- rec_enable_button->unset_flags (Gtk::CAN_FOCUS);
/* map the current state */
- update_rec_display ();
map_frozen ();
}
@@ -146,14 +142,14 @@ RouteUI::mute_press(GdkEventButton* ev)
*/
if (ev->button == 1) {
- set_mix_group_mute (_route, !_route.muted());
+ set_mix_group_mute (_route, !_route->muted());
}
} else {
/* plain click applies change to this route */
- reversibly_apply_route_boolean ("mute change", &Route::set_mute, !_route.muted(), this);
+ reversibly_apply_route_boolean ("mute change", &Route::set_mute, !_route->muted(), this);
}
}
}
@@ -231,7 +227,7 @@ RouteUI::solo_press(GdkEventButton* ev)
// shift-click: set this route to solo safe
- _route.set_solo_safe (!_route.solo_safe(), this);
+ _route->set_solo_safe (!_route->solo_safe(), this);
wait_for_release = false;
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
@@ -241,14 +237,14 @@ RouteUI::solo_press(GdkEventButton* ev)
*/
if (ev->button == 1) {
- set_mix_group_solo (_route, !_route.soloed());
+ set_mix_group_solo (_route, !_route->soloed());
}
} else {
/* click: solo this route */
- reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route.soloed(), this);
+ reversibly_apply_route_boolean ("solo change", &Route::set_solo, !_route->soloed(), this);
}
}
}
@@ -276,7 +272,7 @@ RouteUI::solo_release(GdkEventButton* ev)
gint
RouteUI::rec_enable_press(GdkEventButton* ev)
{
- if (!ignore_toggle && is_audio_track()) {
+ if (!ignore_toggle && is_track() && rec_enable_button) {
if (ev->button == 2 && Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
// do nothing on midi bind event
@@ -298,7 +294,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
- set_mix_group_rec_enable (_route, !_route.record_enabled());
+ set_mix_group_rec_enable (_route, !_route->record_enabled());
} else {
@@ -326,7 +322,7 @@ RouteUI::update_solo_display ()
{
bool x;
- if (solo_button->get_active() != (x = _route.soloed())){
+ if (solo_button->get_active() != (x = _route->soloed())){
ignore_toggle = true;
solo_button->set_active(x);
ignore_toggle = false;
@@ -334,7 +330,7 @@ RouteUI::update_solo_display ()
/* show solo safe */
- if (_route.solo_safe()){
+ if (_route->solo_safe()){
solo_button->set_name(safe_solo_button_name());
} else {
solo_button->set_name(solo_button_name());
@@ -352,7 +348,7 @@ RouteUI::update_mute_display ()
{
bool x;
- if (mute_button->get_active() != (x = _route.muted())){
+ if (mute_button->get_active() != (x = _route->muted())){
ignore_toggle = true;
mute_button->set_active(x);
ignore_toggle = false;
@@ -360,7 +356,7 @@ RouteUI::update_mute_display ()
}
void
-RouteUI::route_rec_enable_changed (void *src)
+RouteUI::route_rec_enable_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &RouteUI::update_rec_display));
}
@@ -374,7 +370,7 @@ RouteUI::session_rec_enable_changed ()
void
RouteUI::update_rec_display ()
{
- bool model = _route.record_enabled();
+ bool model = _route->record_enabled();
bool view = rec_enable_button->get_active();
/* first make sure the button's "depressed" visual
@@ -440,7 +436,7 @@ RouteUI::refresh_remote_control_menu ()
limit += 4; /* leave some breathing room */
rc_items.push_back (RadioMenuElem (rc_group, _("None")));
- if (_route.remote_control_id() == 0) {
+ if (_route->remote_control_id() == 0) {
rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
rc_active->set_active ();
}
@@ -449,7 +445,7 @@ RouteUI::refresh_remote_control_menu ()
snprintf (buf, sizeof (buf), "%u", i);
rc_items.push_back (RadioMenuElem (rc_group, buf));
rc_active = dynamic_cast<RadioMenuItem*>(&rc_items.back());
- if (_route.remote_control_id() == i) {
+ if (_route->remote_control_id() == i) {
rc_active = dynamic_cast<CheckMenuItem*> (&rc_items.back());
rc_active->set_active ();
}
@@ -467,7 +463,7 @@ RouteUI::set_remote_control_id (uint32_t id, CheckMenuItem* item)
*/
if (item->get_active()) {
- _route.set_remote_control_id (id);
+ _route->set_remote_control_id (id);
}
}
@@ -482,14 +478,14 @@ RouteUI::build_solo_menu (void)
CheckMenuItem* check;
check = new CheckMenuItem(_("Solo-safe"));
- check->set_active (_route.solo_safe());
+ check->set_active (_route->solo_safe());
check->signal_toggled().connect (bind (mem_fun (*this, &RouteUI::toggle_solo_safe), check));
- _route.solo_safe_changed.connect(bind (mem_fun (*this, &RouteUI::solo_safe_toggle), check));
+ _route->solo_safe_changed.connect(bind (mem_fun (*this, &RouteUI::solo_safe_toggle), check));
items.push_back (CheckMenuElem(*check));
check->show_all();
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
+ // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
}
@@ -506,39 +502,39 @@ RouteUI::build_mute_menu(void)
check = new CheckMenuItem(_("Pre Fader"));
init_mute_menu(PRE_FADER, check);
check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), PRE_FADER, check));
- _route.pre_fader_changed.connect(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), check));
+ _route->pre_fader_changed.connect(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), check));
items.push_back (CheckMenuElem(*check));
check->show_all();
check = new CheckMenuItem(_("Post Fader"));
init_mute_menu(POST_FADER, check);
check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), POST_FADER, check));
- _route.post_fader_changed.connect(bind (mem_fun (*this, &RouteUI::post_fader_toggle), check));
+ _route->post_fader_changed.connect(bind (mem_fun (*this, &RouteUI::post_fader_toggle), check));
items.push_back (CheckMenuElem(*check));
check->show_all();
check = new CheckMenuItem(_("Control Outs"));
init_mute_menu(CONTROL_OUTS, check);
check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), CONTROL_OUTS, check));
- _route.control_outs_changed.connect(bind (mem_fun (*this, &RouteUI::control_outs_toggle), check));
+ _route->control_outs_changed.connect(bind (mem_fun (*this, &RouteUI::control_outs_toggle), check));
items.push_back (CheckMenuElem(*check));
check->show_all();
check = new CheckMenuItem(_("Main Outs"));
init_mute_menu(MAIN_OUTS, check);
check->signal_toggled().connect(bind (mem_fun (*this, &RouteUI::toggle_mute_menu), MAIN_OUTS, check));
- _route.main_outs_changed.connect(bind (mem_fun (*this, &RouteUI::main_outs_toggle), check));
+ _route->main_outs_changed.connect(bind (mem_fun (*this, &RouteUI::main_outs_toggle), check));
items.push_back (CheckMenuElem(*check));
check->show_all();
items.push_back (SeparatorElem());
- items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
+ // items.push_back (MenuElem (_("MIDI Bind"), mem_fun (*mute_button, &BindableToggleButton::midi_learn)));
}
void
RouteUI::init_mute_menu(mute_type type, CheckMenuItem* check)
{
- if (_route.get_mute_config (type)) {
+ if (_route->get_mute_config (type)) {
check->set_active (true);
}
}
@@ -546,21 +542,21 @@ RouteUI::init_mute_menu(mute_type type, CheckMenuItem* check)
void
RouteUI::toggle_mute_menu(mute_type type, Gtk::CheckMenuItem* check)
{
- _route.set_mute_config(type, check->get_active(), this);
+ _route->set_mute_config(type, check->get_active(), this);
}
void
RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
{
- _route.set_solo_safe (check->get_active(), this);
+ _route->set_solo_safe (check->get_active(), this);
}
void
-RouteUI::set_mix_group_solo(Route& route, bool yn)
+RouteUI::set_mix_group_solo(boost::shared_ptr<Route> route, bool yn)
{
RouteGroup* mix_group;
- if((mix_group = route.mix_group()) != 0){
+ if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group solo change"));
Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
mix_group->apply(&Route::set_solo, yn, this);
@@ -568,7 +564,7 @@ RouteUI::set_mix_group_solo(Route& route, bool yn)
_session.add_command (cmd);
_session.commit_reversible_command ();
} else {
- reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route.soloed(), this);
+ reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route->soloed(), this);
}
}
@@ -595,11 +591,11 @@ RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*f
}
void
-RouteUI::set_mix_group_mute(Route& route, bool yn)
+RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn)
{
RouteGroup* mix_group;
- if((mix_group = route.mix_group()) != 0){
+ if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group mute change"));
Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand (_session, this);
mix_group->apply(&Route::set_mute, yn, this);
@@ -607,16 +603,16 @@ RouteUI::set_mix_group_mute(Route& route, bool yn)
_session.add_command(cmd);
_session.commit_reversible_command ();
} else {
- reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route.muted(), this);
+ reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route->muted(), this);
}
}
void
-RouteUI::set_mix_group_rec_enable(Route& route, bool yn)
+RouteUI::set_mix_group_rec_enable(boost::shared_ptr<Route> route, bool yn)
{
RouteGroup* mix_group;
- if((mix_group = route.mix_group()) != 0){
+ if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group rec-enable change"));
Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
mix_group->apply (&Route::set_record_enable, yn, this);
@@ -624,7 +620,7 @@ RouteUI::set_mix_group_rec_enable(Route& route, bool yn)
_session.add_command(cmd);
_session.commit_reversible_command ();
} else {
- reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route.record_enabled(), this);
+ reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route->record_enabled(), this);
}
}
@@ -655,7 +651,7 @@ RouteUI::set_color (const Gdk::Color & c)
snprintf (buf, sizeof (buf), "%d:%d:%d", c.get_red(), c.get_green(), c.get_blue());
xml_node->add_property ("color", buf);
- _route.gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
+ _route->gui_changed ("color", (void *) 0); /* EMIT_SIGNAL */
}
@@ -663,9 +659,9 @@ void
RouteUI::ensure_xml_node ()
{
if (xml_node == 0) {
- if ((xml_node = _route.extra_xml ("GUI")) == 0) {
+ if ((xml_node = _route->extra_xml ("GUI")) == 0) {
xml_node = new XMLNode ("GUI");
- _route.add_extra_xml (*xml_node);
+ _route->add_extra_xml (*xml_node);
}
}
}
@@ -710,10 +706,10 @@ RouteUI::remove_this_route ()
vector<string> choices;
string prompt;
- if (is_audio_track()) {
- prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route.name());
+ if (is_track()) {
+ prompt = string_compose (_("Do you really want to remove track \"%1\" ?\n\nYou may also lose the playlist used by this track.\n(cannot be undone)"), _route->name());
} else {
- prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route.name());
+ prompt = string_compose (_("Do you really want to remove bus \"%1\" ?\n(cannot be undone)"), _route->name());
}
choices.push_back (_("No, do nothing."));
@@ -747,7 +743,7 @@ RouteUI::route_rename ()
ArdourPrompter name_prompter (true);
string result;
name_prompter.set_prompt (_("New Name: "));
- name_prompter.set_initial_text (_route.name());
+ name_prompter.set_initial_text (_route->name());
name_prompter.add_button (_("Rename"), Gtk::RESPONSE_ACCEPT);
name_prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
name_prompter.show_all ();
@@ -757,7 +753,7 @@ RouteUI::route_rename ()
case Gtk::RESPONSE_ACCEPT:
name_prompter.get_result (result);
if (result.length()) {
- _route.set_name (result, this);
+ _route->set_name (result, this);
}
break;
}
@@ -771,7 +767,7 @@ RouteUI::name_changed (void *src)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::name_changed), src));
- name_label.set_text (_route.name());
+ name_label.set_text (_route->name());
}
void
@@ -780,8 +776,8 @@ RouteUI::toggle_route_active ()
bool yn;
if (route_active_menu_item) {
- if (route_active_menu_item->get_active() != (yn = _route.active())) {
- _route.set_active (!yn);
+ if (route_active_menu_item->get_active() != (yn = _route->active())) {
+ _route->set_active (!yn);
}
}
}
@@ -790,7 +786,7 @@ void
RouteUI::route_active_changed ()
{
if (route_active_menu_item) {
- Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*route_active_menu_item, &CheckMenuItem::set_active), _route.active()));
+ Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*route_active_menu_item, &CheckMenuItem::set_active), _route->active()));
}
}
@@ -803,12 +799,12 @@ RouteUI::toggle_polarity ()
ENSURE_GUI_THREAD(mem_fun (*this, &RouteUI::toggle_polarity));
- if ((x = polarity_menu_item->get_active()) != _route.phase_invert()) {
- _route.set_phase_invert (x, this);
+ if ((x = polarity_menu_item->get_active()) != _route->phase_invert()) {
+ _route->set_phase_invert (x, this);
if (x) {
name_label.set_text (X_("Ø ") + name_label.get_text());
} else {
- name_label.set_text (_route.name());
+ name_label.set_text (_route->name());
}
}
}
@@ -823,7 +819,7 @@ RouteUI::polarity_changed ()
void
RouteUI::solo_safe_toggle(void* src, Gtk::CheckMenuItem* check)
{
- bool yn = _route.solo_safe ();
+ bool yn = _route->solo_safe ();
if (check->get_active() != yn) {
check->set_active (yn);
@@ -834,7 +830,7 @@ RouteUI::pre_fader_toggle(void* src, Gtk::CheckMenuItem* check)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::pre_fader_toggle), src, check));
- bool yn = _route.get_mute_config(PRE_FADER);
+ bool yn = _route->get_mute_config(PRE_FADER);
if (check->get_active() != yn) {
check->set_active (yn);
}
@@ -845,7 +841,7 @@ RouteUI::post_fader_toggle(void* src, Gtk::CheckMenuItem* check)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::post_fader_toggle), src, check));
- bool yn = _route.get_mute_config(POST_FADER);
+ bool yn = _route->get_mute_config(POST_FADER);
if (check->get_active() != yn) {
check->set_active (yn);
}
@@ -856,7 +852,7 @@ RouteUI::control_outs_toggle(void* src, Gtk::CheckMenuItem* check)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::control_outs_toggle), src, check));
- bool yn = _route.get_mute_config(CONTROL_OUTS);
+ bool yn = _route->get_mute_config(CONTROL_OUTS);
if (check->get_active() != yn) {
check->set_active (yn);
}
@@ -867,7 +863,7 @@ RouteUI::main_outs_toggle(void* src, Gtk::CheckMenuItem* check)
{
ENSURE_GUI_THREAD(bind (mem_fun (*this, &RouteUI::main_outs_toggle), src, check));
- bool yn = _route.get_mute_config(MAIN_OUTS);
+ bool yn = _route->get_mute_config(MAIN_OUTS);
if (check->get_active() != yn) {
check->set_active (yn);
}
@@ -876,42 +872,55 @@ RouteUI::main_outs_toggle(void* src, Gtk::CheckMenuItem* check)
void
RouteUI::disconnect_input ()
{
- _route.disconnect_inputs (this);
+ _route->disconnect_inputs (this);
}
void
RouteUI::disconnect_output ()
{
- _route.disconnect_outputs (this);
+ _route->disconnect_outputs (this);
+}
+
+bool
+RouteUI::is_track () const
+{
+ return dynamic_cast<Track*>(_route.get()) != 0;
+}
+
+Track*
+RouteUI::track() const
+{
+ return dynamic_cast<Track*>(_route.get());
}
bool
RouteUI::is_audio_track () const
{
- return dynamic_cast<AudioTrack*>(&_route) != 0;
+ return dynamic_cast<AudioTrack*>(_route.get()) != 0;
+}
+
+AudioTrack*
+RouteUI::audio_track() const
+{
+ return dynamic_cast<AudioTrack*>(_route.get());
}
-AudioDiskstream*
+Diskstream*
RouteUI::get_diskstream () const
{
- AudioTrack *at;
+ boost::shared_ptr<Track> t;
- if ((at = dynamic_cast<AudioTrack*>(&_route)) != 0) {
- return &at->disk_stream();
+ if ((t = boost::dynamic_pointer_cast<Track>(_route)) != 0) {
+ return &t->diskstream();
} else {
return 0;
}
}
-AudioTrack*
-RouteUI::audio_track() const
-{
- return dynamic_cast<AudioTrack*>(&_route);
-}
string
RouteUI::name() const
{
- return _route.name();
+ return _route->name();
}
void
@@ -919,7 +928,7 @@ RouteUI::map_frozen ()
{
ENSURE_GUI_THREAD (mem_fun (*this, &RouteUI::map_frozen));
- AudioTrack* at = dynamic_cast<AudioTrack*>(&_route);
+ AudioTrack* at = dynamic_cast<AudioTrack*>(_route.get());
if (at) {
switch (at->freeze_state()) {
@@ -932,3 +941,4 @@ RouteUI::map_frozen ()
}
}
}
+
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index 69c9b7f5a9..7415eddad6 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -26,13 +26,10 @@
#include <pbd/xml++.h>
#include <ardour/ardour.h>
#include <ardour/route.h>
+#include <ardour/track.h>
#include "axis_view.h"
-namespace Gtkmm2ext {
- class BindableToggleButton;
-}
-
namespace ARDOUR {
class AudioTrack;
}
@@ -43,21 +40,30 @@ namespace Gtk {
class Widget;
}
+class BindableToggleButton;
+
class RouteUI : public virtual AxisView
{
public:
- RouteUI(ARDOUR::Route&, ARDOUR::Session&, const char*, const char*, const char*);
+ RouteUI(boost::shared_ptr<ARDOUR::Route>, ARDOUR::Session&, const char*, const char*, const char*);
virtual ~RouteUI();
+ bool is_track() const;
bool is_audio_track() const;
- ARDOUR::AudioDiskstream* get_diskstream() const;
- ARDOUR::Route& route() const { return _route; }
+ boost::shared_ptr<ARDOUR::Route> route() const { return _route; }
+
+ // FIXME: make these return shared_ptr
+ ARDOUR::Track* track() const;
ARDOUR::AudioTrack* audio_track() const;
+
+ ARDOUR::Diskstream* get_diskstream() const;
string name() const;
-
- ARDOUR::Route& _route;
+
+ // protected: XXX sigh this should be here
+
+ boost::shared_ptr<ARDOUR::Route> _route;
void set_color (const Gdk::Color & c);
bool choose_color ();
@@ -65,9 +71,9 @@ class RouteUI : public virtual AxisView
bool ignore_toggle;
bool wait_for_release;
- Gtkmm2ext::BindableToggleButton * mute_button;
- Gtkmm2ext::BindableToggleButton * solo_button;
- Gtkmm2ext::BindableToggleButton * rec_enable_button;
+ BindableToggleButton* mute_button;
+ BindableToggleButton* solo_button;
+ BindableToggleButton* rec_enable_button;
virtual string solo_button_name () const { return "SoloButton"; }
virtual string safe_solo_button_name () const { return "SafeSoloButton"; }
@@ -89,7 +95,8 @@ class RouteUI : public virtual AxisView
void solo_changed(void*);
void mute_changed(void*);
- void route_rec_enable_changed(void*);
+ virtual void redirects_changed (void *) {}
+ void route_rec_enable_changed();
void session_rec_enable_changed();
void build_solo_menu (void);
@@ -108,9 +115,9 @@ class RouteUI : public virtual AxisView
void build_mute_menu(void);
void init_mute_menu(ARDOUR::mute_type, Gtk::CheckMenuItem*);
- void set_mix_group_solo(ARDOUR::Route&, bool);
- void set_mix_group_mute(ARDOUR::Route&, bool);
- void set_mix_group_rec_enable(ARDOUR::Route&, bool);
+ void set_mix_group_solo(boost::shared_ptr<ARDOUR::Route>, bool);
+ void set_mix_group_mute(boost::shared_ptr<ARDOUR::Route>, bool);
+ void set_mix_group_rec_enable(boost::shared_ptr<ARDOUR::Route>, bool);
int set_color_from_route ();
diff --git a/gtk2_ardour/selectable.h b/gtk2_ardour/selectable.h
index b4be7090e2..b52214c9c9 100644
--- a/gtk2_ardour/selectable.h
+++ b/gtk2_ardour/selectable.h
@@ -34,7 +34,7 @@ class Selectable : public virtual sigc::trackable
virtual void set_selected (bool yn) {
if (yn != _selected) {
- _selected = true;
+ _selected = yn;
Selected (_selected); /* EMIT_SIGNAL */
}
}
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index 2e4ed8a117..086d878994 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -24,7 +24,7 @@
#include <ardour/playlist.h>
-#include "regionview.h"
+#include "region_view.h"
#include "selection.h"
#include "selection_templates.h"
#include "time_axis_view.h"
@@ -46,7 +46,7 @@ Selection&
Selection::operator= (const Selection& other)
{
if (&other != this) {
- audio_regions = other.audio_regions;
+ regions = other.regions;
tracks = other.tracks;
time = other.time;
lines = other.lines;
@@ -57,7 +57,7 @@ Selection::operator= (const Selection& other)
bool
operator== (const Selection& a, const Selection& b)
{
- return a.audio_regions == b.audio_regions &&
+ return a.regions == b.regions &&
a.tracks == b.tracks &&
a.time.track == b.time.track &&
a.time.group == b.time.group &&
@@ -71,7 +71,7 @@ void
Selection::clear ()
{
clear_tracks ();
- clear_audio_regions ();
+ clear_regions ();
clear_points ();
clear_lines();
clear_time ();
@@ -83,8 +83,8 @@ void
Selection::dump_region_layers()
{
cerr << "region selection layer dump" << endl;
- for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- cerr << "layer: " << (int)(*i)->region.layer() << endl;
+ for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
+ cerr << "layer: " << (int)(*i)->region().layer() << endl;
}
}
@@ -99,10 +99,10 @@ Selection::clear_redirects ()
}
void
-Selection::clear_audio_regions ()
+Selection::clear_regions ()
{
- if (!audio_regions.empty()) {
- audio_regions.clear_all ();
+ if (!regions.empty()) {
+ regions.clear_all ();
RegionsChanged();
}
}
@@ -151,7 +151,7 @@ Selection::clear_lines ()
}
void
-Selection::toggle (Redirect* r)
+Selection::toggle (boost::shared_ptr<Redirect> r)
{
RedirectSelection::iterator i;
@@ -196,29 +196,29 @@ Selection::toggle (TimeAxisView* track)
}
void
-Selection::toggle (AudioRegionView* r)
+Selection::toggle (RegionView* r)
{
- AudioRegionSelection::iterator i;
+ RegionSelection::iterator i;
- if ((i = find (audio_regions.begin(), audio_regions.end(), r)) == audio_regions.end()) {
- audio_regions.add (r);
+ if ((i = find (regions.begin(), regions.end(), r)) == regions.end()) {
+ regions.add (r);
} else {
- audio_regions.erase (i);
+ regions.erase (i);
}
RegionsChanged ();
}
void
-Selection::toggle (vector<AudioRegionView*>& r)
+Selection::toggle (vector<RegionView*>& r)
{
- AudioRegionSelection::iterator i;
+ RegionSelection::iterator i;
- for (vector<AudioRegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
- if ((i = find (audio_regions.begin(), audio_regions.end(), (*x))) == audio_regions.end()) {
- audio_regions.add ((*x));
+ for (vector<RegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
+ if ((i = find (regions.begin(), regions.end(), (*x))) == regions.end()) {
+ regions.add ((*x));
} else {
- audio_regions.erase (i);
+ regions.erase (i);
}
}
@@ -243,7 +243,7 @@ Selection::toggle (jack_nframes_t start, jack_nframes_t end)
void
-Selection::add (Redirect* r)
+Selection::add (boost::shared_ptr<Redirect> r)
{
if (find (redirects.begin(), redirects.end(), r) == redirects.end()) {
redirects.push_back (r);
@@ -310,22 +310,22 @@ Selection::add (TimeAxisView* track)
}
void
-Selection::add (AudioRegionView* r)
+Selection::add (RegionView* r)
{
- if (find (audio_regions.begin(), audio_regions.end(), r) == audio_regions.end()) {
- audio_regions.add (r);
+ if (find (regions.begin(), regions.end(), r) == regions.end()) {
+ regions.add (r);
RegionsChanged ();
}
}
void
-Selection::add (vector<AudioRegionView*>& v)
+Selection::add (vector<RegionView*>& v)
{
bool changed = false;
- for (vector<AudioRegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
- if (find (audio_regions.begin(), audio_regions.end(), (*i)) == audio_regions.end()) {
- audio_regions.add ((*i));
+ for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
+ if (find (regions.begin(), regions.end(), (*i)) == regions.end()) {
+ regions.add ((*i));
changed = true;
}
}
@@ -381,9 +381,9 @@ Selection::add (AutomationList* ac)
}
void
-Selection::remove (Redirect* r)
+Selection::remove (boost::shared_ptr<Redirect> r)
{
- list<Redirect*>::iterator i;
+ RedirectSelection::iterator i;
if ((i = find (redirects.begin(), redirects.end(), r)) != redirects.end()) {
redirects.erase (i);
RedirectsChanged ();
@@ -451,9 +451,9 @@ Selection::remove (const list<Playlist*>& pllist)
}
void
-Selection::remove (AudioRegionView* r)
+Selection::remove (RegionView* r)
{
- audio_regions.remove (r);
+ regions.remove (r);
RegionsChanged ();
}
@@ -491,7 +491,7 @@ Selection::remove (AutomationList *ac)
}
void
-Selection::set (Redirect *r)
+Selection::set (boost::shared_ptr<Redirect> r)
{
clear_redirects ();
add (r);
@@ -526,17 +526,16 @@ Selection::set (const list<Playlist*>& pllist)
}
void
-Selection::set (AudioRegionView* r)
+Selection::set (RegionView* r)
{
- clear_audio_regions ();
+ clear_regions ();
add (r);
}
void
-Selection::set (vector<AudioRegionView*>& v)
+Selection::set (vector<RegionView*>& v)
{
-
- clear_audio_regions ();
+ clear_regions ();
// make sure to deselect any automation selections
clear_points();
add (v);
@@ -590,15 +589,15 @@ Selection::selected (TimeAxisView* tv)
}
bool
-Selection::selected (AudioRegionView* arv)
+Selection::selected (RegionView* rv)
{
- return find (audio_regions.begin(), audio_regions.end(), arv) != audio_regions.end();
+ return find (regions.begin(), regions.end(), rv) != regions.end();
}
bool
Selection::empty ()
{
- return audio_regions.empty () &&
+ return regions.empty () &&
tracks.empty () &&
points.empty () &&
playlists.empty () &&
@@ -612,7 +611,7 @@ Selection::empty ()
void
Selection::set (list<Selectable*>& selectables)
{
- clear_audio_regions();
+ clear_regions();
clear_points ();
add (selectables);
}
@@ -620,14 +619,14 @@ Selection::set (list<Selectable*>& selectables)
void
Selection::add (list<Selectable*>& selectables)
{
- AudioRegionView* arv;
+ RegionView* rv;
AutomationSelectable* as;
- vector<AudioRegionView*> arvs;
+ vector<RegionView*> rvs;
vector<AutomationSelectable*> autos;
for (std::list<Selectable*>::iterator i = selectables.begin(); i != selectables.end(); ++i) {
- if ((arv = dynamic_cast<AudioRegionView*> (*i)) != 0) {
- arvs.push_back (arv);
+ if ((rv = dynamic_cast<RegionView*> (*i)) != 0) {
+ rvs.push_back (rv);
} else if ((as = dynamic_cast<AutomationSelectable*> (*i)) != 0) {
autos.push_back (as);
} else {
@@ -638,8 +637,8 @@ Selection::add (list<Selectable*>& selectables)
}
}
- if (!arvs.empty()) {
- add (arvs);
+ if (!rvs.empty()) {
+ add (rvs);
}
if (!autos.empty()) {
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index ebeda1aea7..7b503a5e63 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -22,6 +22,7 @@
#define __ardour_gtk_selection_h__
#include <vector>
+#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
@@ -34,7 +35,7 @@
#include "point_selection.h"
class TimeAxisView;
-class AudioRegionView;
+class RegionView;
class Selectable;
namespace ARDOUR {
@@ -60,7 +61,7 @@ class Selection : public sigc::trackable
};
TrackSelection tracks;
- AudioRegionSelection audio_regions;
+ RegionSelection regions;
TimeSelection time;
AutomationSelection lines;
PlaylistSelection playlists;
@@ -88,55 +89,55 @@ class Selection : public sigc::trackable
void dump_region_layers();
bool selected (TimeAxisView*);
- bool selected (AudioRegionView*);
+ bool selected (RegionView*);
void set (list<Selectable*>&);
void add (list<Selectable*>&);
void set (TimeAxisView*);
void set (const list<TimeAxisView*>&);
- void set (AudioRegionView*);
- void set (std::vector<AudioRegionView*>&);
+ void set (RegionView*);
+ void set (std::vector<RegionView*>&);
long set (TimeAxisView*, jack_nframes_t, jack_nframes_t);
void set (ARDOUR::AutomationList*);
void set (ARDOUR::Playlist*);
void set (const list<ARDOUR::Playlist*>&);
- void set (ARDOUR::Redirect*);
+ void set (boost::shared_ptr<ARDOUR::Redirect>);
void set (AutomationSelectable*);
void toggle (TimeAxisView*);
void toggle (const list<TimeAxisView*>&);
- void toggle (AudioRegionView*);
- void toggle (std::vector<AudioRegionView*>&);
+ void toggle (RegionView*);
+ void toggle (std::vector<RegionView*>&);
long toggle (jack_nframes_t, jack_nframes_t);
void toggle (ARDOUR::AutomationList*);
void toggle (ARDOUR::Playlist*);
void toggle (const list<ARDOUR::Playlist*>&);
- void toggle (ARDOUR::Redirect*);
+ void toggle (boost::shared_ptr<ARDOUR::Redirect>);
void add (TimeAxisView*);
void add (const list<TimeAxisView*>&);
- void add (AudioRegionView*);
- void add (std::vector<AudioRegionView*>&);
+ void add (RegionView*);
+ void add (std::vector<RegionView*>&);
long add (jack_nframes_t, jack_nframes_t);
void add (ARDOUR::AutomationList*);
void add (ARDOUR::Playlist*);
void add (const list<ARDOUR::Playlist*>&);
- void add (ARDOUR::Redirect*);
+ void add (boost::shared_ptr<ARDOUR::Redirect>);
void remove (TimeAxisView*);
void remove (const list<TimeAxisView*>&);
- void remove (AudioRegionView*);
+ void remove (RegionView*);
void remove (uint32_t selection_id);
void remove (jack_nframes_t, jack_nframes_t);
void remove (ARDOUR::AutomationList*);
void remove (ARDOUR::Playlist*);
void remove (const list<ARDOUR::Playlist*>&);
- void remove (ARDOUR::Redirect*);
+ void remove (boost::shared_ptr<ARDOUR::Redirect>);
void replace (uint32_t time_index, jack_nframes_t start, jack_nframes_t end);
- void clear_audio_regions();
+ void clear_regions();
void clear_tracks ();
void clear_time();
void clear_lines ();
@@ -144,10 +145,8 @@ class Selection : public sigc::trackable
void clear_redirects ();
void clear_points ();
- void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void));
- void foreach_audio_region (void (ARDOUR::Region::*method)(void));
- template<class A> void foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg);
- template<class A> void foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg);
+ void foreach_region (void (ARDOUR::Region::*method)(void));
+ template<class A> void foreach_region (void (ARDOUR::Region::*method)(A), A arg);
private:
uint32_t next_time_id;
diff --git a/gtk2_ardour/selection_templates.h b/gtk2_ardour/selection_templates.h
index c2ca70b526..9511db7d61 100644
--- a/gtk2_ardour/selection_templates.h
+++ b/gtk2_ardour/selection_templates.h
@@ -27,35 +27,21 @@
*/
#include <ardour/region.h>
-#include <ardour/audioregion.h>
#include "selection.h"
+#include "region_view.h"
inline void
-Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(void)) {
- for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- ((*i)->region.*(method))();
- }
-}
-
-inline void
-Selection::foreach_audio_region (void (ARDOUR::Region::*method)(void)) {
- for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- ((*i)->region.*(method))();
- }
-}
-
-template<class A> inline void
-Selection::foreach_audio_region (void (ARDOUR::AudioRegion::*method)(A), A arg) {
- for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- ((*i)->region.*(method))(arg);
+Selection::foreach_region (void (ARDOUR::Region::*method)(void)) {
+ for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
+ ((*i)->region().*(method))();
}
}
template<class A> inline void
-Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) {
- for (AudioRegionSelection::iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- ((*i)->region.*(method))(arg);
+Selection::foreach_region (void (ARDOUR::Region::*method)(A), A arg) {
+ for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
+ ((*i)->region().*(method))(arg);
}
}
@@ -64,14 +50,14 @@ Selection::foreach_audio_region (void (ARDOUR::Region::*method)(A), A arg) {
template<class A> inline void
Selection::foreach_route (void (ARDOUR::Route::*method)(A), A arg) {
for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
- ((*i)->region.*(method))(arg);
+ ((*i)->region().*(method))(arg);
}
}
template<class A1, class A2> inline void
Selection::foreach_route (void (ARDOUR::Route::*method)(A1,A2), A1 arg1, A2 arg2) {
for (list<ARDOUR::Route*>::iterator i = routes.begin(); i != routes.end(); ++i) {
- ((*i)->region.*(method))(arg1, arg2);
+ ((*i)->region().*(method))(arg1, arg2);
}
}
diff --git a/gtk2_ardour/send_ui.cc b/gtk2_ardour/send_ui.cc
index be95f753e7..9925ff51d4 100644
--- a/gtk2_ardour/send_ui.cc
+++ b/gtk2_ardour/send_ui.cc
@@ -30,7 +30,7 @@
using namespace ARDOUR;
using namespace PBD;
-SendUI::SendUI (Send& s, Session& se)
+SendUI::SendUI (boost::shared_ptr<Send> s, Session& se)
: _send (s),
_session (se),
gpm (s, se),
@@ -53,10 +53,10 @@ SendUI::SendUI (Send& s, Session& se)
show_all ();
- _send.set_metering (true);
+ _send->set_metering (true);
- _send.output_changed.connect (mem_fun (*this, &SendUI::ins_changed));
- _send.output_changed.connect (mem_fun (*this, &SendUI::outs_changed));
+ _send->output_changed.connect (mem_fun (*this, &SendUI::ins_changed));
+ _send->output_changed.connect (mem_fun (*this, &SendUI::outs_changed));
panners.set_width (Wide);
panners.setup_pan ();
@@ -70,7 +70,7 @@ SendUI::SendUI (Send& s, Session& se)
SendUI::~SendUI ()
{
- _send.set_metering (false);
+ _send->set_metering (false);
/* XXX not clear that we need to do this */
@@ -118,7 +118,7 @@ SendUI::fast_update ()
}
}
-SendUIWindow::SendUIWindow (Send& s, Session& ss)
+SendUIWindow::SendUIWindow (boost::shared_ptr<Send> s, Session& ss)
{
ui = new SendUI (s, ss);
@@ -131,7 +131,7 @@ SendUIWindow::SendUIWindow (Send& s, Session& ss)
add (vpacker);
set_name ("SendUIWindow");
- s.GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
+ s->GoingAway.connect (mem_fun (*this, &SendUIWindow::send_going_away));
signal_delete_event().connect (bind (ptr_fun (just_hide_it), reinterpret_cast<Window *> (this)));
diff --git a/gtk2_ardour/send_ui.h b/gtk2_ardour/send_ui.h
index d1a49930ea..1d5a74e102 100644
--- a/gtk2_ardour/send_ui.h
+++ b/gtk2_ardour/send_ui.h
@@ -35,7 +35,7 @@ class IOSelector;
class SendUI : public Gtk::HBox
{
public:
- SendUI (ARDOUR::Send&, ARDOUR::Session&);
+ SendUI (boost::shared_ptr<ARDOUR::Send>, ARDOUR::Session&);
~SendUI();
void update ();
@@ -44,7 +44,7 @@ class SendUI : public Gtk::HBox
IOSelector* io;
private:
- ARDOUR::Send& _send;
+ boost::shared_ptr<ARDOUR::Send> _send;
ARDOUR::Session& _session;
GainMeter gpm;
PannerUI panners;
@@ -62,7 +62,7 @@ class SendUI : public Gtk::HBox
class SendUIWindow : public Gtk::Window
{
public:
- SendUIWindow(ARDOUR::Send&, ARDOUR::Session&);
+ SendUIWindow(boost::shared_ptr<ARDOUR::Send>, ARDOUR::Session&);
~SendUIWindow();
SendUI* ui;
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 79546880de..d9ded04d2b 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -97,6 +97,9 @@ SoundFileBox::SoundFileBox ()
(mem_fun (*this, &SoundFileBox::add_field_clicked));
remove_field_btn.signal_clicked().connect
(mem_fun (*this, &SoundFileBox::remove_field_clicked));
+
+ Gtk::CellRendererText* cell(dynamic_cast<Gtk::CellRendererText*>(field_view.get_column_cell_renderer(1)));
+ cell->signal_edited().connect (mem_fun (*this, &SoundFileBox::field_edited));
field_view.get_selection()->signal_changed().connect (mem_fun (*this, &SoundFileBox::field_selected));
Library->fields_changed.connect (mem_fun (*this, &SoundFileBox::setup_fields));
@@ -260,6 +263,13 @@ SoundFileBox::remove_field_clicked ()
}
void
+SoundFileBox::field_edited (const Glib::ustring& str1, const Glib::ustring& str2)
+{
+ cout << "field_edited" << endl;
+ Library->save_changes ();
+}
+
+void
SoundFileBox::delete_row (const Gtk::TreeModel::iterator& iter)
{
Gtk::TreeModel::Row row = *iter;
@@ -394,6 +404,9 @@ SoundFileOmega::set_mode (Editing::ImportMode mode)
case Editing::ImportToTrack:
split_check.set_sensitive (false);
break;
+ case Editing::ImportAsTapeTrack:
+ split_check.set_sensitive (true);
+ break;
}
}
@@ -433,5 +446,8 @@ SoundFileOmega::mode_changed ()
case Editing::ImportToTrack:
split_check.set_sensitive (false);
break;
+ case Editing::ImportAsTapeTrack:
+ split_check.set_sensitive (true);
+ break;
}
}
diff --git a/gtk2_ardour/sfdb_ui.h b/gtk2_ardour/sfdb_ui.h
index 79c73b97ac..8ef57d7b9f 100644
--- a/gtk2_ardour/sfdb_ui.h
+++ b/gtk2_ardour/sfdb_ui.h
@@ -100,6 +100,7 @@ class SoundFileBox : public Gtk::VBox
void stop_btn_clicked ();
void add_field_clicked ();
void remove_field_clicked ();
+ void field_edited (const Glib::ustring&, const Glib::ustring&);
void delete_row (const Gtk::TreeModel::iterator& iter);
void field_selected ();
diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc
index a60e0d59e7..d1d163d7a2 100644
--- a/gtk2_ardour/streamview.cc
+++ b/gtk2_ardour/streamview.cc
@@ -1,28 +1,42 @@
+/*
+ Copyright (C) 2001, 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
#include <cmath>
#include <gtkmm.h>
#include <gtkmm2ext/gtk_ui.h>
-#include <ardour/audioplaylist.h>
-#include <ardour/audioregion.h>
-#include <ardour/audiosource.h>
-#include <ardour/audio_diskstream.h>
-#include <ardour/audio_track.h>
-#include <ardour/playlist_templates.h>
+#include <ardour/playlist.h>
+#include <ardour/region.h>
#include <ardour/source.h>
+#include <ardour/diskstream.h>
+#include <ardour/track.h>
#include "streamview.h"
-#include "regionview.h"
-#include "taperegionview.h"
-#include "audio_time_axis.h"
+#include "region_view.h"
+#include "route_time_axis.h"
#include "canvas-waveview.h"
#include "canvas-simplerect.h"
#include "region_selection.h"
#include "selection.h"
#include "public_editor.h"
#include "ardour_ui.h"
-#include "crossfade_view.h"
#include "rgb_macros.h"
#include "gui_thread.h"
#include "utils.h"
@@ -32,52 +46,36 @@ using namespace ARDOUR;
using namespace PBD;
using namespace Editing;
-StreamView::StreamView (AudioTimeAxisView& tv)
+StreamView::StreamView (RouteTimeAxisView& tv)
: _trackview (tv)
+ , canvas_group(new ArdourCanvas::Group(*_trackview.canvas_display))
+ , canvas_rect(new ArdourCanvas::SimpleRect (*canvas_group))
+ , _samples_per_unit(_trackview.editor.get_current_zoom())
+ , rec_updating(false)
+ , rec_active(false)
+ , use_rec_regions(tv.editor.show_waveforms_recording())
+ , region_color(_trackview.color())
+ , stream_base_color(0xFFFFFFFF)
{
- region_color = _trackview.color();
- crossfades_visible = true;
-
- if (tv.is_audio_track()) {
- /* TRACK */
- //stream_base_color = RGBA_TO_UINT (222,223,218,255);
- stream_base_color = color_map[cAudioTrackBase];
- } else {
- /* BUS */
- //stream_base_color = RGBA_TO_UINT (230,226,238,255);
- stream_base_color = color_map[cAudioBusBase];
- }
-
/* set_position() will position the group */
- canvas_group = new ArdourCanvas::Group(*_trackview.canvas_display);
-
canvas_rect = new ArdourCanvas::SimpleRect (*canvas_group);
canvas_rect->property_x1() = 0.0;
canvas_rect->property_y1() = 0.0;
canvas_rect->property_x2() = 1000000.0;
canvas_rect->property_y2() = (double) tv.height;
- canvas_rect->property_outline_color_rgba() = color_map[cAudioTrackOutline];
canvas_rect->property_outline_what() = (guint32) (0x1|0x2|0x8); // outline ends and bottom
- canvas_rect->property_fill_color_rgba() = stream_base_color;
+ // (Fill/Outline colours set in derived classes)
canvas_rect->signal_event().connect (bind (mem_fun (_trackview.editor, &PublicEditor::canvas_stream_view_event), canvas_rect, &_trackview));
- _samples_per_unit = _trackview.editor.get_current_zoom();
- _amplitude_above_axis = 1.0;
-
- if (_trackview.is_audio_track()) {
- _trackview.audio_track()->diskstream_changed.connect (mem_fun (*this, &StreamView::diskstream_changed));
+ if (_trackview.is_track()) {
+ _trackview.track()->DiskstreamChanged.connect (mem_fun (*this, &StreamView::diskstream_changed));
_trackview.session().TransportStateChange.connect (mem_fun (*this, &StreamView::transport_changed));
- _trackview.get_diskstream()->record_enable_changed.connect (mem_fun (*this, &StreamView::rec_enable_changed));
+ _trackview.get_diskstream()->RecordEnableChanged.connect (mem_fun (*this, &StreamView::rec_enable_changed));
_trackview.session().RecordStateChanged.connect (mem_fun (*this, &StreamView::sess_rec_enable_changed));
}
- rec_updating = false;
- rec_active = false;
- use_rec_regions = tv.editor.show_waveforms_recording ();
- last_rec_peak_frame = 0;
-
ColorChanged.connect (mem_fun (*this, &StreamView::color_handler));
}
@@ -90,7 +88,7 @@ StreamView::~StreamView ()
void
StreamView::attach ()
{
- if (_trackview.is_audio_track()) {
+ if (_trackview.is_track()) {
display_diskstream (_trackview.get_diskstream());
}
}
@@ -115,13 +113,13 @@ StreamView::set_height (gdouble h)
canvas_rect->property_y2() = h;
- for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
(*i)->set_height (h);
}
- for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ /*for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
(*i)->set_height (h);
- }
+ }*/
for (vector<RecBoxInfo>::iterator i = rec_rects.begin(); i != rec_rects.end(); ++i) {
RecBoxInfo &recbox = (*i);
@@ -134,7 +132,7 @@ StreamView::set_height (gdouble h)
int
StreamView::set_samples_per_unit (gdouble spp)
{
- AudioRegionViewList::iterator i;
+ RegionViewList::iterator i;
if (spp < 1.0) {
return -1;
@@ -146,10 +144,6 @@ StreamView::set_samples_per_unit (gdouble spp)
(*i)->set_samples_per_unit (spp);
}
- for (CrossfadeViewList::iterator xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
- (*xi)->set_samples_per_unit (spp);
- }
-
for (vector<RecBoxInfo>::iterator xi = rec_rects.begin(); xi != rec_rects.end(); ++xi) {
RecBoxInfo &recbox = (*xi);
@@ -163,25 +157,6 @@ StreamView::set_samples_per_unit (gdouble spp)
return 0;
}
-int
-StreamView::set_amplitude_above_axis (gdouble app)
-
-{
- AudioRegionViewList::iterator i;
-
- if (app < 1.0) {
- return -1;
- }
-
- _amplitude_above_axis = app;
-
- for (i = region_views.begin(); i != region_views.end(); ++i) {
- (*i)->set_amplitude_above_axis (app);
- }
-
- return 0;
-}
-
void
StreamView::add_region_view (Region *r)
{
@@ -189,87 +164,17 @@ StreamView::add_region_view (Region *r)
}
void
-StreamView::add_region_view_internal (Region *r, bool wait_for_waves)
-{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_region_view), r));
-
- AudioRegion* region = dynamic_cast<AudioRegion*> (r);
-
- if (region == 0) {
- return;
- }
-
- AudioRegionView *region_view;
- list<AudioRegionView *>::iterator i;
-
- for (i = region_views.begin(); i != region_views.end(); ++i) {
- if (&(*i)->region == region) {
-
- /* great. we already have a AudioRegionView for this Region. use it again.
- */
-
- (*i)->set_valid (true);
- return;
- }
- }
-
- switch (_trackview.audio_track()->mode()) {
- case Normal:
- region_view = new AudioRegionView (canvas_group, _trackview, *region,
- _samples_per_unit, region_color);
- break;
- case Destructive:
- region_view = new TapeAudioRegionView (canvas_group, _trackview, *region,
- _samples_per_unit, region_color);
- break;
- }
-
- region_view->init (_amplitude_above_axis, region_color, wait_for_waves);
- region_views.push_front (region_view);
-
- /* follow global waveform setting */
-
- region_view->set_waveform_visible(_trackview.editor.show_waveforms());
-
- /* catch regionview going away */
-
- region->GoingAway.connect (mem_fun (*this, &StreamView::remove_region_view));
-
- AudioRegionViewAdded (region_view);
-}
-
-void
StreamView::remove_region_view (Region *r)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_region_view), r));
- AudioRegion* ar = dynamic_cast<AudioRegion*> (r);
-
- if (ar == 0) {
- return;
- }
-
- for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- if (&((*i)->region) == ar) {
+ for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ if (&((*i)->region()) == r) {
delete *i;
region_views.erase (i);
break;
}
}
-
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end();) {
- list<CrossfadeView*>::iterator tmp;
-
- tmp = i;
- ++tmp;
-
- if ((*i)->crossfade.involves (*ar)) {
- delete *i;
- crossfade_views.erase (i);
- }
-
- i = tmp;
- }
}
void
@@ -282,14 +187,8 @@ StreamView::remove_rec_region (Region *r)
/*NOTREACHED*/
}
- AudioRegion* ar = dynamic_cast<AudioRegion*> (r);
-
- if (ar == 0) {
- return;
- }
-
- for (list<AudioRegion *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
- if (*i == ar) {
+ for (list<Region *>::iterator i = rec_regions.begin(); i != rec_regions.end(); ++i) {
+ if (*i == r) {
rec_regions.erase (i);
break;
}
@@ -299,21 +198,15 @@ StreamView::remove_rec_region (Region *r)
void
StreamView::undisplay_diskstream ()
{
-
- for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- delete *i;
- }
-
- for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
delete *i;
}
region_views.clear();
- crossfade_views.clear ();
}
void
-StreamView::display_diskstream (AudioDiskstream *ds)
+StreamView::display_diskstream (Diskstream *ds)
{
playlist_change_connection.disconnect();
playlist_changed (ds);
@@ -325,21 +218,13 @@ StreamView::playlist_modified ()
{
ENSURE_GUI_THREAD (mem_fun (*this, &StreamView::playlist_modified));
- /* if the playlist is modified, make sure xfades are on top and all the regionviews are stacked
- correctly.
- */
-
- for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
region_layered (*i);
}
-
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- (*i)->get_canvas_group()->raise_to_top();
- }
}
void
-StreamView::playlist_changed (AudioDiskstream *ds)
+StreamView::playlist_changed (Diskstream *ds)
{
ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_changed), ds));
@@ -362,69 +247,6 @@ StreamView::playlist_changed (AudioDiskstream *ds)
playlist_connections.push_back (ds->playlist()->RegionRemoved.connect (mem_fun (*this, &StreamView::remove_region_view)));
playlist_connections.push_back (ds->playlist()->StateChanged.connect (mem_fun (*this, &StreamView::playlist_state_changed)));
playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified)));
- playlist_connections.push_back (ds->playlist()->NewCrossfade.connect (mem_fun (*this, &StreamView::add_crossfade)));
-}
-
-void
-StreamView::add_crossfade (Crossfade *crossfade)
-{
- AudioRegionView* lview = 0;
- AudioRegionView* rview = 0;
-
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::add_crossfade), crossfade));
-
- /* first see if we already have a CrossfadeView for this Crossfade */
-
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if (&(*i)->crossfade == crossfade) {
- if (!crossfades_visible) {
- (*i)->hide();
- } else {
- (*i)->show ();
- }
- (*i)->set_valid (true);
- return;
- }
- }
-
- /* create a new one */
-
- for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- if (!lview && &((*i)->region) == &crossfade->out()) {
- lview = *i;
- }
- if (!rview && &((*i)->region) == &crossfade->in()) {
- rview = *i;
- }
- }
-
- CrossfadeView *cv = new CrossfadeView (_trackview.canvas_display,
- _trackview,
- *crossfade,
- _samples_per_unit,
- region_color,
- *lview, *rview);
-
- crossfade->Invalidated.connect (mem_fun (*this, &StreamView::remove_crossfade));
- crossfade_views.push_back (cv);
-
- if (!crossfades_visible) {
- cv->hide ();
- }
-}
-
-void
-StreamView::remove_crossfade (Crossfade *xfade)
-{
- ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::remove_crossfade), xfade));
-
- for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if (&(*i)->crossfade == xfade) {
- delete *i;
- crossfade_views.erase (i);
- break;
- }
- }
}
void
@@ -436,64 +258,12 @@ StreamView::playlist_state_changed (Change ignored)
}
void
-StreamView::redisplay_diskstream ()
-{
- list<AudioRegionView *>::iterator i, tmp;
- list<CrossfadeView*>::iterator xi, tmpx;
-
-
- for (i = region_views.begin(); i != region_views.end(); ++i) {
- (*i)->set_valid (false);
- }
-
- for (xi = crossfade_views.begin(); xi != crossfade_views.end(); ++xi) {
- (*xi)->set_valid (false);
- if ((*xi)->visible()) {
- (*xi)->show ();
- }
- }
-
- if (_trackview.is_audio_track()) {
- _trackview.get_diskstream()->playlist()->foreach_region (this, &StreamView::add_region_view);
- _trackview.get_diskstream()->playlist()->foreach_crossfade (this, &StreamView::add_crossfade);
- }
-
- for (i = region_views.begin(); i != region_views.end(); ) {
- tmp = i;
- tmp++;
-
- if (!(*i)->is_valid()) {
- delete *i;
- region_views.erase (i);
- }
-
- i = tmp;
- }
-
- for (xi = crossfade_views.begin(); xi != crossfade_views.end();) {
- tmpx = xi;
- tmpx++;
-
- if (!(*xi)->valid()) {
- delete *xi;
- crossfade_views.erase (xi);
- }
-
- xi = tmpx;
- }
-
- /* now fix layering */
-
- playlist_modified ();
-}
-
-void
-StreamView::diskstream_changed (void *src_ignored)
+StreamView::diskstream_changed ()
{
- AudioTrack *at;
+ Track *t;
- if ((at = _trackview.audio_track()) != 0) {
- AudioDiskstream& ds = at->disk_stream();
+ if ((t = _trackview.track()) != 0) {
+ Diskstream& ds = t->diskstream();
/* XXX grrr: when will SigC++ allow me to bind references? */
Gtkmm2ext::UI::instance()->call_slot (bind (mem_fun (*this, &StreamView::display_diskstream), &ds));
} else {
@@ -505,7 +275,7 @@ void
StreamView::apply_color (Gdk::Color& color, ColorTarget target)
{
- list<AudioRegionView *>::iterator i;
+ list<RegionView *>::iterator i;
switch (target) {
case RegionColor:
@@ -513,76 +283,18 @@ StreamView::apply_color (Gdk::Color& color, ColorTarget target)
for (i = region_views.begin(); i != region_views.end(); ++i) {
(*i)->set_color (region_color);
}
- // stream_base_color = RGBA_TO_UINT (color.red/256, color.green/256, color.blue/256, 255);
- // gnome_canvas_item_set (canvas_rect, "fill_color_rgba", stream_base_color, NULL);
break;
case StreamBaseColor:
- // stream_base_color = RGBA_TO_UINT (color.red/256, color.green/256, color.blue/256, 255);
- // gnome_canvas_item_set (canvas_rect, "fill_color_rgba", stream_base_color, NULL);
+ stream_base_color = RGBA_TO_UINT (
+ color.get_red_p(), color.get_green_p(), color.get_blue_p(), 255);
+ canvas_rect->property_fill_color_rgba() = stream_base_color;
break;
}
}
void
-StreamView::set_show_waveforms (bool yn)
-{
- for (list<AudioRegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- (*i)->set_waveform_visible (yn);
- }
-}
-
-void
-StreamView::set_selected_regionviews (AudioRegionSelection& regions)
-{
- bool selected;
-
- // cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
- for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
-
- selected = false;
-
- for (AudioRegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) {
- if (*i == *ii) {
- selected = true;
- }
- }
-
- // cerr << "\tregion " << (*i)->region.name() << " selected = " << selected << endl;
- (*i)->set_selected (selected);
- }
-}
-
-void
-StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results)
-{
- for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- if ((*i)->region.coverage(start, end) != OverlapNone) {
- results.push_back (*i);
- }
- }
-}
-
-void
-StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
-{
- for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- if (!sel.audio_regions.contains (*i)) {
- results.push_back (*i);
- }
- }
-}
-
-void
-StreamView::set_waveform_shape (WaveformShape shape)
-{
- for (AudioRegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- (*i)->set_waveform_shape (shape);
- }
-}
-
-void
-StreamView::region_layered (AudioRegionView* rv)
+StreamView::region_layered (RegionView* rv)
{
rv->get_canvas_group()->lower_to_bottom();
@@ -590,11 +302,14 @@ StreamView::region_layered (AudioRegionView* rv)
get events - the parent group does instead ...
*/
- rv->get_canvas_group()->raise (rv->region.layer() + 1);
+ /* this used to be + 1, but regions to the left ended up below
+ ..something.. and couldn't receive events. why? good question.
+ */
+ rv->get_canvas_group()->raise (rv->region().layer() + 2);
}
void
-StreamView::rec_enable_changed (void *src)
+StreamView::rec_enable_changed ()
{
Gtkmm2ext::UI::instance()->call_slot (mem_fun (*this, &StreamView::setup_rec_box));
}
@@ -612,161 +327,6 @@ StreamView::transport_changed()
}
void
-StreamView::setup_rec_box ()
-{
- // cerr << _trackview.name() << " streamview SRB\n";
-
- if (_trackview.session().transport_rolling()) {
-
- // cerr << "\trolling\n";
-
- if (!rec_active &&
- _trackview.session().record_status() == Session::Recording &&
- _trackview.get_diskstream()->record_enabled()) {
-
- if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
-
- /* add a new region, but don't bother if they set use_rec_regions mid-record */
-
- AudioRegion::SourceList sources;
-
- for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
- (*prc).disconnect();
- }
- peak_ready_connections.clear();
-
- for (uint32_t n=0; n < _trackview.get_diskstream()->n_channels(); ++n) {
- AudioSource *src = (AudioSource *) _trackview.get_diskstream()->write_source (n);
- if (src) {
- sources.push_back (src);
- peak_ready_connections.push_back (src->PeakRangeReady.connect (bind (mem_fun (*this, &StreamView::rec_peak_range_ready), src)));
- }
- }
-
- // handle multi
-
- jack_nframes_t start = 0;
- if (rec_regions.size() > 0) {
- start = rec_regions.back()->start() + _trackview.get_diskstream()->get_captured_frames(rec_regions.size()-1);
- }
-
- AudioRegion * region = new AudioRegion(sources, start, 1 , "", 0, (Region::Flag)(Region::DefaultFlags | Region::DoNotSaveState), false);
- region->set_position (_trackview.session().transport_frame(), this);
- rec_regions.push_back (region);
- /* catch it if it goes away */
- region->GoingAway.connect (mem_fun (*this, &StreamView::remove_rec_region));
-
- /* we add the region later */
- }
-
- /* start a new rec box */
-
- AudioTrack* at;
-
- at = _trackview.audio_track(); /* we know what it is already */
- AudioDiskstream& ds = at->disk_stream();
- jack_nframes_t frame_pos = ds.current_capture_start ();
- gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
- gdouble xend;
- uint32_t fill_color;
-
- switch (_trackview.audio_track()->mode()) {
- case Normal:
- xend = xstart;
- fill_color = color_map[cRecordingRectFill];
- break;
-
- case Destructive:
- xend = xstart + 2;
- fill_color = color_map[cRecordingRectFill];
- /* make the recording rect translucent to allow
- the user to see the peak data coming in, etc.
- */
- fill_color = UINT_RGBA_CHANGE_A (fill_color, 120);
- break;
- }
-
- ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
- rec_rect->property_x1() = xstart;
- rec_rect->property_y1() = 1.0;
- rec_rect->property_x2() = xend;
- rec_rect->property_y2() = (double) _trackview.height - 1;
- rec_rect->property_outline_color_rgba() = color_map[cRecordingRectOutline];
- rec_rect->property_fill_color_rgba() = fill_color;
-
- RecBoxInfo recbox;
- recbox.rectangle = rec_rect;
- recbox.start = _trackview.session().transport_frame();
- recbox.length = 0;
-
- rec_rects.push_back (recbox);
-
- screen_update_connection.disconnect();
- screen_update_connection = ARDOUR_UI::instance()->SuperRapidScreenUpdate.connect (mem_fun (*this, &StreamView::update_rec_box));
- rec_updating = true;
- rec_active = true;
-
- } else if (rec_active &&
- (_trackview.session().record_status() != Session::Recording ||
- !_trackview.get_diskstream()->record_enabled())) {
-
- screen_update_connection.disconnect();
- rec_active = false;
- rec_updating = false;
-
- }
-
- } else {
-
- // cerr << "\tNOT rolling, rec_rects = " << rec_rects.size() << " rec_regions = " << rec_regions.size() << endl;
-
- if (!rec_rects.empty() || !rec_regions.empty()) {
-
- /* disconnect rapid update */
- screen_update_connection.disconnect();
-
- for (list<sigc::connection>::iterator prc = peak_ready_connections.begin(); prc != peak_ready_connections.end(); ++prc) {
- (*prc).disconnect();
- }
- peak_ready_connections.clear();
-
- rec_updating = false;
- rec_active = false;
- last_rec_peak_frame = 0;
-
- /* remove temp regions */
- for (list<AudioRegion*>::iterator iter=rec_regions.begin(); iter != rec_regions.end(); )
- {
- list<AudioRegion*>::iterator tmp;
-
- tmp = iter;
- ++tmp;
-
- /* this will trigger the remove_region_view */
- delete *iter;
-
- iter = tmp;
- }
-
- rec_regions.clear();
-
- // cerr << "\tclear " << rec_rects.size() << " rec rects\n";
-
-
- /* transport stopped, clear boxes */
- for (vector<RecBoxInfo>::iterator iter=rec_rects.begin(); iter != rec_rects.end(); ++iter) {
- RecBoxInfo &rect = (*iter);
- delete rect.rectangle;
- }
-
- rec_rects.clear();
-
- }
- }
-}
-
-
-void
StreamView::update_rec_box ()
{
if (rec_active && rec_rects.size() > 0) {
@@ -776,7 +336,7 @@ StreamView::update_rec_box ()
double xstart;
double xend;
- switch (_trackview.audio_track()->mode()) {
+ switch (_trackview.track()->mode()) {
case Normal:
rect.length = at - rect.start;
xstart = _trackview.editor.frame_to_pixel (rect.start);
@@ -795,12 +355,12 @@ StreamView::update_rec_box ()
}
}
-AudioRegionView*
-StreamView::find_view (const AudioRegion& region)
+RegionView*
+StreamView::find_view (const Region& region)
{
- for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
- if (&(*i)->region == &region) {
+ if (&(*i)->region() == &region) {
return *i;
}
}
@@ -808,172 +368,51 @@ StreamView::find_view (const AudioRegion& region)
}
void
-StreamView::foreach_regionview (sigc::slot<void,AudioRegionView*> slot)
+StreamView::foreach_regionview (sigc::slot<void,RegionView*> slot)
{
- for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
slot (*i);
}
}
void
-StreamView::foreach_crossfadeview (void (CrossfadeView::*pmf)(void))
-{
- for (list<CrossfadeView*>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- ((*i)->*pmf) ();
- }
-}
-
-void
-StreamView::rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, Source * src)
-{
- // this is called from the peak building thread
-
- ENSURE_GUI_THREAD(bind (mem_fun (*this, &StreamView::rec_peak_range_ready), start, cnt, src));
-
- if (rec_peak_ready_map.size() == 0 || start+cnt > last_rec_peak_frame) {
- last_rec_peak_frame = start + cnt;
- }
-
- rec_peak_ready_map[src] = true;
-
- if (rec_peak_ready_map.size() == _trackview.get_diskstream()->n_channels()) {
- this->update_rec_regions ();
- rec_peak_ready_map.clear();
- }
-}
-
-void
-StreamView::update_rec_regions ()
+StreamView::set_selected_regionviews (RegionSelection& regions)
{
- if (use_rec_regions) {
-
- uint32_t n = 0;
-
- for (list<AudioRegion*>::iterator iter = rec_regions.begin(); iter != rec_regions.end(); n++) {
-
- list<AudioRegion*>::iterator tmp;
-
- tmp = iter;
- ++tmp;
-
- if (!canvas_item_visible (rec_rects[n].rectangle)) {
- /* rect already hidden, this region is done */
- iter = tmp;
- continue;
- }
-
- AudioRegion * region = (*iter);
- jack_nframes_t origlen = region->length();
-
- if (region == rec_regions.back() && rec_active) {
-
- if (last_rec_peak_frame > region->start()) {
-
- jack_nframes_t nlen = last_rec_peak_frame - region->start();
-
- if (nlen != region->length()) {
-
- region->freeze ();
- region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
- region->set_length (nlen, this);
- region->thaw ("updated");
-
- if (origlen == 1) {
- /* our special initial length */
- add_region_view_internal (region, false);
- }
-
- /* also update rect */
- ArdourCanvas::SimpleRect * rect = rec_rects[n].rectangle;
- gdouble xend = _trackview.editor.frame_to_pixel (region->position() + region->length());
- rect->property_x2() = xend;
- }
- }
-
- } else {
-
- jack_nframes_t nlen = _trackview.get_diskstream()->get_captured_frames(n);
-
- if (nlen != region->length()) {
-
- if (region->source(0).length() >= region->start() + nlen) {
-
- region->freeze ();
- region->set_position (_trackview.get_diskstream()->get_capture_start_frame(n), this);
- region->set_length (nlen, this);
- region->thaw ("updated");
-
- if (origlen == 1) {
- /* our special initial length */
- add_region_view_internal (region, false);
- }
-
- /* also hide rect */
- ArdourCanvas::Item * rect = rec_rects[n].rectangle;
- rect->hide();
+ bool selected;
- }
- }
+ // cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
+ for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+
+ selected = false;
+
+ for (RegionSelection::iterator ii = regions.begin(); ii != regions.end(); ++ii) {
+ if (*i == *ii) {
+ selected = true;
}
-
- iter = tmp;
}
+
+ // cerr << "\tregion " << (*i)->region().name() << " selected = " << selected << endl;
+ (*i)->set_selected (selected);
}
}
void
-StreamView::show_all_xfades ()
-{
- foreach_crossfadeview (&CrossfadeView::show);
- crossfades_visible = true;
-}
-
-void
-StreamView::hide_all_xfades ()
-{
- foreach_crossfadeview (&CrossfadeView::hide);
- crossfades_visible = false;
-}
-
-void
-StreamView::hide_xfades_involving (AudioRegionView& rv)
+StreamView::get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable*>& results)
{
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if ((*i)->crossfade.involves (rv.region)) {
- (*i)->fake_hide ();
+ for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ if ((*i)->region().coverage(start, end) != OverlapNone) {
+ results.push_back (*i);
}
}
}
void
-StreamView::reveal_xfades_involving (AudioRegionView& rv)
+StreamView::get_inverted_selectables (Selection& sel, list<Selectable*>& results)
{
- for (list<CrossfadeView *>::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
- if ((*i)->crossfade.involves (rv.region) && (*i)->visible()) {
- (*i)->show ();
+ for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
+ if (!sel.regions.contains (*i)) {
+ results.push_back (*i);
}
}
}
-void
-StreamView::color_handler (ColorID id, uint32_t val)
-{
- switch (id) {
- case cAudioTrackBase:
- if (_trackview.is_audio_track()) {
- canvas_rect->property_fill_color_rgba() = val;
- }
- break;
- case cAudioBusBase:
- if (!_trackview.is_audio_track()) {
- canvas_rect->property_fill_color_rgba() = val;
- }
- break;
- case cAudioTrackOutline:
- canvas_rect->property_outline_color_rgba() = val;
- break;
-
- default:
- break;
- }
-}
diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h
index 00ec2d93f2..5a0e10974f 100644
--- a/gtk2_ardour/streamview.h
+++ b/gtk2_ardour/streamview.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2001 Paul Davis
+ Copyright (C) 2001, 2006 Paul Davis
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
@@ -14,8 +14,6 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
*/
#ifndef __ardour_streamview_h__
@@ -37,141 +35,116 @@ namespace Gdk {
namespace ARDOUR {
class Route;
- class AudioDiskstream;
+ class Diskstream;
class Crossfade;
class PeakData;
- class AudioRegion;
+ class Region;
class Source;
}
struct RecBoxInfo {
- ArdourCanvas::SimpleRect* rectangle;
- jack_nframes_t start;
- jack_nframes_t length;
+ ArdourCanvas::SimpleRect* rectangle;
+ jack_nframes_t start;
+ jack_nframes_t length;
};
class PublicEditor;
class Selectable;
-class AudioTimeAxisView;
-class AudioRegionView;
-class AudioRegionSelection;
+class RouteTimeAxisView;
+class RegionView;
+class RegionSelection;
class CrossfadeView;
class Selection;
class StreamView : public sigc::trackable
{
- public:
- StreamView (AudioTimeAxisView&);
- ~StreamView ();
+public:
+ virtual ~StreamView ();
- void set_waveform_shape (WaveformShape);
+ RouteTimeAxisView& trackview() { return _trackview; }
- AudioTimeAxisView& trackview() { return _trackview; }
+ void attach ();
void set_zoom_all();
- int set_height (gdouble);
int set_position (gdouble x, gdouble y);
+ virtual int set_height (gdouble);
- int set_samples_per_unit (gdouble spp);
- gdouble get_samples_per_unit () { return _samples_per_unit; }
-
- int set_amplitude_above_axis (gdouble app);
- gdouble get_amplitude_above_axis () { return _amplitude_above_axis; }
-
- void set_show_waveforms (bool yn);
- void set_show_waveforms_recording (bool yn) { use_rec_regions = yn; }
+ virtual int set_samples_per_unit (gdouble spp);
+ gdouble get_samples_per_unit () { return _samples_per_unit; }
ArdourCanvas::Item* canvas_item() { return canvas_group; }
- sigc::signal<void,AudioRegionView*> AudioRegionViewAdded;
-
enum ColorTarget {
RegionColor,
StreamBaseColor
};
- void apply_color (Gdk::Color&, ColorTarget t);
- void set_selected_regionviews (AudioRegionSelection&);
+ Gdk::Color get_region_color () const { return region_color; }
+ void apply_color (Gdk::Color&, ColorTarget t);
+
+ RegionView* find_view (const ARDOUR::Region&);
+ void foreach_regionview (sigc::slot<void,RegionView*> slot);
+
+ void set_selected_regionviews (RegionSelection&);
void get_selectables (jack_nframes_t start, jack_nframes_t end, list<Selectable* >&);
void get_inverted_selectables (Selection&, list<Selectable* >& results);
- Gdk::Color get_region_color () const { return region_color; }
- void foreach_regionview (sigc::slot<void,AudioRegionView*> slot);
- void foreach_crossfadeview (void (CrossfadeView::*pmf)(void));
+ void add_region_view (ARDOUR::Region*);
+ void region_layered (RegionView*);
+
+ sigc::signal<void,RegionView*> RegionViewAdded;
- void attach ();
+protected:
+ StreamView (RouteTimeAxisView&);
- void region_layered (AudioRegionView*);
+//private: (FIXME?)
+
+ void transport_changed();
+ void rec_enable_changed();
+ void sess_rec_enable_changed();
+ virtual void setup_rec_box () = 0;
+ void update_rec_box ();
+ virtual void update_rec_regions () = 0;
- AudioRegionView* find_view (const ARDOUR::AudioRegion&);
-
- void show_all_xfades ();
- void hide_all_xfades ();
- void hide_xfades_involving (AudioRegionView&);
- void reveal_xfades_involving (AudioRegionView&);
+ virtual void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves) = 0;
+ virtual void remove_region_view (ARDOUR::Region* );
+ void remove_rec_region (ARDOUR::Region*);
+
+ void display_diskstream (ARDOUR::Diskstream* );
+ virtual void undisplay_diskstream ();
+ virtual void redisplay_diskstream () = 0;
+ void diskstream_changed ();
+
+ void playlist_state_changed (ARDOUR::Change);
+ virtual void playlist_changed (ARDOUR::Diskstream* );
+ virtual void playlist_modified ();
+
+ virtual void color_handler (ColorID, uint32_t) = 0;
- private:
- AudioTimeAxisView& _trackview;
- ArdourCanvas::Group* canvas_group;
+ RouteTimeAxisView& _trackview;
+ ArdourCanvas::Group* canvas_group;
ArdourCanvas::SimpleRect* canvas_rect; /* frame around the whole thing */
- typedef list<AudioRegionView* > AudioRegionViewList;
- AudioRegionViewList region_views;
-
- typedef list<CrossfadeView*> CrossfadeViewList;
- CrossfadeViewList crossfade_views;
+ typedef list<RegionView* > RegionViewList;
+ RegionViewList region_views;
double _samples_per_unit;
- double _amplitude_above_axis;
-
- sigc::connection screen_update_connection;
- vector<RecBoxInfo> rec_rects;
- list<ARDOUR::AudioRegion* > rec_regions;
- bool rec_updating;
- bool rec_active;
- bool use_rec_regions;
- list<sigc::connection> peak_ready_connections;
- jack_nframes_t last_rec_peak_frame;
- map<ARDOUR::Source*, bool> rec_peak_ready_map;
-
- void update_rec_box ();
- void transport_changed();
- void rec_enable_changed(void* src = 0);
- void sess_rec_enable_changed();
- void setup_rec_box ();
- void rec_peak_range_ready (jack_nframes_t start, jack_nframes_t cnt, ARDOUR::Source* src);
- void update_rec_regions ();
-
- void add_region_view (ARDOUR::Region*);
- void add_region_view_internal (ARDOUR::Region*, bool wait_for_waves);
- void remove_region_view (ARDOUR::Region* );
- void remove_rec_region (ARDOUR::Region*);
- void remove_audio_region_view (ARDOUR::AudioRegion* );
- void remove_audio_rec_region (ARDOUR::AudioRegion*);
-
- void display_diskstream (ARDOUR::AudioDiskstream* );
- void undisplay_diskstream ();
- void redisplay_diskstream ();
- void diskstream_changed (void* );
- void playlist_state_changed (ARDOUR::Change);
- void playlist_changed (ARDOUR::AudioDiskstream* );
- void playlist_modified ();
-
- bool crossfades_visible;
- void add_crossfade (ARDOUR::Crossfade*);
- void remove_crossfade (ARDOUR::Crossfade*);
-
- /* XXX why are these different? */
-
- Gdk::Color region_color;
- uint32_t stream_base_color;
- void color_handler (ColorID, uint32_t);
+ sigc::connection screen_update_connection;
+ vector<RecBoxInfo> rec_rects;
+ list<ARDOUR::Region* > rec_regions;
+ bool rec_updating;
+ bool rec_active;
+ bool use_rec_regions;
+
+ Gdk::Color region_color; ///< Contained region color
+ uint32_t stream_base_color; ///< Background color
vector<sigc::connection> playlist_connections;
- sigc::connection playlist_change_connection;
+ sigc::connection playlist_change_connection;
};
#endif /* __ardour_streamview_h__ */
+
diff --git a/gtk2_ardour/taperegionview.cc b/gtk2_ardour/tape_region_view.cc
index 641d067350..bd5ce8af02 100644
--- a/gtk2_ardour/taperegionview.cc
+++ b/gtk2_ardour/tape_region_view.cc
@@ -30,7 +30,7 @@
#include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
-#include "taperegionview.h"
+#include "tape_region_view.h"
#include "audio_time_axis.h"
#include "gui_thread.h"
@@ -42,72 +42,33 @@ using namespace PBD;
using namespace Editing;
using namespace ArdourCanvas;
-TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, AudioTimeAxisView &tv,
+const TimeAxisViewItem::Visibility TapeAudioRegionView::default_tape_visibility
+ = TimeAxisViewItem::Visibility (
+ TimeAxisViewItem::ShowNameHighlight |
+ TimeAxisViewItem::ShowFrame |
+ TimeAxisViewItem::HideFrameRight |
+ TimeAxisViewItem::FullWidthNameHighlight);
+
+TapeAudioRegionView::TapeAudioRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
AudioRegion& r,
double spu,
Gdk::Color& basic_color)
: AudioRegionView (parent, tv, r, spu, basic_color,
- TimeAxisViewItem::Visibility (TimeAxisViewItem::ShowNameHighlight|
- TimeAxisViewItem::ShowFrame|
- TimeAxisViewItem::HideFrameLR|
- TimeAxisViewItem::FullWidthNameHighlight))
+ TimeAxisViewItem::Visibility ((r.position() != 0) ? default_tape_visibility :
+ TimeAxisViewItem::Visibility (default_tape_visibility|TimeAxisViewItem::HideFrameLeft)))
{
}
void
-TapeAudioRegionView::init (double amplitude_above_axis, Gdk::Color& basic_color, bool wfw)
+TapeAudioRegionView::init (Gdk::Color& basic_color, bool wfw)
{
- XMLNode *node;
-
- editor = 0;
- valid = true;
- in_destructor = false;
- _amplitude_above_axis = amplitude_above_axis;
- zero_line = 0;
- wait_for_waves = wfw;
- _height = 0;
-
- _flags = 0;
-
- if ((node = region.extra_xml ("GUI")) != 0) {
- set_flags (node);
- } else {
- _flags = WaveformVisible;
- store_flags ();
- }
-
- fade_in_handle = 0;
- fade_out_handle = 0;
- gain_line = 0;
- sync_mark = 0;
-
- compute_colors (basic_color);
-
- create_waves ();
-
- name_highlight->set_data ("regionview", this);
-
- reset_width_dependent_items ((double) region.length() / samples_per_unit);
-
- set_height (trackview.height);
-
- region_muted ();
- region_resized (BoundsChanged);
- set_waveview_data_src();
- region_locked ();
-
- /* no events, no state changes */
-
- set_colors ();
-
- // ColorChanged.connect (mem_fun (*this, &AudioRegionView::color_handler));
+ AudioRegionView::init(basic_color, wfw);
/* every time the wave data changes and peaks are ready, redraw */
-
- for (uint32_t n = 0; n < region.n_channels(); ++n) {
- region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
+ for (uint32_t n = 0; n < audio_region().n_channels(); ++n) {
+ audio_region().source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
}
}
@@ -129,7 +90,7 @@ TapeAudioRegionView::update (uint32_t n)
/* this triggers a cache invalidation and redraw in the waveview */
- waves[n]->property_data_src() = &region;
+ waves[n]->property_data_src() = &_region;
}
void
diff --git a/gtk2_ardour/taperegionview.h b/gtk2_ardour/tape_region_view.h
index 3e23e0fc19..ed3852e3a9 100644
--- a/gtk2_ardour/taperegionview.h
+++ b/gtk2_ardour/tape_region_view.h
@@ -23,23 +23,25 @@
#include <vector>
-#include "regionview.h"
+#include "audio_region_view.h"
class TapeAudioRegionView : public AudioRegionView
{
public:
TapeAudioRegionView (ArdourCanvas::Group *,
- AudioTimeAxisView&,
+ RouteTimeAxisView&,
ARDOUR::AudioRegion&,
double initial_samples_per_unit,
Gdk::Color& base_color);
~TapeAudioRegionView ();
protected:
- void init (double amplitude_above_axis, Gdk::Color& base_color, bool wait_for_waves);
+ void init (Gdk::Color& base_color, bool wait_for_waves);
void set_frame_color ();
void update (uint32_t n);
+
+ static const TimeAxisViewItem::Visibility default_tape_visibility;
};
#endif /* __gtk_ardour_tape_audio_region_view_h__ */
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index b5ab5baa10..6261241139 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -128,6 +128,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session& sess, PublicEditor& ed, TimeAxisVie
controls_table.attach (name_hbox, 0, 4, 0, 1, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
controls_table.show_all ();
+ controls_table.set_no_show_all ();
controls_vbox.pack_start (controls_table, false, false);
controls_vbox.show ();
@@ -661,8 +662,6 @@ TimeAxisView::show_selection (TimeSelection& ts)
void
TimeAxisView::reshow_selection (TimeSelection& ts)
{
- cerr << name() << ": reshow selection" << endl;
-
show_selection (ts);
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
@@ -882,7 +881,7 @@ TimeAxisView::reset_height()
set_height_pixels (height);
for (vector<TimeAxisView*>::iterator i = children.begin(); i != children.end(); ++i) {
- (*i)->set_height ((TrackHeight)(*i)->height);
+ (*i)->set_height_pixels ((TrackHeight)(*i)->height);
}
}
diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h
index c607c78166..31ff3d84ee 100644
--- a/gtk2_ardour/time_axis_view.h
+++ b/gtk2_ardour/time_axis_view.h
@@ -54,7 +54,7 @@ namespace Gtk {
}
class PublicEditor;
-class AudioRegionSelection;
+class RegionSelection;
class TimeSelection;
class PointSelection;
class TimeAxisViewItem;
@@ -183,7 +183,7 @@ class TimeAxisView : public virtual AxisView
virtual bool cut_copy_clear (Selection&, Editing::CutCopyOp) { return false; }
virtual bool paste (jack_nframes_t, float times, Selection&, size_t nth) { return false; }
- virtual void set_selected_regionviews (AudioRegionSelection&) {}
+ virtual void set_selected_regionviews (RegionSelection&) {}
virtual void set_selected_points (PointSelection&) {}
virtual ARDOUR::Region* find_next_region (jack_nframes_t pos, ARDOUR::RegionPoint, int32_t dir) {
diff --git a/gtk2_ardour/time_axis_view_item.cc b/gtk2_ardour/time_axis_view_item.cc
index abab306a84..28fafcaa09 100644
--- a/gtk2_ardour/time_axis_view_item.cc
+++ b/gtk2_ardour/time_axis_view_item.cc
@@ -137,8 +137,12 @@ TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group&
uint32_t outline_what = 0x1|0x2|0x4|0x8;
- if (visibility & HideFrameLR) {
- outline_what &= ~(0x1 | 0x2);
+ if (visibility & HideFrameLeft) {
+ outline_what &= ~(0x1);
+ }
+
+ if (visibility & HideFrameRight) {
+ outline_what &= ~(0x2);
}
if (visibility & HideFrameTB) {
diff --git a/gtk2_ardour/time_axis_view_item.h b/gtk2_ardour/time_axis_view_item.h
index b23350eef7..9ddb06876a 100644
--- a/gtk2_ardour/time_axis_view_item.h
+++ b/gtk2_ardour/time_axis_view_item.h
@@ -316,9 +316,10 @@ class TimeAxisViewItem : public Selectable
ShowNameHighlight = 0x2,
ShowNameText = 0x4,
ShowHandles = 0x8,
- HideFrameLR = 0x10,
- HideFrameTB = 0x20,
- FullWidthNameHighlight = 0x40
+ HideFrameLeft = 0x10,
+ HideFrameRight = 0x20,
+ HideFrameTB = 0x40,
+ FullWidthNameHighlight = 0x80
};
/**
diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc
index 91cb7ad58b..ef90c34755 100644
--- a/gtk2_ardour/utils.cc
+++ b/gtk2_ardour/utils.cc
@@ -215,7 +215,7 @@ get_font_for_style (string widgetname)
{
Gtk::Window window (WINDOW_TOPLEVEL);
Gtk::Label foobar;
- Glib::RefPtr<Style> style;
+ Glib::RefPtr<Gtk::Style> style;
window.add (foobar);
foobar.set_name (widgetname);
@@ -435,12 +435,10 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
if (!special_handling_of_unmodified_accelerators ||
ev->state & (Gdk::MOD1_MASK|
- Gdk::MOD2_MASK|
Gdk::MOD3_MASK|
Gdk::MOD4_MASK|
Gdk::MOD5_MASK|
- Gdk::CONTROL_MASK|
- Gdk::LOCK_MASK)) {
+ Gdk::CONTROL_MASK)) {
/* no special handling or modifiers in effect: accelerate first */
diff --git a/gtk2_ardour/visual_time_axis.cc b/gtk2_ardour/visual_time_axis.cc
index c27ed33089..e44ea4011e 100644
--- a/gtk2_ardour/visual_time_axis.cc
+++ b/gtk2_ardour/visual_time_axis.cc
@@ -255,7 +255,7 @@ VisualTimeAxis::set_time_axis_color(Gdk::Color c)
}
void
-VisualTimeAxis::set_selected_regionviews (AudioRegionSelection& regions)
+VisualTimeAxis::set_selected_regionviews (RegionSelection& regions)
{
// Not handled by purely visual TimeAxis
}
diff --git a/gtk2_ardour/visual_time_axis.h b/gtk2_ardour/visual_time_axis.h
index 4be2da3b9a..c68ce8da1c 100644
--- a/gtk2_ardour/visual_time_axis.h
+++ b/gtk2_ardour/visual_time_axis.h
@@ -42,7 +42,7 @@ class ImageFrameView;
class ImageFrameTimeAxisView;
class MarkersTimeAxisView;
class TimeSelection;
-class AudioRegionSelection;
+class RegionSelection;
class MarkerTimeAxis;
class TimeAxisViewStrip;
@@ -105,7 +105,7 @@ class VisualTimeAxis : public TimeAxisView
/**
* Not implemented
*/
- virtual void set_selected_regionviews(AudioRegionSelection&) ;
+ virtual void set_selected_regionviews(RegionSelection&) ;
//---------------------------------------------------------------------------------//
diff --git a/libs/appleutility/AUOutputBL.cpp b/libs/appleutility/AUOutputBL.cpp
new file mode 100644
index 0000000000..8509f46288
--- /dev/null
+++ b/libs/appleutility/AUOutputBL.cpp
@@ -0,0 +1,160 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ AUOutputBL.h
+
+=============================================================================*/
+#include "AUOutputBL.h"
+
+/*
+struct AudioBufferList
+{
+ UInt32 mNumberBuffers;
+ AudioBuffer mBuffers[1];
+};
+struct AudioBuffer
+{
+ UInt32 mNumberChannels; // number of interleaved channels in the buffer
+ UInt32 mDataByteSize; // the size of the buffer pointed to by mData
+ void* mData; // the pointer to the buffer
+};
+*/
+
+AUOutputBL::AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames)
+ : mFormat (inDesc),
+ mBufferMemory(NULL),
+ mBufferList (NULL),
+ mNumberBuffers (0), // keep this here, so can ensure integrity of ABL
+ mBufferSize (0),
+ mFrames(inDefaultNumFrames)
+{
+ mNumberBuffers = mFormat.IsInterleaved() ? 1 : mFormat.NumberChannels();
+ mBufferList = reinterpret_cast<AudioBufferList*>(new Byte[sizeof(UInt32) + (mNumberBuffers * sizeof(AudioBuffer))]);
+}
+
+AUOutputBL::~AUOutputBL()
+{
+ if (mBufferMemory)
+ delete[] mBufferMemory;
+
+ if (mBufferList)
+ delete [] mBufferList;
+}
+
+void AUOutputBL::Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated)
+{
+ UInt32 channelsPerBuffer = mFormat.IsInterleaved() ? mFormat.NumberChannels() : 1;
+
+ if (mBufferMemory == NULL || inWantNullBufferIfAllocated)
+ {
+ mBufferList->mNumberBuffers = mNumberBuffers;
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
+ buf->mNumberChannels = channelsPerBuffer;
+ buf->mDataByteSize = mFormat.FramesToBytes (inNumFrames);
+ buf->mData = NULL;
+ }
+ }
+ else
+ {
+ UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
+ if ((nBytes * mNumberBuffers) > AllocatedBytes())
+ throw OSStatus(-10874);//(kAudioUnitErr_TooManyFramesToProcess);
+
+ mBufferList->mNumberBuffers = mNumberBuffers;
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ Byte* p = mBufferMemory;
+ for (UInt32 i = 0; i < mNumberBuffers; ++i, ++buf) {
+ buf->mNumberChannels = channelsPerBuffer;
+ buf->mDataByteSize = nBytes;
+ buf->mData = p;
+ p += mBufferSize;
+ }
+ }
+}
+
+
+void AUOutputBL::Allocate (UInt32 inNumFrames)
+{
+ if (inNumFrames)
+ {
+ UInt32 nBytes = mFormat.FramesToBytes (inNumFrames);
+
+ if (nBytes <= AllocatedBytes())
+ return;
+
+ // align successive buffers for Altivec and to take alternating
+ // cache line hits by spacing them by odd multiples of 16
+ if (mNumberBuffers > 1)
+ nBytes = (nBytes + (0x10 - (nBytes & 0xF))) | 0x10;
+
+ mBufferSize = nBytes;
+
+ UInt32 memorySize = mBufferSize * mNumberBuffers;
+ Byte *newMemory = new Byte[memorySize];
+ memset(newMemory, 0, memorySize); // make buffer "hot"
+
+ Byte *oldMemory = mBufferMemory;
+ mBufferMemory = newMemory;
+ delete[] oldMemory;
+
+ mFrames = inNumFrames;
+ }
+ else
+ {
+ if (mBufferMemory) {
+ delete [] mBufferMemory;
+ mBufferMemory = NULL;
+ }
+ mBufferSize = 0;
+ mFrames = 0;
+ }
+}
+
+#if DEBUG
+void AUOutputBL::Print()
+{
+ printf ("AUOutputBL::Print\n");
+ mFormat.Print();
+ printf ("Num Buffers:%ld, mFrames:%ld, allocatedMemory:%c\n", mBufferList->mNumberBuffers, mFrames, (mBufferMemory != NULL ? 'T' : 'F'));
+ AudioBuffer *buf = &mBufferList->mBuffers[0];
+ for (UInt32 i = 0; i < mBufferList->mNumberBuffers; ++i, ++buf)
+ printf ("\tBuffer:%ld, Size:%ld, Chans:%ld, Buffer:%X\n", i, buf->mDataByteSize, buf->mNumberChannels, int(buf->mData));
+}
+#endif
+
diff --git a/libs/appleutility/AUOutputBL.h b/libs/appleutility/AUOutputBL.h
new file mode 100644
index 0000000000..b80588abac
--- /dev/null
+++ b/libs/appleutility/AUOutputBL.h
@@ -0,0 +1,115 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ AUOutputBL.h
+
+=============================================================================*/
+
+#ifndef __AUOutputBL_h__
+#define __AUOutputBL_h__
+
+#include "CAStreamBasicDescription.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+#else
+ #include <AssertMacros.h>
+#endif
+
+// ____________________________________________________________________________
+//
+// AUOutputBL - Simple Buffer List wrapper targetted to use with retrieving AU output
+// Works in one of two ways (both adjustable)... Can use it with NULL pointers, or allocate
+// memory to receive the data in.
+
+// Before using this with any call to AudioUnitRender, it needs to be Prepared
+// as some calls to AudioUnitRender can reset the ABL
+
+class AUOutputBL {
+public:
+
+ // you CANNOT use one of these - it will crash!
+// AUOutputBL ();
+
+ // this is the constructor that you use
+ // it can't be reset once you've constructed it
+ AUOutputBL (const CAStreamBasicDescription &inDesc, UInt32 inDefaultNumFrames = 512);
+ ~AUOutputBL();
+
+ void Prepare ()
+ {
+ Prepare (mFrames);
+ }
+
+ // this version can throw if this is an allocted ABL and inNumFrames is > AllocatedFrames()
+ // you can set the bool to true if you want a NULL buffer list even if allocated
+ // inNumFrames must be a valid number (will throw if inNumFrames is 0)
+ void Prepare (UInt32 inNumFrames, bool inWantNullBufferIfAllocated = false);
+
+ AudioBufferList* ABL() { return mBufferList; }
+
+ // You only need to call this if you want to allocate a buffer list
+ // if you want an empty buffer list, just call Prepare()
+ // if you want to dispose previously allocted memory, pass in 0
+ // then you either have an empty buffer list, or you can re-allocate
+ // Memory is kept around if an Allocation request is less than what is currently allocated
+ void Allocate (UInt32 inNumberFrames);
+
+ UInt32 AllocatedFrames() const { return mFrames; }
+
+ const CAStreamBasicDescription& GetFormat() const { return mFormat; }
+
+#if DEBUG
+ void Print();
+#endif
+
+private:
+ UInt32 AllocatedBytes () const { return (mBufferSize * mNumberBuffers); }
+
+ CAStreamBasicDescription mFormat;
+ Byte* mBufferMemory;
+ AudioBufferList* mBufferList;
+ UInt32 mNumberBuffers;
+ UInt32 mBufferSize;
+ UInt32 mFrames;
+
+// don't want to copy these.. can if you want, but more code to write!
+ AUOutputBL (const AUOutputBL &c) {}
+ AUOutputBL& operator= (const AUOutputBL& c) { return *this; }
+};
+
+#endif // __AUOutputBL_h__
diff --git a/libs/appleutility/CAAudioChannelLayout.cpp b/libs/appleutility/CAAudioChannelLayout.cpp
new file mode 100644
index 0000000000..585ff44fb7
--- /dev/null
+++ b/libs/appleutility/CAAudioChannelLayout.cpp
@@ -0,0 +1,138 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAAudioChannelLayout.cpp
+
+=============================================================================*/
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CAAudioChannelLayout.h"
+#include <stdlib.h>
+#include <string.h>
+
+//=============================================================================
+// CAAudioChannelLayout
+//=============================================================================
+
+AudioChannelLayout* CAAudioChannelLayout::Create(UInt32 inNumberChannelDescriptions)
+{
+ UInt32 theSize = CalculateByteSize(inNumberChannelDescriptions);
+ AudioChannelLayout* theAnswer = static_cast<AudioChannelLayout*>(calloc(1, theSize));
+ if(theAnswer != NULL)
+ {
+ SetAllToUnknown(*theAnswer, inNumberChannelDescriptions);
+ }
+ return theAnswer;
+}
+
+void CAAudioChannelLayout::Destroy(AudioChannelLayout* inChannelLayout)
+{
+ free(inChannelLayout);
+}
+
+void CAAudioChannelLayout::SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions)
+{
+ outChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+ outChannelLayout.mChannelBitmap = 0;
+ outChannelLayout.mNumberChannelDescriptions = inNumberChannelDescriptions;
+ for(UInt32 theChannelIndex = 0; theChannelIndex < inNumberChannelDescriptions; ++theChannelIndex)
+ {
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelLabel = kAudioChannelLabel_Unknown;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mChannelFlags = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[0] = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[1] = 0;
+ outChannelLayout.mChannelDescriptions[theChannelIndex].mCoordinates[2] = 0;
+ }
+}
+
+bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y)
+{
+ // compare based on the number of channel descriptions present
+ // (this may be too strict a comparison if all you care about are matching layout tags)
+ UInt32 theSize1 = CAAudioChannelLayout::CalculateByteSize(x.mNumberChannelDescriptions);
+ UInt32 theSize2 = CAAudioChannelLayout::CalculateByteSize(y.mNumberChannelDescriptions);
+
+ if (theSize1 != theSize2)
+ return false;
+
+ return !memcmp (&x, &y, theSize1);
+}
+
+// counting the one bits in a word
+inline UInt32 CountOnes(UInt32 x)
+{
+ // secret magic algorithm for counting bits in a word.
+ UInt32 t;
+ x = x - ((x >> 1) & 0x55555555);
+ t = ((x >> 2) & 0x33333333);
+ x = (x & 0x33333333) + t;
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ x = x + (x << 8);
+ x = x + (x << 16);
+ return x >> 24;
+}
+
+UInt32 CAAudioChannelLayout::NumberChannels (const AudioChannelLayout& inLayout)
+{
+ if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions)
+ return inLayout.mNumberChannelDescriptions;
+
+ if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+ return CountOnes (inLayout.mChannelBitmap);
+
+ return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
+}
+
+void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout)
+{
+ fprintf (file, "\tTag=0x%lX, ", layout->mChannelLayoutTag);
+ if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap)
+ fprintf (file, "Using Bitmap:0x%lX\n", layout->mChannelBitmap);
+ else {
+ fprintf (file, "Num Chan Descs=%ld\n", layout->mNumberChannelDescriptions);
+ const AudioChannelDescription *desc = layout->mChannelDescriptions;
+ for (unsigned int i = 0; i < layout->mNumberChannelDescriptions; ++i, ++desc) {
+ fprintf (file, "\t\tLabel=%ld, Flags=0x%lX, ", desc->mChannelLabel, desc->mChannelFlags);
+ fprintf (file, "[az=%f,el=%f,dist=%f]\n", desc->mCoordinates[0], desc->mCoordinates[1], desc->mCoordinates[2]);
+ }
+ }
+}
diff --git a/libs/appleutility/CAAudioChannelLayout.h b/libs/appleutility/CAAudioChannelLayout.h
new file mode 100644
index 0000000000..8f995b8614
--- /dev/null
+++ b/libs/appleutility/CAAudioChannelLayout.h
@@ -0,0 +1,162 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAAudioChannelLayout.h
+
+=============================================================================*/
+#if !defined(__CAAudioChannelLayout_h__)
+#define __CAAudioChannelLayout_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CoreFoundation.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !HAL_Build
+ #include "CAReferenceCounted.h"
+#endif
+
+//=============================================================================
+// CAAudioChannelLayout
+//=============================================================================
+
+bool operator== (const AudioChannelLayout &x, const AudioChannelLayout &y);
+
+extern "C" void CAShowAudioChannelLayout (FILE* file, const AudioChannelLayout *layout);
+
+class CAAudioChannelLayout
+{
+// static Construction/Destruction
+public:
+ static AudioChannelLayout* Create(UInt32 inNumberChannelDescriptions);
+ static void Destroy(AudioChannelLayout* inChannelLayout);
+ static UInt32 CalculateByteSize(UInt32 inNumberChannelDescriptions) {
+ return offsetof(AudioChannelLayout, mChannelDescriptions) + inNumberChannelDescriptions * sizeof(AudioChannelDescription);
+ }
+ static void SetAllToUnknown(AudioChannelLayout& outChannelLayout, UInt32 inNumberChannelDescriptions);
+ static UInt32 NumberChannels(const AudioChannelLayout& inLayout);
+
+#if !HAL_Build
+// object methods
+public:
+ CAAudioChannelLayout ();
+
+ CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+ // if inChooseSurround is false, then symmetrical speaker arrangements
+ // are chosen in place of surround layouts if there is a choice
+ // This call chooses layouts based on the expected defaults in
+ // AudioUnit usage
+ CAAudioChannelLayout (AudioChannelLayoutTag inTag);
+ CAAudioChannelLayout (const CAAudioChannelLayout &c);
+ CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout);
+ ~CAAudioChannelLayout();
+
+ CAAudioChannelLayout& operator= (const AudioChannelLayout* inChannelLayout);
+ CAAudioChannelLayout& operator= (const CAAudioChannelLayout& c);
+ bool operator== (const CAAudioChannelLayout &c) const;
+
+ void SetWithTag(AudioChannelLayoutTag inTag);
+
+ bool IsValid() const { return NumberChannels() > 0; }
+ UInt32 Size() const { return mLayoutHolder ? mLayoutHolder->Size() : 0; }
+
+ UInt32 NumberChannels() const { return NumberChannels(Layout()); }
+
+ AudioChannelLayoutTag Tag() const { return Layout().mChannelLayoutTag; }
+ const AudioChannelLayout& Layout() const { return mLayoutHolder->Layout(); }
+ operator const AudioChannelLayout *() const { return &Layout(); }
+
+ void Print () const { Print (stdout); }
+ void Print (FILE* file) const;
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ class ACLRefCounter : public CAReferenceCounted {
+ public:
+ ACLRefCounter (UInt32 inDataSize)
+ {
+ if (inDataSize < offsetof(AudioChannelLayout, mChannelDescriptions))
+ inDataSize = offsetof(AudioChannelLayout, mChannelDescriptions);
+
+ mLayout = static_cast<AudioChannelLayout*>(malloc (inDataSize));
+ memset (mLayout, 0, inDataSize);
+ mByteSize = inDataSize;
+ }
+
+ const AudioChannelLayout & Layout() const { return *mLayout; }
+
+ UInt32 Size () const { return mByteSize; }
+
+ private:
+ AudioChannelLayout *mLayout;
+ UInt32 mByteSize;
+
+ // only the constructors can change the actual state of the layout
+ friend CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround);
+ friend OSStatus CAAudioChannelLayout::Restore (CFPropertyListRef &inData);
+ friend CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout);
+ friend void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag);
+
+ AudioChannelLayout * GetLayout() { return mLayout; }
+ ~ACLRefCounter() { if (mLayout) { free(mLayout); mLayout = NULL; } }
+
+ private:
+ ACLRefCounter () : mLayout(NULL) { }
+ ACLRefCounter(const ACLRefCounter& c) : mLayout(NULL) { }
+ ACLRefCounter& operator=(const ACLRefCounter& c) { return *this; }
+ };
+
+ ACLRefCounter *mLayoutHolder;
+#endif // HAL_Build
+
+};
+
+#endif
diff --git a/libs/appleutility/CAAudioChannelLayoutObject.cpp b/libs/appleutility/CAAudioChannelLayoutObject.cpp
new file mode 100644
index 0000000000..8c4030048d
--- /dev/null
+++ b/libs/appleutility/CAAudioChannelLayoutObject.cpp
@@ -0,0 +1,199 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAAudioChannelLayoutObject.cpp
+
+=============================================================================*/
+
+#include "CAAudioChannelLayout.h"
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+ #include <AudioToolbox/AudioFormat.h>
+#else
+ #include <CoreServices.h>
+ #include <AudioFormat.h>
+#endif
+
+
+CAAudioChannelLayout::CAAudioChannelLayout ()
+{
+ mLayoutHolder = new ACLRefCounter (offsetof(AudioChannelLayout, mChannelDescriptions));
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (UInt32 inNumberChannels, bool inChooseSurround)
+{
+ // this chooses default layouts based on the number of channels...
+ UInt32 theSize = CalculateByteSize (inNumberChannels);
+
+ mLayoutHolder = new ACLRefCounter (theSize);
+
+ AudioChannelLayout* layout = mLayoutHolder->GetLayout();
+
+ layout->mNumberChannelDescriptions = inNumberChannels;
+
+ switch (inNumberChannels)
+ {
+ case 1:
+ layout->mChannelLayoutTag = kAudioChannelLayoutTag_Mono;
+ break;
+ case 2:
+ layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Binaural : kAudioChannelLayoutTag_Stereo;
+ break;
+ case 4:
+ layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_Ambisonic_B_Format : kAudioChannelLayoutTag_AudioUnit_4;
+ break;
+ case 5:
+ layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_5_0 : kAudioChannelLayoutTag_AudioUnit_5;
+ break;
+ case 6:
+ layout->mChannelLayoutTag = inChooseSurround ? kAudioChannelLayoutTag_AudioUnit_6_0 : kAudioChannelLayoutTag_AudioUnit_6;
+ break;
+ case 7:
+ layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_7_0;
+ break;
+ case 8:
+ layout->mChannelLayoutTag = kAudioChannelLayoutTag_AudioUnit_8;
+ break;
+ default:
+ // here we have a "broken" layout, in the sense that we haven't any idea how to lay this out
+ // the layout itself is all set to zeros
+ // ### no longer true ###
+ SetAllToUnknown(*layout, inNumberChannels);
+ break;
+ }
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (AudioChannelLayoutTag inLayoutTag)
+ : mLayoutHolder(NULL)
+{
+ SetWithTag(inLayoutTag);
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (const CAAudioChannelLayout &c)
+ : mLayoutHolder(NULL)
+{
+ *this = c;
+}
+
+
+//=============================================================================
+// CAAudioChannelLayout::AudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::CAAudioChannelLayout (const AudioChannelLayout* inChannelLayout)
+ : mLayoutHolder(NULL)
+{
+ *this = inChannelLayout;
+}
+
+//=============================================================================
+// CAAudioChannelLayout::~CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout::~CAAudioChannelLayout ()
+{
+ if (mLayoutHolder) {
+ mLayoutHolder->release();
+ mLayoutHolder = NULL;
+ }
+}
+
+//=============================================================================
+// CAAudioChannelLayout::CAAudioChannelLayout
+//=============================================================================
+CAAudioChannelLayout& CAAudioChannelLayout::operator= (const CAAudioChannelLayout &c)
+{
+ if (mLayoutHolder != c.mLayoutHolder) {
+ if (mLayoutHolder)
+ mLayoutHolder->release();
+
+ if ((mLayoutHolder = c.mLayoutHolder) != NULL)
+ mLayoutHolder->retain();
+ }
+
+ return *this;
+}
+
+CAAudioChannelLayout& CAAudioChannelLayout::operator= (const AudioChannelLayout* inChannelLayout)
+{
+ if (mLayoutHolder)
+ mLayoutHolder->release();
+
+ UInt32 theSize = CalculateByteSize (inChannelLayout->mNumberChannelDescriptions);
+
+ mLayoutHolder = new ACLRefCounter (theSize);
+
+ memcpy(mLayoutHolder->mLayout, inChannelLayout, theSize);
+ return *this;
+}
+
+void CAAudioChannelLayout::SetWithTag(AudioChannelLayoutTag inTag)
+{
+ if (mLayoutHolder)
+ mLayoutHolder->release();
+
+ mLayoutHolder = new ACLRefCounter(offsetof(AudioChannelLayout, mChannelDescriptions[0]));
+ AudioChannelLayout* layout = mLayoutHolder->GetLayout();
+ layout->mChannelLayoutTag = inTag;
+}
+
+//=============================================================================
+// CAAudioChannelLayout::operator==
+//=============================================================================
+bool CAAudioChannelLayout::operator== (const CAAudioChannelLayout &c) const
+{
+ if (mLayoutHolder == c.mLayoutHolder)
+ return true;
+ return Layout() == c.Layout();
+}
+
+//=============================================================================
+// CAAudioChannelLayout::Print
+//=============================================================================
+void CAAudioChannelLayout::Print (FILE* file) const
+{
+ CAShowAudioChannelLayout (file, &Layout());
+}
+
diff --git a/libs/appleutility/CAAudioUnit.cpp b/libs/appleutility/CAAudioUnit.cpp
new file mode 100644
index 0000000000..9244877d29
--- /dev/null
+++ b/libs/appleutility/CAAudioUnit.cpp
@@ -0,0 +1,1202 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAAudioUnit.cpp
+
+=============================================================================*/
+
+#include "CAAudioUnit.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <AudioUnit/MusicDevice.h>
+#else
+ #include <MusicDevice.h>
+#endif
+
+#include "CAReferenceCounted.h"
+#include "AUOutputBL.h" //this is for the Preroll only
+
+
+struct StackAUChannelInfo {
+ StackAUChannelInfo (UInt32 inSize) : mChanInfo ((AUChannelInfo*)malloc (inSize)) {}
+ ~StackAUChannelInfo() { free (mChanInfo); }
+
+ AUChannelInfo* mChanInfo;
+};
+
+
+
+class CAAudioUnit::AUState : public CAReferenceCounted {
+public:
+ AUState (Component inComp)
+ : mUnit(0), mNode (0)
+ {
+ OSStatus result = ::OpenAComponent (inComp, &mUnit);
+ if (result)
+ throw result;
+ Init();
+ }
+
+ AUState (const AUNode &inNode, const AudioUnit& inUnit)
+ : mUnit (inUnit), mNode (inNode)
+ {
+ Init();
+ }
+
+ ~AUState();
+
+ AudioUnit mUnit;
+ AUNode mNode;
+
+ OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const
+ {
+ if (mGetParamProc != NULL) {
+ return reinterpret_cast<AudioUnitGetParameterProc>(mGetParamProc) (mConnInstanceStorage,
+ inID, scope, element, &outValue);
+ }
+ return AudioUnitGetParameter(mUnit, inID, scope, element, &outValue);
+ }
+
+ OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames)
+ {
+ if (mSetParamProc != NULL) {
+ return reinterpret_cast<AudioUnitSetParameterProc>(mSetParamProc) (mConnInstanceStorage,
+ inID, scope, element, value, bufferOffsetFrames);
+ }
+ return AudioUnitSetParameter(mUnit, inID, scope, element, value, bufferOffsetFrames);
+ }
+
+ OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData)
+ {
+ if (mRenderProc != NULL) {
+ return reinterpret_cast<AudioUnitRenderProc>(mRenderProc) (mConnInstanceStorage,
+ ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData);
+ }
+ return AudioUnitRender(mUnit, ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData);
+ }
+
+ OSStatus MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame)
+ {
+#if !TARGET_OS_WIN32
+ if (mMIDIEventProc != NULL) {
+ return reinterpret_cast<MusicDeviceMIDIEventProc>(mMIDIEventProc) (mConnInstanceStorage,
+ inStatus, inData1, inData2, inOffsetSampleFrame);
+ }
+ return MusicDeviceMIDIEvent (mUnit, inStatus, inData1, inData2, inOffsetSampleFrame);
+#else
+ return paramErr;
+#endif
+ }
+
+ OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+ {
+#if !TARGET_OS_WIN32
+ return MusicDeviceStartNote (mUnit, inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams);
+#else
+ return paramErr;
+#endif
+ }
+ OSStatus StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame)
+ {
+#if !TARGET_OS_WIN32
+ return MusicDeviceStopNote (mUnit, inGroupID, inNoteInstanceID, inOffsetSampleFrame);
+#else
+ return paramErr;
+#endif
+ }
+
+private:
+ // get the fast dispatch pointers
+ void Init()
+ {
+ UInt32 size = sizeof(AudioUnitRenderProc);
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitRenderSelect,
+ &mRenderProc, &size) != noErr)
+ mRenderProc = NULL;
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitGetParameterSelect,
+ &mGetParamProc, &size) != noErr)
+ mGetParamProc = NULL;
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kAudioUnitSetParameterSelect,
+ &mSetParamProc, &size) != noErr)
+ mSetParamProc = NULL;
+
+ if (AudioUnitGetProperty(mUnit, kAudioUnitProperty_FastDispatch,
+ kAudioUnitScope_Global, kMusicDeviceMIDIEventSelect,
+ &mMIDIEventProc, &size) != noErr)
+ mMIDIEventProc = NULL;
+
+ if (mRenderProc || mGetParamProc || mSetParamProc || mMIDIEventProc)
+ mConnInstanceStorage = GetComponentInstanceStorage(mUnit);
+ else
+ mConnInstanceStorage = NULL;
+ }
+
+ ProcPtr mRenderProc, mGetParamProc, mSetParamProc, mMIDIEventProc;
+
+ void * mConnInstanceStorage;
+
+private:
+ // get the compiler to tell us when we do a bad thing!!!
+ AUState () {}
+ AUState (const AUState&) {}
+ AUState& operator= (const AUState&) { return *this; }
+};
+
+
+CAAudioUnit::AUState::~AUState ()
+{
+ if (mUnit && (mNode == 0)) {
+ ::CloseComponent (mUnit);
+ }
+ mNode = 0;
+ mUnit = 0;
+}
+
+OSStatus CAAudioUnit::Open (const CAComponent& inComp, CAAudioUnit &outUnit)
+{
+ try {
+ outUnit = inComp;
+ return noErr;
+ } catch (OSStatus res) {
+ return res;
+ } catch (...) {
+ return -1;
+ }
+}
+
+CAAudioUnit::CAAudioUnit (const AudioUnit& inUnit)
+ : mComp (inUnit), mDataPtr (new AUState (-1, inUnit))
+{
+}
+
+CAAudioUnit::CAAudioUnit (const CAComponent& inComp)
+ : mComp (inComp), mDataPtr (0)
+{
+ mDataPtr = new AUState (mComp.Comp());
+}
+
+CAAudioUnit::CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit)
+ : mComp (inUnit), mDataPtr(new AUState (inNode, inUnit))
+{
+}
+
+CAAudioUnit::~CAAudioUnit ()
+{
+ if (mDataPtr) {
+ mDataPtr->release();
+ mDataPtr = NULL;
+ }
+}
+
+CAAudioUnit& CAAudioUnit::operator= (const CAAudioUnit &a)
+{
+ if (mDataPtr != a.mDataPtr) {
+ if (mDataPtr)
+ mDataPtr->release();
+
+ if ((mDataPtr = a.mDataPtr) != NULL)
+ mDataPtr->retain();
+
+ mComp = a.mComp;
+ }
+
+ return *this;
+}
+
+bool CAAudioUnit::operator== (const CAAudioUnit& y) const
+{
+ if (mDataPtr == y.mDataPtr) return true;
+ AudioUnit au1 = mDataPtr ? mDataPtr->mUnit : 0;
+ AudioUnit au2 = y.mDataPtr ? y.mDataPtr->mUnit : 0;
+ return au1 == au2;
+}
+
+bool CAAudioUnit::operator== (const AudioUnit& y) const
+{
+ if (!mDataPtr) return false;
+ return mDataPtr->mUnit == y;
+}
+
+#pragma mark __State Management
+
+bool CAAudioUnit::IsValid () const
+{
+ return mDataPtr ? mDataPtr->mUnit != 0 : false;
+}
+
+AudioUnit CAAudioUnit::AU() const
+{
+ return mDataPtr ? mDataPtr->mUnit : 0;
+}
+
+AUNode CAAudioUnit::GetAUNode () const
+{
+ return mDataPtr ? mDataPtr->mNode : 0;
+}
+
+#pragma mark __Format Handling
+
+bool CAAudioUnit::CanDo ( int inChannelsIn,
+ int inChannelsOut) const
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+ if (result)
+ {
+ if (Comp().Desc().IsEffect() && (inChannelsIn == inChannelsOut)
+ || Comp().Desc().IsOffline() && (inChannelsIn == inChannelsOut))
+ {
+ return true;
+ }
+ else
+ {
+ // the au should either really tell us about this
+ // or we will assume the worst
+ return false;
+ }
+ }
+
+ StackAUChannelInfo info (dataSize);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize);
+ if (result) { return false; }
+
+ return ValidateChannelPair (inChannelsIn, inChannelsOut, info.mChanInfo, (dataSize / sizeof (AUChannelInfo)));
+}
+
+bool CAAudioUnit::ValidateChannelPair (int inChannelsIn,
+ int inChannelsOut,
+ const AUChannelInfo * info,
+ UInt32 numChanInfo) const
+{
+// we've the following cases (some combinations) to test here:
+/*
+>0 An explicit number of channels on either side
+0 that side (generally input!) has no elements
+-1 wild card:
+-1,-1 any num channels as long as same channels on in and out
+-1,-2 any num channels channels on in and out - special meaning
+-2+ indicates total num channs AU can handle
+ - elements configurable to any num channels,
+ - element count in scope must be writable
+*/
+
+ //now chan layout can contain -1 for either scope (ie. doesn't care)
+ for (unsigned int i = 0; i < numChanInfo; ++i)
+ {
+ //less than zero on both sides - check for special attributes
+ if ((info[i].inChannels < 0) && (info[i].outChannels < 0))
+ {
+ // these are our wild card matches
+ if (info[i].inChannels == -1 && info[i].outChannels == -1) {
+ if (inChannelsOut == inChannelsIn) {
+ return true;
+ }
+ }
+ else if ((info[i].inChannels == -1 && info[i].outChannels == -2)
+ || (info[i].inChannels == -2 && info[i].outChannels == -1))
+ {
+ return true;
+ }
+ // these are our total num channels matches
+ // element count MUST be writable
+ else {
+ bool outWrite = false; bool inWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Output, outWrite);
+ IsElementCountWritable (kAudioUnitScope_Input, inWrite);
+ if (inWrite && outWrite) {
+ if ((inChannelsOut <= abs(info[i].outChannels))
+ && (inChannelsIn <= abs(info[i].inChannels)))
+ {
+ return true;
+ }
+ }
+ }
+ }
+
+ // special meaning on input, specific num on output
+ else if (info[i].inChannels < 0) {
+ if (info[i].outChannels == inChannelsOut)
+ {
+ // can do any in channels
+ if (info[i].inChannels == -1) {
+ return true;
+ }
+ // total chans on input
+ else {
+ bool inWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Input, inWrite);
+ if (inWrite && (inChannelsIn <= abs(info[i].inChannels))) {
+ return true;
+ }
+ }
+ }
+ }
+
+ // special meaning on output, specific num on input
+ else if (info[i].outChannels < 0) {
+ if (info[i].inChannels == inChannelsIn)
+ {
+ // can do any out channels
+ if (info[i].outChannels == -1) {
+ return true;
+ }
+ // total chans on output
+ else {
+ bool outWrite = false;
+ IsElementCountWritable (kAudioUnitScope_Output, outWrite);
+ if (outWrite && (inChannelsOut <= abs(info[i].outChannels))) {
+ return true;
+ }
+ }
+ }
+ }
+
+ // both chans in struct >= 0 - thus has to explicitly match
+ else if ((info[i].inChannels == inChannelsIn) && (info[i].outChannels == inChannelsOut)) {
+ return true;
+ }
+
+ // now check to see if a wild card on the args (inChannelsIn or inChannelsOut chans is zero) is found
+ // tells us to match just one side of the scopes
+ else if (inChannelsIn == 0) {
+ if (info[i].outChannels == inChannelsOut) {
+ return true;
+ }
+ }
+ else if (inChannelsOut == 0) {
+ if (info[i].inChannels == inChannelsIn) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool CheckDynCount (SInt32 inTotalChans, const CAAUChanHelper &inHelper)
+{
+ int totalChans = 0;
+ for (unsigned int i = 0; i < inHelper.mNumEls; ++i)
+ totalChans += inHelper.mChans[i];
+ return (totalChans <= inTotalChans);
+}
+
+bool CAAudioUnit::CheckOneSide (const CAAUChanHelper &inHelper,
+ bool checkOutput,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const
+{
+ // now we can use the wildcard option (see above impl) to see if this matches
+ for (unsigned int el = 0; el < inHelper.mNumEls; ++el) {
+ bool testAlready = false;
+ for (unsigned int i = 0; i < el; ++i) {
+ if (inHelper.mChans[i] == inHelper.mChans[el]) {
+ testAlready = true;
+ break;
+ }
+ }
+ if (!testAlready) {
+ if (checkOutput) {
+ if (!ValidateChannelPair (0, inHelper.mChans[el], info, numInfo)) return false;
+ } else {
+ if (!ValidateChannelPair (inHelper.mChans[el], 0, info, numInfo)) return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool CAAudioUnit::CanDo (const CAAUChanHelper &inputs,
+ const CAAUChanHelper &outputs) const
+
+{
+// first check our state
+ // huh!
+ if (inputs.mNumEls == 0 && outputs.mNumEls == 0) return false;
+
+ UInt32 elCount;
+ if (GetElementCount (kAudioUnitScope_Input, elCount)) { return false; }
+ if (elCount != inputs.mNumEls) return false;
+
+ if (GetElementCount (kAudioUnitScope_Output, elCount)) { return false; }
+ if (elCount != outputs.mNumEls) return false;
+
+// (1) special cases (effects and sources (generators and instruments) only)
+ UInt32 dataSize = 0;
+ if (GetPropertyInfo (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0, &dataSize, NULL) != noErr)
+ {
+ if (Comp().Desc().IsEffect() || Comp().Desc().IsOffline()) {
+ UInt32 numChan = outputs.mNumEls > 0 ? outputs.mChans[0] : inputs.mChans[0];
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in)
+ if (numChan != inputs.mChans[in]) return false;
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out)
+ if (numChan != outputs.mChans[out]) return false;
+ return true;
+ }
+
+ // in this case, all the channels have to match the current config
+ if (Comp().Desc().IsGenerator() || Comp().Desc().IsMusicDevice()) {
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in) {
+ UInt32 chan;
+ if (NumberChannels (kAudioUnitScope_Input, in, chan)) return false;
+ if (chan != UInt32(inputs.mChans[in])) return false;
+ }
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
+ UInt32 chan;
+ if (NumberChannels (kAudioUnitScope_Output, out, chan)) return false;
+ if (chan != UInt32(outputs.mChans[out])) return false;
+ }
+ return true;
+ }
+
+ // if we get here we can't determine anything about channel capabilities
+ return false;
+ }
+
+ StackAUChannelInfo info (dataSize);
+
+ if (GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize) != noErr)
+ {
+ return false;
+ }
+
+ int numInfo = dataSize / sizeof(AUChannelInfo);
+
+// (2) Test for dynamic capability (or no elements on that scope)
+ SInt32 dynInChans = 0;
+ if (ValidateDynamicScope (kAudioUnitScope_Input, dynInChans, info.mChanInfo, numInfo)) {
+ if (CheckDynCount (dynInChans, inputs) == false) return false;
+ }
+
+ SInt32 dynOutChans = 0;
+ if (ValidateDynamicScope (kAudioUnitScope_Output, dynOutChans, info.mChanInfo, numInfo)) {
+ if (CheckDynCount (dynOutChans, outputs) == false) return false;
+ }
+
+ if (dynOutChans && dynInChans) { return true; }
+
+// (3) Just need to test one side
+ if (dynInChans || (inputs.mNumEls == 0)) {
+ return CheckOneSide (outputs, true, info.mChanInfo, numInfo);
+ }
+
+ if (dynOutChans || (outputs.mNumEls == 0)) {
+ return CheckOneSide (inputs, false, info.mChanInfo, numInfo);
+ }
+
+// (4) - not a dynamic AU, has ins and outs, and has channel constraints so we test every possible pairing
+ for (unsigned int in = 0; in < inputs.mNumEls; ++in)
+ {
+ bool testInAlready = false;
+ for (unsigned int i = 0; i < in; ++i) {
+ if (inputs.mChans[i] == inputs.mChans[in]) {
+ testInAlready = true;
+ break;
+ }
+ }
+ if (!testInAlready) {
+ for (unsigned int out = 0; out < outputs.mNumEls; ++out) {
+ // try to save a little bit and not test the same pairing multiple times...
+ bool testOutAlready = false;
+ for (unsigned int i = 0; i < out; ++i) {
+ if (outputs.mChans[i] == outputs.mChans[out]) {
+ testOutAlready = true;
+ break;
+ }
+ }
+ if (!testOutAlready) {
+ if (!ValidateChannelPair (inputs.mChans[in], outputs.mChans[out],info.mChanInfo, numInfo)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CAAudioUnit::SupportsNumChannels () const
+{
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ // lets see if the unit has any channel restrictions
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // if this property is NOT implemented an FX unit
+ // is expected to deal with same channel valance in and out
+ if (result) {
+ if (Comp().Desc().IsEffect() || Comp().Desc().IsOffline())
+ return true;
+ }
+ return result == noErr;
+}
+
+bool CAAudioUnit::GetChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ ChannelTagVector &outChannelVector) const
+{
+ if (HasChannelLayouts (inScope, inEl) == false) return false;
+
+ UInt32 dataSize;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ &dataSize, NULL);
+
+ if (result == kAudioUnitErr_InvalidProperty) {
+ // if we get here we can do layouts but we've got the speaker config property
+ outChannelVector.erase (outChannelVector.begin(), outChannelVector.end());
+ outChannelVector.push_back (kAudioChannelLayoutTag_Stereo);
+ outChannelVector.push_back (kAudioChannelLayoutTag_StereoHeadphones);
+ outChannelVector.push_back (kAudioChannelLayoutTag_Quadraphonic);
+ outChannelVector.push_back (kAudioChannelLayoutTag_AudioUnit_5_0);
+ return true;
+ }
+
+ if (result) return false;
+
+ bool canDo = false;
+ // OK lets get our channel layouts and see if the one we want is present
+ AudioChannelLayoutTag* info = (AudioChannelLayoutTag*)malloc (dataSize);
+ result = AudioUnitGetProperty (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ info, &dataSize);
+ if (result) goto home;
+
+ outChannelVector.erase (outChannelVector.begin(), outChannelVector.end());
+ for (unsigned int i = 0; i < (dataSize / sizeof (AudioChannelLayoutTag)); ++i)
+ outChannelVector.push_back (info[i]);
+
+home:
+ free (info);
+ return canDo;
+}
+
+bool CAAudioUnit::HasChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl) const
+{
+ OSStatus result = AudioUnitGetPropertyInfo (AU(),
+ kAudioUnitProperty_SupportedChannelLayoutTags,
+ inScope, inEl,
+ NULL, NULL);
+ return !result;
+}
+
+OSStatus CAAudioUnit::GetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &outLayout) const
+{
+ UInt32 size;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(), kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, &size, NULL);
+ if (result) return result;
+
+ AudioChannelLayout *layout = (AudioChannelLayout*)malloc (size);
+
+ require_noerr (result = AudioUnitGetProperty (AU(), kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, layout, &size), home);
+
+ outLayout = CAAudioChannelLayout (layout);
+
+home:
+ free (layout);
+ return result;
+}
+
+OSStatus CAAudioUnit::SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &inLayout)
+{
+ OSStatus result = AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl,
+ inLayout, inLayout.Size());
+ return result;
+}
+
+OSStatus CAAudioUnit::SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioChannelLayout &inLayout,
+ UInt32 inSize)
+{
+ OSStatus result = AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl,
+ &inLayout, inSize);
+ return result;
+}
+
+OSStatus CAAudioUnit::ClearChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl)
+{
+ return AudioUnitSetProperty (AU(),
+ kAudioUnitProperty_AudioChannelLayout,
+ inScope, inEl, NULL, 0);
+}
+
+OSStatus CAAudioUnit::GetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioStreamBasicDescription &outFormat) const
+{
+ UInt32 dataSize = sizeof (AudioStreamBasicDescription);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_StreamFormat,
+ inScope, inEl,
+ &outFormat, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioStreamBasicDescription &inFormat)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_StreamFormat,
+ inScope, inEl,
+ const_cast<AudioStreamBasicDescription*>(&inFormat),
+ sizeof (AudioStreamBasicDescription));
+}
+
+OSStatus CAAudioUnit::GetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 &outRate) const
+{
+ UInt32 dataSize = sizeof (Float64);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_SampleRate,
+ inScope, inEl,
+ &outRate, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 inRate)
+{
+ AudioStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (result) return result;
+ desc.mSampleRate = inRate;
+ return SetFormat (inScope, inEl, desc);
+}
+
+OSStatus CAAudioUnit::SetSampleRate (Float64 inSampleRate)
+{
+ OSStatus result;
+
+ UInt32 elCount;
+ require_noerr (result = GetElementCount(kAudioUnitScope_Input, elCount), home);
+ if (elCount) {
+ for (unsigned int i = 0; i < elCount; ++i) {
+ require_noerr (result = SetSampleRate (kAudioUnitScope_Input, i, inSampleRate), home);
+ }
+ }
+
+ require_noerr (result = GetElementCount(kAudioUnitScope_Output, elCount), home);
+ if (elCount) {
+ for (unsigned int i = 0; i < elCount; ++i) {
+ require_noerr (result = SetSampleRate (kAudioUnitScope_Output, i, inSampleRate), home);
+ }
+ }
+
+home:
+ return result;
+}
+
+OSStatus CAAudioUnit::NumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const
+{
+ AudioStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (!result)
+ outChans = desc.mChannelsPerFrame;
+ return result;
+}
+
+OSStatus CAAudioUnit::SetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 inChans)
+{
+ // set this as the output of the AU
+ CAStreamBasicDescription desc;
+ OSStatus result = GetFormat (inScope, inEl, desc);
+ if (result) return result;
+ desc.SetCanonical (inChans, desc.IsInterleaved());
+ result = SetFormat (inScope, inEl, desc);
+ return result;
+}
+
+OSStatus CAAudioUnit::IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const
+{
+ Boolean isWritable;
+ UInt32 outDataSize;
+ OSStatus result = GetPropertyInfo (kAudioUnitProperty_ElementCount, inScope, 0, &outDataSize, &isWritable);
+ if (result)
+ return result;
+ outWritable = isWritable ? true : false;
+ return noErr;
+}
+
+OSStatus CAAudioUnit::GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const
+{
+ UInt32 propSize = sizeof(outCount);
+ return GetProperty (kAudioUnitProperty_ElementCount, inScope, 0, &outCount, &propSize);
+}
+
+OSStatus CAAudioUnit::SetElementCount (AudioUnitScope inScope, UInt32 inCount)
+{
+ return SetProperty (kAudioUnitProperty_ElementCount, inScope, 0, &inCount, sizeof(inCount));
+}
+
+bool CAAudioUnit::HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const
+{
+ // ok - now we need to check the AU's capability here.
+ // this is the default assumption of an audio effect unit
+ Boolean* isWritable = 0;
+ UInt32 dataSize = 0;
+ OSStatus result = GetPropertyInfo (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ &dataSize, isWritable); //don't care if this is writable
+
+ // AU has to explicitly tell us about this.
+ if (result) return false;
+
+ StackAUChannelInfo info (dataSize);
+
+ result = GetProperty (kAudioUnitProperty_SupportedNumChannels,
+ kAudioUnitScope_Global, 0,
+ info.mChanInfo, &dataSize);
+ if (result) return false;
+
+ return ValidateDynamicScope (inScope, outTotalNumChannels, info.mChanInfo, (dataSize / sizeof(AUChannelInfo)));
+}
+
+// as we've already checked that the element count is writable
+// the following conditions will match this..
+/*
+-1, -2 -> signifies no restrictions
+-2, -1 -> signifies no restrictions -> in this case outTotalNumChannels == -1 (any num channels)
+
+-N (where N is less than -2), signifies the total channel count on the scope side (in or out)
+*/
+bool CAAudioUnit::ValidateDynamicScope (AudioUnitScope inScope,
+ SInt32 &outTotalNumChannels,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const
+{
+ bool writable = false;
+ OSStatus result = IsElementCountWritable (inScope, writable);
+ if (result || (writable == false))
+ return false;
+
+ //now chan layout can contain -1 for either scope (ie. doesn't care)
+ for (unsigned int i = 0; i < numInfo; ++i)
+ {
+ // lets test the special wild card case first...
+ // this says the AU can do any num channels on input or output - for eg. Matrix Mixer
+ if (((info[i].inChannels == -1) && (info[i].outChannels == -2))
+ || ((info[i].inChannels == -2) && (info[i].outChannels == -1)))
+ {
+ outTotalNumChannels = -1;
+ return true;
+ }
+
+ // ok lets now test our special case....
+ if (inScope == kAudioUnitScope_Input) {
+ // isn't dynamic on this side at least
+ if (info[i].inChannels >= 0)
+ continue;
+
+ if (info[i].inChannels < -2) {
+ outTotalNumChannels = abs (info[i].inChannels);
+ return true;
+ }
+ }
+
+ else if (inScope == kAudioUnitScope_Output) {
+ // isn't dynamic on this side at least
+ if (info[i].outChannels >= 0)
+ continue;
+
+ if (info[i].outChannels < -2) {
+ outTotalNumChannels = abs (info[i].outChannels);
+ return true;
+ }
+ }
+
+ else {
+ break; // wrong scope was specified
+ }
+ }
+
+ return false;
+}
+
+OSStatus CAAudioUnit::ConfigureDynamicScope (AudioUnitScope inScope,
+ UInt32 inNumElements,
+ UInt32 *inChannelsPerElement,
+ Float64 inSampleRate)
+{
+ SInt32 numChannels = 0;
+ bool isDyamic = HasDynamicScope (inScope, numChannels);
+ if (isDyamic == false)
+ return kAudioUnitErr_InvalidProperty;
+
+ //lets to a sanity check...
+ // if numChannels == -1, then it can do "any"...
+ if (numChannels > 0) {
+ SInt32 count = 0;
+ for (unsigned int i = 0; i < inNumElements; ++i)
+ count += inChannelsPerElement[i];
+ if (count > numChannels)
+ return kAudioUnitErr_InvalidPropertyValue;
+ }
+
+ OSStatus result = SetElementCount (inScope, inNumElements);
+ if (result)
+ return result;
+
+ CAStreamBasicDescription desc;
+ desc.mSampleRate = inSampleRate;
+ for (unsigned int i = 0; i < inNumElements; ++i) {
+ desc.SetCanonical (inChannelsPerElement[i], false);
+ result = SetFormat (inScope, i, desc);
+ if (result)
+ return result;
+ }
+ return noErr;
+}
+
+#pragma mark __Properties
+
+bool CAAudioUnit::CanBypass () const
+{
+ Boolean outWritable;
+ OSStatus result = AudioUnitGetPropertyInfo (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ NULL, &outWritable);
+ return (!result && outWritable);
+}
+
+bool CAAudioUnit::GetBypass () const
+{
+ UInt32 dataSize = sizeof (UInt32);
+ UInt32 outBypass;
+ OSStatus result = AudioUnitGetProperty (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ &outBypass, &dataSize);
+ return (result ? false : outBypass);
+}
+
+OSStatus CAAudioUnit::SetBypass (bool inBypass) const
+{
+ UInt32 bypass = inBypass ? 1 : 0;
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_BypassEffect,
+ kAudioUnitScope_Global, 0,
+ &bypass, sizeof (UInt32));
+}
+
+Float64 CAAudioUnit::Latency () const
+{
+ Float64 secs;
+ UInt32 size = sizeof(secs);
+ if (GetProperty (kAudioUnitProperty_Latency, kAudioUnitScope_Global, 0, &secs, &size))
+ return 0;
+ return secs;
+}
+
+OSStatus CAAudioUnit::GetAUPreset (CFPropertyListRef &outData) const
+{
+ UInt32 dataSize = sizeof(outData);
+ return AudioUnitGetProperty (AU(), kAudioUnitProperty_ClassInfo,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+}
+
+OSStatus CAAudioUnit::SetAUPreset (CFPropertyListRef &inData)
+{
+ return AudioUnitSetProperty (AU(), kAudioUnitProperty_ClassInfo,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (CFPropertyListRef));
+}
+
+OSStatus CAAudioUnit::GetPresentPreset (AUPreset &outData) const
+{
+ UInt32 dataSize = sizeof(outData);
+ OSStatus result = AudioUnitGetProperty (AU(), kAudioUnitProperty_PresentPreset,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+ if (result == kAudioUnitErr_InvalidProperty) {
+ dataSize = sizeof(outData);
+ result = AudioUnitGetProperty (AU(), kAudioUnitProperty_CurrentPreset,
+ kAudioUnitScope_Global, 0,
+ &outData, &dataSize);
+ if (result == noErr) {
+ // we now retain the CFString in the preset so for the client of this API
+ // it is consistent (ie. the string should be released when done)
+ if (outData.presetName)
+ CFRetain (outData.presetName);
+ }
+ }
+ return result;
+}
+
+OSStatus CAAudioUnit::SetPresentPreset (AUPreset &inData)
+{
+ OSStatus result = AudioUnitSetProperty (AU(), kAudioUnitProperty_PresentPreset,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (AUPreset));
+ if (result == kAudioUnitErr_InvalidProperty) {
+ result = AudioUnitSetProperty (AU(), kAudioUnitProperty_CurrentPreset,
+ kAudioUnitScope_Global, 0,
+ &inData, sizeof (AUPreset));
+ }
+ return result;
+}
+
+bool CAAudioUnit::HasCustomView () const
+{
+ UInt32 dataSize = 0;
+ OSStatus result = GetPropertyInfo(kAudioUnitProperty_GetUIComponentList,
+ kAudioUnitScope_Global, 0,
+ &dataSize, NULL);
+ if (result || !dataSize) {
+ dataSize = 0;
+ result = GetPropertyInfo(kAudioUnitProperty_CocoaUI,
+ kAudioUnitScope_Global, 0,
+ &dataSize, NULL);
+ if (result || !dataSize)
+ return false;
+ }
+ return true;
+}
+
+OSStatus CAAudioUnit::GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const
+{
+ return mDataPtr ? mDataPtr->GetParameter (inID, scope, element, outValue) : paramErr;
+}
+
+OSStatus CAAudioUnit::SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames)
+{
+ return mDataPtr ? mDataPtr->SetParameter (inID, scope, element, value, bufferOffsetFrames) : paramErr;
+}
+
+OSStatus CAAudioUnit::MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame)
+{
+ return mDataPtr ? mDataPtr->MIDIEvent (inStatus, inData1, inData2, inOffsetSampleFrame) : paramErr;
+}
+
+OSStatus CAAudioUnit::StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+{
+ return mDataPtr ? mDataPtr->StartNote (inInstrument, inGroupID, outNoteInstanceID, inOffsetSampleFrame, inParams)
+ : paramErr;
+}
+
+OSStatus CAAudioUnit::StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame)
+{
+ return mDataPtr ? mDataPtr->StopNote (inGroupID, inNoteInstanceID, inOffsetSampleFrame) : paramErr;
+}
+
+#pragma mark __Render
+
+OSStatus CAAudioUnit::Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData)
+{
+ return mDataPtr ? mDataPtr->Render (ioActionFlags, inTimeStamp, inOutputBusNumber, inNumberFrames, ioData) : paramErr;
+}
+
+static AURenderCallbackStruct sRenderCallback;
+static OSStatus PrerollRenderProc ( void * /*inRefCon*/,
+ AudioUnitRenderActionFlags * /*inActionFlags*/,
+ const AudioTimeStamp * /*inTimeStamp*/,
+ UInt32 /*inBusNumber*/,
+ UInt32 /*inNumFrames*/,
+ AudioBufferList *ioData)
+{
+ AudioBuffer *buf = ioData->mBuffers;
+ for (UInt32 i = ioData->mNumberBuffers; i--; ++buf)
+ memset((Byte *)buf->mData, 0, buf->mDataByteSize);
+
+ return noErr;
+}
+
+OSStatus CAAudioUnit::Preroll (UInt32 inFrameSize)
+{
+ CAStreamBasicDescription desc;
+ OSStatus result = GetFormat (kAudioUnitScope_Input, 0, desc);
+ bool hasInput = false;
+ //we have input
+ if (result == noErr)
+ {
+ sRenderCallback.inputProc = PrerollRenderProc;
+ sRenderCallback.inputProcRefCon = 0;
+
+ result = SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+ 0, &sRenderCallback, sizeof(sRenderCallback));
+ if (result) return result;
+ hasInput = true;
+ }
+
+ AudioUnitRenderActionFlags flags = 0;
+ AudioTimeStamp time;
+ memset (&time, 0, sizeof(time));
+ time.mFlags = kAudioTimeStampSampleTimeValid;
+
+ CAStreamBasicDescription outputFormat;
+ require_noerr (result = GetFormat (kAudioUnitScope_Output, 0, outputFormat), home);
+ {
+ AUOutputBL list (outputFormat, inFrameSize);
+ list.Prepare ();
+
+ require_noerr (result = Render (&flags, &time, 0, inFrameSize, list.ABL()), home);
+ require_noerr (result = GlobalReset(), home);
+ }
+
+home:
+ if (hasInput) {
+ // remove our installed callback
+ sRenderCallback.inputProc = 0;
+ sRenderCallback.inputProcRefCon = 0;
+
+ SetProperty (kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input,
+ 0, &sRenderCallback, sizeof(sRenderCallback));
+ }
+ return result;
+}
+
+#pragma mark __CAAUChanHelper
+
+CAAUChanHelper::CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope)
+ :mChans(NULL), mNumEls(0), mDidAllocate(false)
+{
+ UInt32 elCount;
+ if (inAU.GetElementCount (inScope, elCount)) return;
+ if (elCount > 8) {
+ mChans = new UInt32[elCount];
+ mDidAllocate = true;
+ memset (mChans, 0, sizeof(int) * elCount);
+ } else {
+ mChans = mStaticChans;
+ memset (mChans, 0, sizeof(int) * 8);
+ }
+ for (unsigned int i = 0; i < elCount; ++i) {
+ UInt32 numChans;
+ if (inAU.NumberChannels (inScope, i, numChans)) return;
+ mChans[i] = numChans;
+ }
+ mNumEls = elCount;
+}
+
+CAAUChanHelper::~CAAUChanHelper()
+{
+ if (mDidAllocate) delete [] mChans;
+}
+
+CAAUChanHelper& CAAUChanHelper::operator= (const CAAUChanHelper &c)
+{
+ if (mDidAllocate) delete [] mChans;
+ if (c.mDidAllocate) {
+ mChans = new UInt32[c.mNumEls];
+ mDidAllocate = true;
+ } else {
+ mDidAllocate = false;
+ mChans = mStaticChans;
+ }
+ memcpy (mChans, c.mChans, c.mNumEls * sizeof(int));
+
+ return *this;
+}
+
+#pragma mark __Print Utilities
+
+void CAAudioUnit::Print (FILE* file) const
+{
+ fprintf (file, "AudioUnit:%p\n", AU());
+ if (IsValid()) {
+ fprintf (file, "\tnode=%ld\t", (long)GetAUNode()); Comp().Print (file);
+ }
+}
diff --git a/libs/appleutility/CAAudioUnit.h b/libs/appleutility/CAAudioUnit.h
new file mode 100644
index 0000000000..6bc31bf30b
--- /dev/null
+++ b/libs/appleutility/CAAudioUnit.h
@@ -0,0 +1,383 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAAudioUnit.h
+
+=============================================================================*/
+
+#ifndef __CAAudioUnit_h__
+#define __CAAudioUnit_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+ #include <CoreAudio/CoreAudio.h>
+ #include <AudioUnit/AudioUnit.h>
+ #include <AudioToolbox/AUGraph.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <CoreServices.h>
+ #include <CoreAudioTypes.h>
+ #include <AudioUnit.h>
+ #include <AUGraph.h>
+#endif
+
+#include <vector>
+#include "CAStreamBasicDescription.h"
+#include "CAComponent.h"
+#include "CAAudioChannelLayout.h"
+
+// defined below
+class CAAUChanHelper;
+
+// These constructors will NOT throw exceptions - so "check" after creation if AU IsValid()
+// The destructor will NOT automatically close the AU down
+// This state should be managed by the Caller
+// once closed, the unit represented by this object is no longer valid
+// it is up to the user of this object to ensure its validity is in sync
+// if it is removed from a graph
+
+// methods that can significantly change the state of the AU (like its format) are
+// NOT const whereas those that don't change the externally related state of the AU are not const
+
+class CAAudioUnit {
+public:
+ typedef std::vector<AudioChannelLayoutTag> ChannelTagVector;
+ typedef ChannelTagVector::iterator ChannelTagVectorIter;
+
+public:
+ CAAudioUnit ()
+ : mDataPtr(0) {}
+
+ CAAudioUnit (const AudioUnit& inUnit);
+
+ CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit);
+
+ CAAudioUnit (const CAAudioUnit& y)
+ : mDataPtr(0) { *this = y; }
+
+ static OSStatus Open (const CAComponent& inComp, CAAudioUnit &outUnit);
+
+ ~CAAudioUnit ();
+
+
+ CAAudioUnit& operator= (const CAAudioUnit& y);
+
+ bool operator== (const CAAudioUnit& y) const;
+
+ bool operator== (const AudioUnit& y) const;
+
+#pragma mark __State Management
+ bool IsValid () const;
+
+ AudioUnit AU() const;
+ operator AudioUnit () const { return AU(); }
+
+ const CAComponent& Comp() const { return mComp; }
+
+ bool FromAUGraph () const { return GetAUNode() != 0 || GetAUNode() != -1; }
+
+ AUNode GetAUNode () const;
+ operator AUNode () const { return GetAUNode(); }
+
+#pragma mark __API Wrapper
+ OSStatus Initialize() const { return AudioUnitInitialize(AU()); }
+ OSStatus Uninitialize() const { return AudioUnitUninitialize(AU()); }
+ OSStatus GetPropertyInfo(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ UInt32 *outDataSize, Boolean *outWritable) const
+ {
+ return AudioUnitGetPropertyInfo(AU(), propID, scope, element, outDataSize, outWritable);
+ }
+ OSStatus GetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ void *outData, UInt32 *ioDataSize) const
+ {
+ return AudioUnitGetProperty(AU(), propID, scope, element, outData, ioDataSize);
+ }
+ OSStatus SetProperty(AudioUnitPropertyID propID, AudioUnitScope scope, AudioUnitElement element,
+ const void *inData, UInt32 inDataSize)
+ {
+ return AudioUnitSetProperty(AU(), propID, scope, element, inData, inDataSize);
+ }
+ OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 value, UInt32 bufferOffsetFrames=0);
+
+ OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope scope, AudioUnitElement element,
+ Float32 &outValue) const;
+
+ OSStatus Render (AudioUnitRenderActionFlags * ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inOutputBusNumber,
+ UInt32 inNumberFrames,
+ AudioBufferList * ioData);
+
+ OSStatus Reset (AudioUnitScope scope, AudioUnitElement element)
+ {
+ return AudioUnitReset (AU(), scope, element);
+ }
+ OSStatus GlobalReset ()
+ {
+ return AudioUnitReset (AU(), kAudioUnitScope_Global, 0);
+ }
+
+ OSStatus Preroll (UInt32 inFrameSize);
+
+ OSStatus AddRenderNotify (AURenderCallback inProc, void *inProcRefCon)
+ {
+ return AudioUnitAddRenderNotify (AU(), inProc, inProcRefCon);
+ }
+
+ OSStatus RemoveRenderNotify (AURenderCallback inProc, void *inProcRefCon)
+ {
+ return AudioUnitRemoveRenderNotify (AU(), inProc, inProcRefCon);
+ }
+
+
+// Fast dispatch support for MIDI Effects or Music Devices
+ OSStatus MIDIEvent (UInt32 inStatus,
+ UInt32 inData1,
+ UInt32 inData2,
+ UInt32 inOffsetSampleFrame);
+
+ // uses the default VoiceForGroup value - this is the normal case
+ OSStatus StartNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams)
+ {
+ return StartNote (kMusicNoteEvent_UseGroupInstrument,
+ inGroupID, outNoteInstanceID,
+ inOffsetSampleFrame, inParams);
+ }
+
+ OSStatus StartNote (MusicDeviceInstrumentID inInstrument,
+ MusicDeviceGroupID inGroupID,
+ NoteInstanceID * outNoteInstanceID,
+ UInt32 inOffsetSampleFrame,
+ const MusicDeviceNoteParams * inParams);
+
+ OSStatus StopNote (MusicDeviceGroupID inGroupID,
+ NoteInstanceID inNoteInstanceID,
+ UInt32 inOffsetSampleFrame);
+
+#pragma mark __Format Utilities
+ // typically you ask this about an AU
+ // These Questions are asking about Input and Output...
+
+ // These ones just say whether an AU can do a single combination of channels
+ // and is fine if the AU has a single output (and if an input, a single input)
+ bool CanDo (int inChannelsInOut) const
+ {
+ return CanDo (inChannelsInOut, inChannelsInOut);
+ }
+
+ bool CanDo ( int inChannelsIn,
+ int inChannelsOut) const;
+
+ // This version does a more thorough test for ANY AU with ANY ins/outs
+ // you pass in the channel helper (for the current element count on that scope)
+
+ bool CanDo ( const CAAUChanHelper &input,
+ const CAAUChanHelper &output) const;
+
+ bool SupportsNumChannels () const;
+
+ bool HasChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl) const;
+
+ bool GetChannelLayouts (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ ChannelTagVector &outChannelVector) const;
+
+ OSStatus GetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &outLayout) const;
+
+ OSStatus SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ CAAudioChannelLayout &inLayout);
+
+ OSStatus SetChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioChannelLayout &inLayout,
+ UInt32 inSize);
+
+ OSStatus ClearChannelLayout (AudioUnitScope inScope,
+ AudioUnitElement inEl);
+
+ OSStatus GetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ AudioStreamBasicDescription &outFormat) const;
+ // if an AudioChannelLayout is either required or set, this call can fail
+ // and the SetChannelLayout call should be used to set the format
+ OSStatus SetFormat (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ const AudioStreamBasicDescription &inFormat);
+
+ OSStatus GetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 &outRate) const;
+ OSStatus SetSampleRate (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ Float64 inRate);
+
+ // this sets the sample rate on all in/out buses of the AU
+ OSStatus SetSampleRate (Float64 inSampleRate);
+
+ OSStatus NumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const;
+
+ OSStatus GetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 &outChans) const
+ {
+ return NumberChannels (inScope, inEl, outChans);
+ }
+
+ OSStatus SetNumberChannels (AudioUnitScope inScope,
+ AudioUnitElement inEl,
+ UInt32 inChans);
+
+ OSStatus IsElementCountWritable (AudioUnitScope inScope, bool &outWritable) const;
+
+ OSStatus GetElementCount (AudioUnitScope inScope, UInt32 &outCount) const;
+
+ OSStatus SetElementCount (AudioUnitScope inScope, UInt32 inCount);
+
+ // value of -1 for outTotalNumChannels indicates no restriction on num channels
+ // for ex. the Matrix Mixer satisfies this (its in/out element count is writable, and can be set to
+ // any number of channels.
+ // outTotalNumChannels is only valid if method returns true...
+ bool HasDynamicInputs (SInt32 &outTotalNumChannels) const
+ {
+ return HasDynamicScope (kAudioUnitScope_Input, outTotalNumChannels);
+ }
+
+ bool HasDynamicOutputs (SInt32 &outTotalNumChannels) const
+ {
+ return HasDynamicScope (kAudioUnitScope_Output, outTotalNumChannels);
+ }
+
+ // here, if the in (or out) elements are dynamic, then you supply the number of elements
+ // you want on in (or out) scope, and the number of channels on each consecutive element
+ OSStatus ConfigureDynamicInput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
+ {
+ return ConfigureDynamicScope (kAudioUnitScope_Input, inNumElements, inChannelsPerElement, inSampleRate);
+ }
+
+ OSStatus ConfigureDynamicOutput (UInt32 inNumElements, UInt32 *inChannelsPerElement, Float64 inSampleRate)
+ {
+ return ConfigureDynamicScope (kAudioUnitScope_Output, inNumElements, inChannelsPerElement, inSampleRate);
+ }
+
+ bool CanBypass () const;
+
+ bool GetBypass () const;
+
+ OSStatus SetBypass (bool inBypass) const;
+
+ Float64 Latency () const;
+
+ // these calls just deal with the global preset state
+ // you could rescope them to deal with presets on the part scope
+ OSStatus GetAUPreset (CFPropertyListRef &outData) const;
+
+ OSStatus SetAUPreset (CFPropertyListRef &inData);
+
+ OSStatus GetPresentPreset (AUPreset &outData) const;
+
+ OSStatus SetPresentPreset (AUPreset &inData);
+
+ bool HasCustomView () const;
+
+#pragma mark __Print
+ void Print () const { Print (stdout); }
+ void Print (FILE* file) const;
+
+private:
+ CAComponent mComp;
+
+ class AUState;
+ AUState* mDataPtr;
+
+ // this can throw - so wrap this up in a static that returns a result code...
+ CAAudioUnit (const CAComponent& inComp);
+
+ bool HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const;
+ OSStatus ConfigureDynamicScope (AudioUnitScope inScope,
+ UInt32 inNumElements,
+ UInt32 *inChannelsPerElement,
+ Float64 inSampleRate);
+ bool ValidateChannelPair (int inChannelsIn,
+ int inChannelsOut,
+ const AUChannelInfo * info,
+ UInt32 numChanInfo) const;
+
+ bool ValidateDynamicScope (AudioUnitScope inScope,
+ SInt32 &outTotalNumChannels,
+ const AUChannelInfo * info,
+ UInt32 numInfo) const;
+ bool CheckOneSide (const CAAUChanHelper &inHelper,
+ bool checkOutput,
+ const AUChannelInfo *info,
+ UInt32 numInfo) const;
+
+};
+
+class CAAUChanHelper {
+public:
+ CAAUChanHelper()
+ : mChans(mStaticChans), mNumEls(0), mDidAllocate(false)
+ {
+ memset (mChans, 0, sizeof(UInt32) * 8);
+ }
+ CAAUChanHelper(const CAAudioUnit &inAU, AudioUnitScope inScope);
+ CAAUChanHelper (const CAAUChanHelper &c) :mChans(mStaticChans), mNumEls(0), mDidAllocate(false) { *this = c; }
+
+ ~CAAUChanHelper();
+
+ CAAUChanHelper& operator= (const CAAUChanHelper &c);
+
+ UInt32 * mChans;
+ UInt32 mNumEls;
+
+private:
+ UInt32 mStaticChans[8];
+ bool mDidAllocate;
+};
+
+#endif
diff --git a/libs/appleutility/CACFDictionary.cpp b/libs/appleutility/CACFDictionary.cpp
new file mode 100644
index 0000000000..c209b5fc36
--- /dev/null
+++ b/libs/appleutility/CACFDictionary.cpp
@@ -0,0 +1,478 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFDictionary.cpp
+ CAAudioEngine
+
+=============================================================================*/
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// Self Include
+#include "CACFDictionary.h"
+
+// PublicUtility Includes
+#include "CACFString.h"
+#include "CACFNumber.h"
+
+//=============================================================================
+// CACFDictionary
+//=============================================================================
+
+bool CACFDictionary::HasKey(const CFStringRef inKey) const
+{
+ return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
+}
+
+UInt32 CACFDictionary::Size () const
+{
+ return CFDictionaryGetCount(mCFDictionary);
+}
+
+void CACFDictionary::GetKeys (const void **keys) const
+{
+ CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
+}
+
+bool CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
+ {
+ outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
+ theAnswer = true;
+ }
+ else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ SInt32 theNumericValue = 0;
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
+ outValue = theNumericValue != 0;
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
+ {
+ CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
+ {
+ outValue = static_cast<CFStringRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
+ {
+ outValue = static_cast<CFArrayRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
+ {
+ outValue = static_cast<CFDictionaryRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
+{
+ bool theAnswer = false;
+
+ CFTypeRef theValue = NULL;
+ if(GetCFType(inKey, theValue))
+ {
+ if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
+ {
+ outValue = static_cast<CFDataRef>(theValue);
+ theAnswer = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
+{
+ bool theAnswer = false;
+
+ if(mCFDictionary != NULL)
+ {
+ outValue = CFDictionaryGetValue(mCFDictionary, inKey);
+ theAnswer = (outValue != NULL);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
+{
+ bool theAnswer = false;
+
+ if(mCFDictionary != NULL)
+ {
+ CACFString theKey(inKey);
+ if(theKey.IsValid())
+ {
+ theAnswer = GetCFType(theKey.GetCFString(), outValue);
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFNumber theValue(inValue);
+ theAnswer = AddCFType(inKey, theValue.GetCFNumber());
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ theAnswer = AddCFType(inKey, inValue);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ theAnswer = AddCFType(inKey, inValue);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ theAnswer = AddCFType(inKey, inValue);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ theAnswer = AddCFType(inKey, inValue);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddData(const CFStringRef inKey, const CFDataRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ theAnswer = AddCFType(inKey, inValue);
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CFDictionarySetValue(mCFDictionary, inKey, inValue);
+ theAnswer = true;
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFString theKey(inKey);
+ if(theKey.IsValid())
+ {
+ theAnswer = AddCFType(theKey.GetCFString(), inValue);
+ }
+ }
+
+ return theAnswer;
+}
+
+bool CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
+{
+ bool theAnswer = false;
+
+ if(mMutable && (mCFDictionary != NULL))
+ {
+ CACFString theValue(inValue);
+ if(theValue.IsValid())
+ {
+ theAnswer = AddCFType(inKey, theValue.GetCFString());
+ }
+ }
+
+ return theAnswer;
+}
diff --git a/libs/appleutility/CACFDictionary.h b/libs/appleutility/CACFDictionary.h
new file mode 100644
index 0000000000..362b1c8821
--- /dev/null
+++ b/libs/appleutility/CACFDictionary.h
@@ -0,0 +1,141 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFDictionary.h
+
+=============================================================================*/
+#if !defined(__CACFDictionary_h__)
+#define __CACFDictionary_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+// System Includes
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include <CoreFoundation.h>
+#endif
+
+//=============================================================================
+// CACFDictionary
+//=============================================================================
+
+class CACFDictionary
+{
+
+// Construction/Destruction
+public:
+ CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
+ CACFDictionary(const CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(true) {}
+ CACFDictionary(const CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
+ CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
+ CACFDictionary& operator=(const CACFDictionary& inDictionary) { mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } return *this; }
+ ~CACFDictionary() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
+
+// Attributes
+public:
+ bool IsValid() const { return mCFDictionary != NULL; }
+ bool IsMutable() const { return mMutable;}
+ bool CanModify() const { return mMutable && (mCFDictionary != NULL); }
+
+ bool WillRelease() const { return mRelease; }
+ void ShouldRelease(bool inRelease) { mRelease = inRelease; }
+
+ CFDictionaryRef GetDict() const { return mCFDictionary; }
+ CFDictionaryRef GetCFDictionary() const { return mCFDictionary; }
+ CFDictionaryRef CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
+
+ CFMutableDictionaryRef GetMutableDict() { return mCFDictionary; }
+ CFMutableDictionaryRef GetCFMutableDictionary() const { return mCFDictionary; }
+ CFMutableDictionaryRef CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
+ void SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }
+
+ CFPropertyListRef AsPropertyList() const { return mCFDictionary; }
+ OSStatus GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }
+
+// Item Operations
+public:
+ bool HasKey(const CFStringRef inKey) const;
+ UInt32 Size() const;
+ void GetKeys(const void** keys) const;
+
+ bool GetBool(const CFStringRef inKey, bool& outValue) const;
+ bool GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
+ bool GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
+ bool GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
+ bool GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
+ bool GetFloat32(const CFStringRef inKey, Float32& outValue) const;
+ bool GetFloat64(const CFStringRef inKey, Float64& outValue) const;
+ bool GetString(const CFStringRef inKey, CFStringRef& outValue) const;
+ bool GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;
+ bool GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;
+ bool GetData(const CFStringRef inKey, CFDataRef& outValue) const;
+ bool GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
+
+ bool GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;
+
+ bool AddSInt32(const CFStringRef inKey, SInt32 inValue);
+ bool AddUInt32(const CFStringRef inKey, UInt32 inValue);
+ bool AddSInt64(const CFStringRef inKey, SInt64 inValue);
+ bool AddUInt64(const CFStringRef inKey, UInt64 inValue);
+ bool AddFloat32(const CFStringRef inKey, Float32 inValue);
+ bool AddFloat64(const CFStringRef inKey, Float64 inValue);
+ bool AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
+ bool AddString(const CFStringRef inKey, const CFStringRef inValue);
+ bool AddArray(const CFStringRef inKey, const CFArrayRef inValue);
+ bool AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
+ bool AddData(const CFStringRef inKey, const CFDataRef inValue);
+ bool AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
+
+ bool AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
+ bool AddCString(const CFStringRef inKey, const char* inValue);
+
+ void Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
+
+ void Show() { CFShow(mCFDictionary); }
+
+// Implementation
+private:
+ CFMutableDictionaryRef mCFDictionary;
+ bool mRelease;
+ bool mMutable;
+};
+
+#endif //__CACFDictionary_h__
diff --git a/libs/appleutility/CACFNumber.cpp b/libs/appleutility/CACFNumber.cpp
new file mode 100644
index 0000000000..3b6160c8bb
--- /dev/null
+++ b/libs/appleutility/CACFNumber.cpp
@@ -0,0 +1,65 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFNumber.cp
+
+=============================================================================*/
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CACFNumber.h"
+
+//=============================================================================
+// CACFNumber
+//=============================================================================
+
+Float32 CACFNumber::GetFixed32() const
+{
+ SInt32 theFixedValue = GetSInt32();
+
+ // this is a 16.16 value so convert it to a float
+ Float32 theSign = theFixedValue < 0 ? -1.0 : 1.0;
+ theFixedValue *= (SInt32)theSign;
+ Float32 theWholePart = (theFixedValue & 0x7FFF0000) >> 16;
+ Float32 theFractPart = theFixedValue & 0x0000FFFF;
+ theFractPart /= 65536.0;
+
+ return theSign * (theWholePart + theFractPart);
+}
diff --git a/libs/appleutility/CACFNumber.h b/libs/appleutility/CACFNumber.h
new file mode 100644
index 0000000000..3991637bac
--- /dev/null
+++ b/libs/appleutility/CACFNumber.h
@@ -0,0 +1,102 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFNumber.h
+
+=============================================================================*/
+#if !defined(__CACFNumber_h__)
+#define __CACFNumber_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CFNumber.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CFNumber.h>
+#endif
+
+//=============================================================================
+// CACFNumber
+//=============================================================================
+
+class CACFNumber
+{
+// Construction/Destruction
+public:
+ CACFNumber(CFNumberRef inCFNumber, bool inWillRelease = true) : mCFNumber(inCFNumber), mWillRelease(inWillRelease) {}
+ CACFNumber(SInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(UInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(SInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(UInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(Float32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat32Type, &inValue)), mWillRelease(true) {}
+ CACFNumber(Float64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat64Type, &inValue)), mWillRelease(true) {}
+ ~CACFNumber() { Release(); }
+ CACFNumber(const CACFNumber& inNumber) : mCFNumber(inNumber.mCFNumber), mWillRelease(inNumber.mWillRelease) { Retain(); }
+ CACFNumber& operator=(const CACFNumber& inNumber) { Release(); mCFNumber = inNumber.mCFNumber; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
+ CACFNumber& operator=(CFNumberRef inCFNumber) { Release(); mCFNumber = inCFNumber; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFNumber != NULL)) { CFRetain(mCFNumber); } }
+ void Release() { if(mWillRelease && (mCFNumber != NULL)) { CFRelease(mCFNumber); } }
+
+ CFNumberRef mCFNumber;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() { return mCFNumber != NULL; }
+
+// Value Access
+public:
+ CFNumberRef GetCFNumber() const { return mCFNumber; }
+ CFNumberRef CopyCFNumber() const { if(mCFNumber != NULL) { CFRetain(mCFNumber); } return mCFNumber; }
+
+ SInt8 GetSInt8() const { SInt8 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt8Type, &theAnswer); } return theAnswer; }
+ SInt32 GetSInt32() const { SInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
+ Float32 GetFloat32() const { Float32 theAnswer = 0.0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberFloat32Type, &theAnswer); } return theAnswer; }
+ Float32 GetFixed32() const;
+ SInt64 GetSInt64() const { SInt64 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt64Type, &theAnswer); } return theAnswer; }
+};
+
+#endif
diff --git a/libs/appleutility/CACFString.cpp b/libs/appleutility/CACFString.cpp
new file mode 100644
index 0000000000..ec3b18a8b6
--- /dev/null
+++ b/libs/appleutility/CACFString.cpp
@@ -0,0 +1,106 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFString.cp
+
+=============================================================================*/
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#include "CACFString.h"
+
+//=============================================================================
+// CACFString
+//=============================================================================
+
+UInt32 CACFString::GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding)
+{
+ UInt32 theAnswer = 0;
+
+ if(inCFString != NULL)
+ {
+ CFRange theRange = { 0, CFStringGetLength(inCFString) };
+ CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, NULL, 0x7FFFFFFF, (CFIndex*)&theAnswer);
+ }
+
+ return theAnswer;
+}
+
+void CACFString::GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding)
+{
+ if(ioStringSize > 0)
+ {
+ if(inCFString != NULL)
+ {
+ CFIndex theLength = 0;
+ CFRange theRange = { 0, CFStringGetLength(inCFString) };
+ CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, (UInt8*)outString, ioStringSize - 1, &theLength);
+ outString[theLength] = 0;
+ ioStringSize = theLength + 1;
+ }
+ else
+ {
+ outString[0] = 0;
+ ioStringSize = 1;
+ }
+ }
+}
+
+void CACFString::GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize)
+{
+ if(ioStringSize > 0)
+ {
+ if(inCFString != NULL)
+ {
+ CFRange theStringRange = { 0, CFStringGetLength(inCFString) };
+ if(static_cast<UInt32>(theStringRange.length) > ioStringSize)
+ {
+ theStringRange.length = ioStringSize;
+ }
+ CFStringGetCharacters(inCFString, theStringRange, outString);
+ ioStringSize = theStringRange.length;
+ }
+ else
+ {
+ outString[0] = 0;
+ ioStringSize = 0;
+ }
+ }
+}
diff --git a/libs/appleutility/CACFString.h b/libs/appleutility/CACFString.h
new file mode 100644
index 0000000000..51fa64ebff
--- /dev/null
+++ b/libs/appleutility/CACFString.h
@@ -0,0 +1,156 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CACFString.h
+
+=============================================================================*/
+#if !defined(__CACFString_h__)
+#define __CACFString_h__
+
+//=============================================================================
+// Includes
+//=============================================================================
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CFString.h>
+#else
+ #include <CoreAudioTypes.h>
+ #include <CFString.h>
+#endif
+
+//=============================================================================
+// CACFString
+//=============================================================================
+
+class CACFString
+{
+// Construction/Destruction
+public:
+ CACFString() : mCFString(NULL), mWillRelease(true) {}
+ CACFString(CFStringRef inCFString, bool inWillRelease = true) : mCFString(inCFString), mWillRelease(inWillRelease) {}
+ CACFString(const char* inCString, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(inWillRelease) {}
+ CACFString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, inCStringEncoding)), mWillRelease(inWillRelease) {}
+ ~CACFString() { Release(); }
+ CACFString(const CACFString& inString) : mCFString(inString.mCFString), mWillRelease(inString.mWillRelease) { Retain(); }
+ CACFString& operator=(const CACFString& inString) { Release(); mCFString = inString.mCFString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
+ CACFString& operator=(CFStringRef inCFString) { Release(); mCFString = inCFString; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFString != NULL)) { CFRetain(mCFString); } }
+ void Release() { if(mWillRelease && (mCFString != NULL)) { CFRelease(mCFString); } }
+
+ CFStringRef mCFString;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() const { return mCFString != NULL; }
+ bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasPrefix(mCFString, inString); } return theAnswer; }
+ bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasSuffix(mCFString, inString); } return theAnswer; }
+
+// Value Access
+public:
+ CFStringRef GetCFString() const { return mCFString; }
+ CFStringRef CopyCFString() const { if(mCFString != NULL) { CFRetain(mCFString); } return mCFString; }
+ UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = CFStringGetLength(mCFString); } return theAnswer; }
+ UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = GetStringByteLength(mCFString, inEncoding); } return theAnswer; }
+ void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { GetCString(mCFString, outString, ioStringSize, inEncoding); }
+ void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { GetUnicodeString(mCFString, outString, ioStringSize); }
+
+ static UInt32 GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
+ static void GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
+ static void GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize);
+
+};
+
+inline bool operator<(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareLessThan; }
+inline bool operator==(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareEqualTo; }
+inline bool operator!=(const CACFString& x, const CACFString& y) { return !(x == y); }
+inline bool operator<=(const CACFString& x, const CACFString& y) { return (x < y) || (x == y); }
+inline bool operator>=(const CACFString& x, const CACFString& y) { return !(x < y); }
+inline bool operator>(const CACFString& x, const CACFString& y) { return !((x < y) || (x == y)); }
+
+//=============================================================================
+// CACFMutableString
+//=============================================================================
+
+class CACFMutableString
+{
+// Construction/Destruction
+public:
+ CACFMutableString() : mCFMutableString(NULL), mWillRelease(true) {}
+ CACFMutableString(CFMutableStringRef inCFMutableString, bool inWillRelease = true) : mCFMutableString(inCFMutableString), mWillRelease(inWillRelease) {}
+ CACFMutableString(CFStringRef inStringToCopy, bool /*inMakeCopy*/, bool inWillRelease = true) : mCFMutableString(CFStringCreateMutableCopy(NULL, 0, inStringToCopy)), mWillRelease(inWillRelease) {}
+ CACFMutableString(const char* inCString, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
+ CACFMutableString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString, inCStringEncoding); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
+ ~CACFMutableString() { Release(); }
+ CACFMutableString(const CACFMutableString& inString) : mCFMutableString(inString.mCFMutableString), mWillRelease(inString.mWillRelease) { Retain(); }
+ CACFMutableString operator=(const CACFMutableString& inString) { Release(); mCFMutableString = inString.mCFMutableString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
+ CACFMutableString operator=(CFMutableStringRef inCFMutableString) { Release(); mCFMutableString = inCFMutableString; mWillRelease = true; return *this; }
+
+private:
+ void Retain() { if(mWillRelease && (mCFMutableString != NULL)) { CFRetain(mCFMutableString); } }
+ void Release() { if(mWillRelease && (mCFMutableString != NULL)) { CFRelease(mCFMutableString); } }
+
+ CFMutableStringRef mCFMutableString;
+ bool mWillRelease;
+
+// Operations
+public:
+ void AllowRelease() { mWillRelease = true; }
+ void DontAllowRelease() { mWillRelease = false; }
+ bool IsValid() { return mCFMutableString != NULL; }
+ bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasPrefix(mCFMutableString, inString); } return theAnswer; }
+ bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasSuffix(mCFMutableString, inString); } return theAnswer; }
+ void Append(CFStringRef inString) { if(mCFMutableString != NULL) { CFStringAppend(mCFMutableString, inString); } }
+
+// Value Access
+public:
+ CFMutableStringRef GetCFMutableString() const { return mCFMutableString; }
+ CFMutableStringRef CopyCFMutableString() const { if(mCFMutableString != NULL) { CFRetain(mCFMutableString); } return mCFMutableString; }
+ UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CFStringGetLength(mCFMutableString); } return theAnswer; }
+ UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CACFString::GetStringByteLength(mCFMutableString, inEncoding); } return theAnswer; }
+ void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { CACFString::GetCString(mCFMutableString, outString, ioStringSize, inEncoding); }
+ void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { CACFString::GetUnicodeString(mCFMutableString, outString, ioStringSize); }
+
+};
+
+#endif
diff --git a/libs/appleutility/CAComponent.cpp b/libs/appleutility/CAComponent.cpp
new file mode 100644
index 0000000000..700d9e2b3e
--- /dev/null
+++ b/libs/appleutility/CAComponent.cpp
@@ -0,0 +1,257 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAComponent.cpp
+
+=============================================================================*/
+
+#include "CAComponent.h"
+#include "CAComponentDescription.h"
+#include "CACFDictionary.h"
+#include <stdlib.h>
+
+CAComponent::CAComponent (const ComponentDescription& inDesc, CAComponent* next)
+ : mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
+{
+ mComp = FindNextComponent ((next ? next->Comp() : NULL), const_cast<ComponentDescription*>(&inDesc));
+ if (mComp)
+ GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
+ else
+ memcpy (&mDesc, &inDesc, sizeof(ComponentDescription));
+}
+
+CAComponent::CAComponent (const Component& comp)
+ : mComp (comp),
+ mManuName(0),
+ mAUName(0),
+ mCompName(0),
+ mCompInfo (0)
+{
+ GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
+}
+
+CAComponent::CAComponent (const ComponentInstance& compInst)
+ : mComp (Component(compInst)),
+ mManuName(0),
+ mAUName(0),
+ mCompName(0),
+ mCompInfo (0)
+{
+ GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
+}
+
+CAComponent::CAComponent (OSType inType, OSType inSubtype, OSType inManu)
+ : mDesc (inType, inSubtype, inManu),
+ mManuName(0), mAUName(0), mCompName(0), mCompInfo (0)
+{
+ mComp = FindNextComponent (NULL, &mDesc);
+ GetComponentInfo (Comp(), &mDesc, NULL, NULL, NULL);
+}
+
+CAComponent::~CAComponent ()
+{
+ Clear();
+}
+
+OSStatus CAComponent::GetResourceVersion (UInt32 &outVersion) const
+{
+ bool versionFound = false;
+ short componentResFileID = kResFileNotOpened;
+ OSStatus result;
+ short thngResourceCount;
+
+ short curRes = CurResFile();
+ require_noerr (result = OpenAComponentResFile( mComp, &componentResFileID), home);
+ require_noerr (result = componentResFileID <= 0, home);
+
+ UseResFile(componentResFileID);
+
+ thngResourceCount = Count1Resources(kComponentResourceType);
+
+ require_noerr (result = ResError(), home);
+ // only go on if we successfully found at least 1 thng resource
+ require_noerr (thngResourceCount <= 0 ? -1 : 0, home);
+
+ // loop through all of the Component thng resources trying to
+ // find one that matches this Component description
+ for (short i = 0; i < thngResourceCount && (!versionFound); i++)
+ {
+ // try to get a handle to this code resource
+ Handle thngResourceHandle = Get1IndResource(kComponentResourceType, i+1);
+ if (thngResourceHandle != NULL && ((*thngResourceHandle) != NULL))
+ {
+ if (UInt32(GetHandleSize(thngResourceHandle)) >= sizeof(ExtComponentResource))
+ {
+ ExtComponentResource * componentThng = (ExtComponentResource*) (*thngResourceHandle);
+
+ // check to see if this is the thng resource for the particular Component that we are looking at
+ // (there often is more than one Component described in the resource)
+ if ((componentThng->cd.componentType == mDesc.Type())
+ && (componentThng->cd.componentSubType == mDesc.SubType())
+ && (componentThng->cd.componentManufacturer == mDesc.Manu()))
+ {
+ outVersion = componentThng->componentVersion;
+ versionFound = true;
+ }
+ }
+ ReleaseResource(thngResourceHandle);
+ }
+ }
+
+ if (!versionFound)
+ result = resNotFound;
+
+ UseResFile(curRes); // revert
+
+ if ( componentResFileID != kResFileNotOpened )
+ CloseComponentResFile(componentResFileID);
+
+home:
+ return result;
+}
+
+void CAComponent::Clear ()
+{
+ if (mManuName) { CFRelease (mManuName); mManuName = 0; }
+ if (mAUName) { CFRelease (mAUName); mAUName = 0; }
+ if (mCompName) { CFRelease (mCompName); mCompName = 0; }
+ if (mCompInfo) { CFRelease (mCompInfo); mCompInfo = 0; }
+}
+
+CAComponent& CAComponent::operator= (const CAComponent& y)
+{
+ Clear();
+
+ mComp = y.mComp;
+ mDesc = y.mDesc;
+
+ if (y.mManuName) { mManuName = y.mManuName; CFRetain (mManuName); }
+ if (y.mAUName) { mAUName = y.mAUName; CFRetain (mAUName); }
+ if (y.mCompName) { mCompName = y.mCompName; CFRetain (mCompName); }
+ if (y.mCompInfo) { mCompInfo = y.mCompInfo; CFRetain (mCompInfo); }
+
+ return *this;
+}
+
+void CAComponent::SetCompNames () const
+{
+ if (!mCompName) {
+ Handle h1 = NewHandle(4);
+ CAComponentDescription desc;
+ OSStatus err = GetComponentInfo (Comp(), &desc, h1, 0, 0);
+
+ if (err) { DisposeHandle(h1); return; }
+
+ HLock(h1);
+ char* ptr1 = *h1;
+ // Get the manufacturer's name... look for the ':' character convention
+ int len = *ptr1++;
+ char* displayStr = 0;
+
+ const_cast<CAComponent*>(this)->mCompName = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
+
+ for (int i = 0; i < len; ++i) {
+ if (ptr1[i] == ':') { // found the name
+ ptr1[i] = 0;
+ displayStr = ptr1;
+ break;
+ }
+ }
+
+ if (displayStr)
+ {
+ const_cast<CAComponent*>(this)->mManuName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
+
+ //move displayStr ptr past the manu, to the name
+ // we move the characters down a index, because the handle doesn't have any room
+ // at the end for the \0
+ int i = strlen(displayStr), j = 0;
+ while (displayStr[++i] == ' ' && i < len)
+ ;
+ while (i < len)
+ displayStr[j++] = displayStr[i++];
+ displayStr[j] = 0;
+
+ const_cast<CAComponent*>(this)->mAUName = CFStringCreateWithCString(NULL, displayStr, kCFStringEncodingMacRoman);
+ }
+
+ DisposeHandle (h1);
+ }
+}
+
+void CAComponent::SetCompInfo () const
+{
+ if (!mCompInfo) {
+ Handle h1 = NewHandle(4);
+ CAComponentDescription desc;
+ OSStatus err = GetComponentInfo (Comp(), &desc, 0, h1, 0);
+ if (err) return;
+ HLock (h1);
+ const_cast<CAComponent*>(this)->mCompInfo = CFStringCreateWithPascalString(NULL, (const unsigned char*)*h1, kCFStringEncodingMacRoman);
+
+ DisposeHandle (h1);
+ }
+}
+
+void _ShowCF (FILE* file, CFStringRef str)
+{
+ if (CFGetTypeID(str) != CFStringGetTypeID()) {
+ CFShow(str);
+ return;
+ }
+
+ UInt32 len = CFStringGetLength(str);
+ char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
+ if (CFStringGetCString (str, chars, len * 2, kCFStringEncodingUTF8))
+ fprintf (file, "%s", chars);
+ else
+ CFShow (str);
+
+ free (chars);
+}
+
+void CAComponent::Print(FILE* file) const
+{
+ fprintf (file, "CAComponent: 0x%X", int(Comp()));
+ if (mManuName) {
+ fprintf (file, ", Manu:"); _ShowCF (file, mManuName);
+ if (mAUName) fprintf (file, ", Name:"); _ShowCF (file, mAUName);
+ }
+ fprintf (file, ", ");
+ Desc ().Print(file);
+}
diff --git a/libs/appleutility/CAComponent.h b/libs/appleutility/CAComponent.h
new file mode 100644
index 0000000000..2ace42532d
--- /dev/null
+++ b/libs/appleutility/CAComponent.h
@@ -0,0 +1,120 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAComponent.h
+
+=============================================================================*/
+
+#ifndef __CAComponent_h__
+#define __CAComponent_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <CoreServices.h>
+#endif
+
+#include "CAComponentDescription.h"
+
+class CAComponent
+{
+public:
+ CAComponent ()
+ : mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) {}
+
+ // if next is specifed that is used to find the next component after that one
+ CAComponent (const ComponentDescription& inDesc, CAComponent* next = 0);
+
+ CAComponent (const CAComponent& y)
+ : mComp (0), mDesc(), mManuName(0), mAUName(0), mCompName(0), mCompInfo (0) { *this = y; }
+
+ CAComponent (const Component& comp);
+
+ CAComponent (const ComponentInstance& compInst);
+
+ CAComponent (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
+
+ ~CAComponent ();
+
+ CAComponent& operator= (const CAComponent& y);
+
+ // returns true if this object references a valid component
+ bool IsValid () const { return Comp() != 0; }
+
+ bool HasAUStrings() const { SetCompNames (); return mManuName != 0; }
+
+ // CFStringRef should be retained by caller if needed beyond lifetime of this object
+
+ // Can return NULL if component doesn't follow AU naming conventions
+ CFStringRef GetAUManu () const { SetCompNames (); return mManuName; }
+ CFStringRef GetAUName () const { SetCompNames (); return mAUName ? mAUName : mCompName; }
+
+ // Return value of NULL indicates a problem getting that information from the component
+ CFStringRef GetCompName () const { SetCompNames(); return mCompName; }
+ CFStringRef GetCompInfo () const { SetCompInfo(); return mCompInfo; }
+
+ const CAComponentDescription& Desc () const { return mDesc; }
+
+ OSStatus Open (ComponentInstance& outInst) const
+ {
+ return OpenAComponent (Comp(), &outInst);
+ }
+
+ OSStatus GetResourceVersion (UInt32 &outVersion) const;
+
+ const Component& Comp() const { return mComp; }
+
+ void Print(FILE* file = stdout) const;
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ Component mComp;
+ CAComponentDescription mDesc;
+
+ CFStringRef mManuName, mAUName, mCompName, mCompInfo;
+
+ void SetCompNames () const;
+ void SetCompInfo () const;
+ void Clear ();
+};
+
+#endif
diff --git a/libs/appleutility/CAComponentDescription.cpp b/libs/appleutility/CAComponentDescription.cpp
new file mode 100644
index 0000000000..261a2b881c
--- /dev/null
+++ b/libs/appleutility/CAComponentDescription.cpp
@@ -0,0 +1,123 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAComponentDescription.cpp
+
+=============================================================================*/
+
+#include "CAComponentDescription.h"
+#include <ctype.h>
+
+extern "C" void CAShowComponentDescription(const ComponentDescription *desc)
+{
+ CAComponentDescription::_CAShowComponentDescription (desc, stdout);
+}
+
+char *StringForOSType (OSType t, char *writeLocation)
+{
+ char *p = writeLocation;
+ unsigned char str[4], *q = str;
+ *(UInt32 *)str = EndianU32_NtoB(t);
+ for (int i = 0; i < 4; ++i) {
+ if (isprint(*q) && *q != '\\')
+ *p++ = *q++;
+ else {
+ sprintf(p, "\\x%02X", *q++);
+ p += 4;
+ }
+ }
+ *p = '\0';
+ return writeLocation;
+}
+
+
+void CAComponentDescription::_CAShowComponentDescription(const ComponentDescription *desc, FILE* file)
+{
+ if (desc)
+ {
+ char str[24];
+ fprintf (file, "ComponentDescription: %s - ", StringForOSType(desc->componentType, str));
+ fprintf (file, "%s - ", StringForOSType(desc->componentSubType, str));
+ fprintf (file, "%s", StringForOSType(desc->componentManufacturer, str));
+ fprintf (file, ", 0x%lX, 0x%lX\n", desc->componentFlags, desc->componentFlagsMask);
+ }
+}
+
+CAComponentDescription::CAComponentDescription (OSType inType, OSType inSubtype, OSType inManu)
+{
+ componentType = inType;
+ componentSubType = inSubtype;
+ componentManufacturer = inManu;
+ componentFlags = 0;
+ componentFlagsMask = 0;
+}
+
+bool CAComponentDescription::IsAU () const
+{
+ bool flag = IsEffect() || IsMusicDevice() || IsOffline();
+ if (flag) return true;
+
+ switch (componentType) {
+ case kAudioUnitType_Output:
+ case kAudioUnitType_FormatConverter:
+ case kAudioUnitType_Mixer:
+ return true;
+ }
+ return false;
+}
+
+inline bool _MatchTest (const OSType &inTypeA, const OSType &inTypeB)
+{
+ return ((inTypeA == inTypeB) || (!inTypeA && !inTypeB) || (inTypeA && !inTypeB) || (!inTypeA && inTypeB));
+}
+
+bool CAComponentDescription::Matches (const ComponentDescription &desc) const
+{
+ bool matches = false;
+
+ // see if the type matches
+ matches = _MatchTest (componentType, desc.componentType);
+
+ if (matches)
+ matches = _MatchTest (componentSubType, desc.componentSubType);
+
+ if (matches)
+ matches = _MatchTest (componentManufacturer, desc.componentManufacturer);
+
+ return matches;
+}
diff --git a/libs/appleutility/CAComponentDescription.h b/libs/appleutility/CAComponentDescription.h
new file mode 100644
index 0000000000..a681902b91
--- /dev/null
+++ b/libs/appleutility/CAComponentDescription.h
@@ -0,0 +1,148 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAComponentDescription.h
+
+=============================================================================*/
+
+#ifndef __CAComponentDescription_h__
+#define __CAComponentDescription_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+ #include <AudioUnit/AudioUnit.h>
+#else
+ #include <ConditionalMacros.h>
+ #include <CoreServices.h>
+ #include <AudioUnit.h>
+#endif
+
+#include "CACFDictionary.h"
+#include <stdio.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void CAShowComponentDescription(const ComponentDescription *desc);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+// ____________________________________________________________________________
+//
+// CAComponentDescription
+class CAComponentDescription : public ComponentDescription {
+public:
+ CAComponentDescription() { memset (this, 0, sizeof (ComponentDescription)); }
+
+ CAComponentDescription (OSType inType, OSType inSubtype = 0, OSType inManu = 0);
+
+ CAComponentDescription(const ComponentDescription& desc) { memcpy (this, &desc, sizeof (ComponentDescription)); }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // interrogation
+
+ bool IsAU () const;
+
+ bool IsAUFX() const { return componentType == kAudioUnitType_Effect; }
+ bool IsAUFM() const { return componentType == kAudioUnitType_MusicEffect; }
+
+ bool IsEffect () const { return IsAUFX() || IsAUFM() || IsPanner(); }
+
+ bool IsOffline () const { return componentType == 'auol'; }
+
+ bool IsFConv () const { return componentType == kAudioUnitType_FormatConverter; }
+
+ bool IsPanner () const { return componentType == kAudioUnitType_Panner; }
+
+ bool IsMusicDevice () const { return componentType == kAudioUnitType_MusicDevice; }
+
+#ifndef MAC_OS_X_VERSION_10_4
+ bool IsGenerator () const { return componentType =='augn'; }
+#else
+ bool IsGenerator () const { return componentType ==kAudioUnitType_Generator; }
+#endif
+
+ bool IsOutput () const { return componentType == kAudioUnitType_Output; }
+
+ bool IsSource () const { return IsMusicDevice() || IsGenerator(); }
+
+ OSType Type () const { return componentType; }
+ OSType SubType () const { return componentSubType; }
+ OSType Manu () const { return componentManufacturer; }
+
+ int Count() const { return CountComponents(const_cast<CAComponentDescription*>(this)); }
+
+ // does a semantic match where "wild card" values for type, subtype, manu will match
+ bool Matches (const ComponentDescription &desc) const;
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // other
+
+ void Print(FILE* file = stdout) const { _CAShowComponentDescription (this, file); }
+
+ OSStatus Save (CFPropertyListRef *outData) const;
+ OSStatus Restore (CFPropertyListRef &inData);
+
+private:
+ static void _CAShowComponentDescription (const ComponentDescription *desc, FILE* file);
+ friend void CAShowComponentDescription (const ComponentDescription *desc);
+};
+
+inline bool operator< (const ComponentDescription& x, const ComponentDescription& y)
+{
+ return memcmp (&x, &y, offsetof (ComponentDescription, componentFlags)) < 0;
+}
+
+inline bool operator== (const ComponentDescription& x, const ComponentDescription& y)
+{
+ return !memcmp (&x, &y, offsetof (ComponentDescription, componentFlags));
+}
+
+inline bool operator!= (const ComponentDescription& x, const ComponentDescription& y)
+{
+ return !(x == y);
+}
+
+#endif
diff --git a/libs/appleutility/CAConditionalMacros.h b/libs/appleutility/CAConditionalMacros.h
new file mode 100644
index 0000000000..62f642709a
--- /dev/null
+++ b/libs/appleutility/CAConditionalMacros.h
@@ -0,0 +1,74 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAConditionalMacros.h
+
+=============================================================================*/
+#if !defined(__CAConditionalMacros_h__)
+#define __CAConditionalMacros_h__
+
+//=============================================================================
+// This file exists to make figuring out how to include system headers
+// easier in a cross platform world. We throw in an include of the standard
+// ConditionalMacros too.
+//=============================================================================
+
+// ########## THIS FILE SHOULD GO AWAY SOON, replaced by __COREAUDIO_USE_FLAT_INCLUDES__
+// but for now, use this as a way to define __COREAUDIO_USE_FLAT_INCLUDES__ programmatically
+
+// TargetConditionals.h defines the bare minimum we need
+#include "TargetConditionals.h"
+
+// Determine whether or not to use framework style includes for system headers
+#if !defined(CoreAudio_Use_Framework_Includes) && !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #if TARGET_RT_MAC_MACHO
+ #define CoreAudio_Use_Framework_Includes 1
+ #else
+ #define CoreAudio_Use_Framework_Includes 0
+ #endif
+#endif
+
+// Include the regular ConditionalMacros.h too, since it has useful stuff that
+// TargetConditionals.h lacks for some reason.
+#if CoreAudio_Use_Framework_Includes
+ #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
+#else
+ #include "ConditionalMacros.h"
+#endif
+
+#endif
diff --git a/libs/appleutility/CADebugMacros.cpp b/libs/appleutility/CADebugMacros.cpp
new file mode 100644
index 0000000000..edee1f3d51
--- /dev/null
+++ b/libs/appleutility/CADebugMacros.cpp
@@ -0,0 +1,84 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CADebugMacros.cp
+
+=============================================================================*/
+
+#include "CADebugMacros.h"
+#include <stdio.h>
+#include <stdarg.h>
+#if TARGET_API_MAC_OSX
+ #include <syslog.h>
+#endif
+
+#if DEBUG
+#include <stdio.h>
+
+void DebugPrint(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ va_end(args);
+}
+#endif // DEBUG
+
+#if TARGET_API_MAC_OSX
+void LogError(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#if DEBUG
+ vprintf(fmt, args);
+#endif
+ vsyslog(LOG_ERR, fmt, args);
+ va_end(args);
+}
+
+void LogWarning(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+#if DEBUG
+ vprintf(fmt, args);
+#endif
+ vsyslog(LOG_WARNING, fmt, args);
+ va_end(args);
+}
+#endif
diff --git a/libs/appleutility/CADebugMacros.h b/libs/appleutility/CADebugMacros.h
new file mode 100644
index 0000000000..1abae40187
--- /dev/null
+++ b/libs/appleutility/CADebugMacros.h
@@ -0,0 +1,414 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CADebugMacros.h
+
+=============================================================================*/
+#if !defined(__CADebugMacros_h__)
+#define __CADebugMacros_h__
+
+//=============================================================================
+// CADebugMacros
+//=============================================================================
+
+//#define CoreAudio_StopOnFailure 1
+//#define CoreAudio_TimeStampMessages 1
+//#define CoreAudio_ThreadStampMessages 1
+//#define CoreAudio_FlushDebugMessages 1
+
+#define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
+
+#pragma mark Basic Definitions
+
+#if DEBUG || CoreAudio_Debug
+
+ // can be used to break into debugger immediately, also see CADebugger
+ #define BusError() (*(long *)0 = 0)
+
+ // basic debugging print routines
+ #if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
+ extern pascal void DebugStr(const unsigned char* debuggerMsg);
+ #define DebugMessage(msg) DebugStr("\p"msg)
+ #define DebugMessageN1(msg, N1)
+ #define DebugMessageN2(msg, N1, N2)
+ #define DebugMessageN3(msg, N1, N2, N3)
+ #else
+ #include "CADebugPrintf.h"
+
+ #if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
+ #define FlushRtn ;fflush(DebugPrintfFile)
+ #else
+ #define FlushRtn
+ #endif
+
+ #if CoreAudio_ThreadStampMessages
+ #include <pthread.h>
+ #include "CAHostTimeBase.h"
+ #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
+ #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
+ #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
+ #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
+ #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
+ #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
+ #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
+ #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
+ #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
+ #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%p %.4f: "msg"\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
+ #elif CoreAudio_TimeStampMessages
+ #include "CAHostTimeBase.h"
+ #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%.4f: %s"DebugPrintfLineEnding, pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), msg) FlushRtn
+ #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1) FlushRtn
+ #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2) FlushRtn
+ #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3) FlushRtn
+ #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4) FlushRtn
+ #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5) FlushRtn
+ #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6) FlushRtn
+ #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7) FlushRtn
+ #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
+ #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, "%.4f: "msg DebugPrintfLineEnding, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
+ #else
+ #define DebugMessage(msg) DebugPrintfRtn(DebugPrintfFile, "%s"DebugPrintfLineEnding, msg) FlushRtn
+ #define DebugMessageN1(msg, N1) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1) FlushRtn
+ #define DebugMessageN2(msg, N1, N2) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2) FlushRtn
+ #define DebugMessageN3(msg, N1, N2, N3) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3) FlushRtn
+ #define DebugMessageN4(msg, N1, N2, N3, N4) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4) FlushRtn
+ #define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5) FlushRtn
+ #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6) FlushRtn
+ #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7) FlushRtn
+ #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8) FlushRtn
+ #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugPrintfRtn(DebugPrintfFile, msg DebugPrintfLineEnding, N1, N2, N3, N4, N5, N6, N7, N8, N9) FlushRtn
+ #endif
+ #endif
+ void DebugPrint(const char *fmt, ...); // can be used like printf
+ #define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h)
+ #if VERBOSE
+ #define vprint(msg) DEBUGPRINT(msg)
+ #else
+ #define vprint(msg)
+ #endif
+
+ #if CoreAudio_StopOnFailure
+ #include "CADebugger.h"
+ #define STOP CADebuggerStop()
+ #else
+ #define STOP
+ #endif
+
+#else
+ #define DebugMessage(msg)
+ #define DebugMessageN1(msg, N1)
+ #define DebugMessageN2(msg, N1, N2)
+ #define DebugMessageN3(msg, N1, N2, N3)
+ #define DebugMessageN4(msg, N1, N2, N3, N4)
+ #define DebugMessageN5(msg, N1, N2, N3, N4, N5)
+ #define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6)
+ #define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7)
+ #define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8)
+ #define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
+ #define DEBUGPRINT(msg)
+ #define vprint(msg)
+ #define STOP
+#endif
+
+void LogError(const char *fmt, ...); // writes to syslog (and stderr if debugging)
+void LogWarning(const char *fmt, ...); // writes to syslog (and stderr if debugging)
+
+#if DEBUG || CoreAudio_Debug
+
+#pragma mark Debug Macros
+
+#define Assert(inCondition, inMessage) \
+ if(!(inCondition)) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ }
+
+#define AssertNoError(inError, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
+ STOP; \
+ } \
+ }
+
+#define AssertNoKernelError(inError, inMessage) \
+ { \
+ unsigned int __Err = (unsigned int)(inError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ STOP; \
+ } \
+ }
+
+#define FailIf(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ DebugMessage(inMessage); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelError(inKernelError, inException, inMessage) \
+ { \
+ kern_return_t __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#define FailIfError(inError, inException, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ } \
+ }
+
+#if defined(__cplusplus)
+
+#define Throw(inException) STOP; throw (inException)
+
+#define ThrowIf(inCondition, inException, inMessage) \
+ if(inCondition) \
+ { \
+ DebugMessage(inMessage); \
+ Throw(inException); \
+ }
+
+#define ThrowIfNULL(inPointer, inException, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ DebugMessage(inMessage); \
+ Throw(inException); \
+ }
+
+#define ThrowIfKernelError(inKernelError, inException, inMessage) \
+ { \
+ kern_return_t __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ Throw(inException); \
+ } \
+ }
+
+#define ThrowIfError(inError, inException, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ char __4CC[5] = CA4CCToCString(__Err); \
+ DebugMessageN2(inMessage ", Error: %ld (%s)", __Err, __4CC); \
+ Throw(inException); \
+ } \
+ }
+
+#if TARGET_OS_WIN32
+#define ThrowIfWinError(inError, inException, inMessage) \
+ { \
+ HRESULT __Err = (inError); \
+ if(FAILED(__Err)) \
+ { \
+ DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
+ Throw(inException); \
+ } \
+ }
+#endif
+
+#define SubclassResponsibility(inMethodName, inException) \
+ { \
+ DebugMessage(inMethodName": Subclasses must implement this method"); \
+ Throw(inException); \
+ }
+
+#endif // defined(__cplusplus)
+
+#else
+
+#pragma mark Release Macros
+
+#define Assert(inCondition, inMessage) \
+ if(!(inCondition)) \
+ { \
+ STOP; \
+ }
+
+#define AssertNoError(inError, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ } \
+ }
+
+#define AssertNoKernelError(inError, inMessage) \
+ { \
+ unsigned int __Err = (unsigned int)(inError); \
+ if(__Err != 0) \
+ { \
+ STOP; \
+ } \
+ }
+
+#define FailIf(inCondition, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ goto inHandler; \
+ }
+
+#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
+ if(inCondition) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfKernelError(inKernelError, inException, inMessage) \
+ if((inKernelError) != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#define FailIfError(inError, inException, inMessage) \
+ if((inError) != 0) \
+ { \
+ STOP; \
+ { inAction; } \
+ goto inHandler; \
+ }
+
+#if defined(__cplusplus)
+
+#define Throw(inException) STOP; throw (inException)
+
+#define ThrowIf(inCondition, inException, inMessage) \
+ if(inCondition) \
+ { \
+ Throw(inException); \
+ }
+
+#define ThrowIfNULL(inPointer, inException, inMessage) \
+ if((inPointer) == NULL) \
+ { \
+ Throw(inException); \
+ }
+
+#define ThrowIfKernelError(inKernelError, inException, inMessage) \
+ { \
+ kern_return_t __Err = (inKernelError); \
+ if(__Err != 0) \
+ { \
+ Throw(inException); \
+ } \
+ }
+
+#define ThrowIfError(inError, inException, inMessage) \
+ { \
+ SInt32 __Err = (inError); \
+ if(__Err != 0) \
+ { \
+ Throw(inException); \
+ } \
+ }
+
+#if TARGET_OS_WIN32
+#define ThrowIfWinError(inError, inException, inMessage) \
+ { \
+ HRESULT __Err = (inError); \
+ if(FAILED(__Err)) \
+ { \
+ Throw(inException); \
+ } \
+ }
+#endif
+
+#define SubclassResponsibility(inMethodName, inException) \
+ { \
+ Throw(inException); \
+ }
+
+#endif // defined(__cplusplus)
+
+#endif // DEBUG || CoreAudio_Debug
+
+#endif
diff --git a/libs/appleutility/CAMath.h b/libs/appleutility/CAMath.h
new file mode 100644
index 0000000000..32b4e7f0b3
--- /dev/null
+++ b/libs/appleutility/CAMath.h
@@ -0,0 +1,64 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAMath.h
+
+=============================================================================*/
+
+#ifndef __CAMath_h__
+#define __CAMath_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+#else
+ #include <CoreAudioTypes.h>
+#endif
+
+inline bool fiszero(Float64 f) { return (f == 0.); }
+inline bool fiszero(Float32 f) { return (f == 0.f); }
+
+inline bool fnonzero(Float64 f) { return !fiszero(f); }
+inline bool fnonzero(Float32 f) { return !fiszero(f); }
+
+inline bool fequal(const Float64 &a, const Float64 &b) { return a == b; }
+inline bool fequal(const Float32 &a, const Float32 &b) { return a == b; }
+
+inline bool fnotequal(const Float64 &a, const Float64 &b) { return !fequal(a, b); }
+inline bool fnotequal(const Float32 &a, const Float32 &b) { return !fequal(a, b); }
+
+#endif // __CAMath_h__
diff --git a/libs/appleutility/CAReferenceCounted.h b/libs/appleutility/CAReferenceCounted.h
new file mode 100644
index 0000000000..d57f97c31f
--- /dev/null
+++ b/libs/appleutility/CAReferenceCounted.h
@@ -0,0 +1,83 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAReferenceCounted.h
+
+=============================================================================*/
+
+#ifndef __CAReferenceCounted_h__
+#define __CAReferenceCounted_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreServices/CoreServices.h>
+#else
+ #include <CoreServices.h>
+#endif
+
+#if TARGET_OS_WIN32
+ #include "CAWindows.h"
+#endif
+
+// base class for reference-counted objects
+class CAReferenceCounted {
+public:
+ CAReferenceCounted() : mRefCount(1) {}
+
+ void retain() { IncrementAtomic(&mRefCount); }
+
+ void release()
+ {
+ // this returns the ORIGINAL value, not the new one.
+ SInt32 rc = DecrementAtomic(&mRefCount);
+ if (rc == 1) {
+ delete this;
+ }
+ }
+
+protected:
+ virtual ~CAReferenceCounted() { }
+
+private:
+ SInt32 mRefCount;
+
+ CAReferenceCounted(const CAReferenceCounted &a) : mRefCount(0) { }
+ CAReferenceCounted operator=(const CAReferenceCounted &a) { return *this; }
+};
+
+
+#endif // __CAReferenceCounted_h__
diff --git a/libs/appleutility/CAStreamBasicDescription.cpp b/libs/appleutility/CAStreamBasicDescription.cpp
new file mode 100644
index 0000000000..f65bdd99ac
--- /dev/null
+++ b/libs/appleutility/CAStreamBasicDescription.cpp
@@ -0,0 +1,520 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAStreamBasicDescription.cpp
+
+=============================================================================*/
+
+#include "CAConditionalMacros.h"
+
+#include "CAStreamBasicDescription.h"
+#include "CAMath.h"
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreFoundation/CFByteOrder.h>
+#else
+ #include <CFByteOrder.h>
+#endif
+
+#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
+
+const AudioStreamBasicDescription CAStreamBasicDescription::sEmpty = { 0.0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+CAStreamBasicDescription::CAStreamBasicDescription(double inSampleRate, UInt32 inFormatID,
+ UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
+ UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
+ UInt32 inBitsPerChannel, UInt32 inFormatFlags)
+{
+ mSampleRate = inSampleRate;
+ mFormatID = inFormatID;
+ mBytesPerPacket = inBytesPerPacket;
+ mFramesPerPacket = inFramesPerPacket;
+ mBytesPerFrame = inBytesPerFrame;
+ mChannelsPerFrame = inChannelsPerFrame;
+ mBitsPerChannel = inBitsPerChannel;
+ mFormatFlags = inFormatFlags;
+}
+
+void CAStreamBasicDescription::PrintFormat(FILE *f, const char *indent, const char *name) const
+{
+ fprintf(f, "%s%s ", indent, name);
+ char formatID[5];
+ *(UInt32 *)formatID = CFSwapInt32HostToBig(mFormatID);
+ formatID[4] = '\0';
+ fprintf(f, "%2ld ch, %6.0f Hz, '%-4.4s' (0x%08lX) ",
+ NumberChannels(), mSampleRate, formatID,
+ mFormatFlags);
+ if (mFormatID == kAudioFormatLinearPCM) {
+ bool isInt = !(mFormatFlags & kLinearPCMFormatFlagIsFloat);
+ int wordSize = SampleWordSize();
+ const char *endian = (wordSize > 1) ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsBigEndian) ? " big-endian" : " little-endian" ) : "";
+ const char *sign = isInt ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsSignedInteger) ? " signed" : " unsigned") : "";
+ const char *floatInt = isInt ? "integer" : "float";
+ char packed[32];
+ if (wordSize > 0 && PackednessIsSignificant()) {
+ if (mFormatFlags & kLinearPCMFormatFlagIsPacked)
+ sprintf(packed, "packed in %d bytes", wordSize);
+ else
+ sprintf(packed, "unpacked in %d bytes", wordSize);
+ } else
+ packed[0] = '\0';
+ const char *align = (wordSize > 0 && AlignmentIsSignificant()) ?
+ ((mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) ? " high-aligned" : " low-aligned") : "";
+ const char *deinter = (mFormatFlags & kAudioFormatFlagIsNonInterleaved) ? ", deinterleaved" : "";
+ const char *commaSpace = (packed[0]!='\0') || (align[0]!='\0') ? ", " : "";
+
+ fprintf(f, "%ld-bit%s%s %s%s%s%s%s\n",
+ mBitsPerChannel, endian, sign, floatInt,
+ commaSpace, packed, align, deinter);
+ } else if (mFormatID == 'alac') { // kAudioFormatAppleLossless
+ int sourceBits = 0;
+ switch (mFormatFlags)
+ {
+ case 1: // kAppleLosslessFormatFlag_16BitSourceData
+ sourceBits = 16;
+ break;
+ case 2: // kAppleLosslessFormatFlag_20BitSourceData
+ sourceBits = 20;
+ break;
+ case 3: // kAppleLosslessFormatFlag_24BitSourceData
+ sourceBits = 24;
+ break;
+ case 4: // kAppleLosslessFormatFlag_32BitSourceData
+ sourceBits = 32;
+ break;
+ }
+ if (sourceBits)
+ fprintf(f, "from %d-bit source, ", sourceBits);
+ else
+ fprintf(f, "from UNKNOWN source bit depth, ");
+
+ fprintf(f, "%ld frames/packet\n", mFramesPerPacket);
+ }
+ else
+ fprintf(f, "%ld bits/channel, %ld bytes/packet, %ld frames/packet, %ld bytes/frame\n",
+ mBitsPerChannel, mBytesPerPacket, mFramesPerPacket, mBytesPerFrame);
+}
+
+void CAStreamBasicDescription::NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription)
+{
+ // the only thing that changes is to make mixable linear PCM into the canonical linear PCM format
+ if((ioDescription.mFormatID == kAudioFormatLinearPCM) && ((ioDescription.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ // the canonical linear PCM format is 32 bit native endian floats
+ ioDescription.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
+ ioDescription.mBytesPerPacket = sizeof(Float32) * ioDescription.mChannelsPerFrame;
+ ioDescription.mFramesPerPacket = 1;
+ ioDescription.mBytesPerFrame = sizeof(Float32) * ioDescription.mChannelsPerFrame;
+ ioDescription.mBitsPerChannel = 8 * sizeof(Float32);
+ }
+}
+
+void CAStreamBasicDescription::ResetFormat(AudioStreamBasicDescription& ioDescription)
+{
+ ioDescription.mSampleRate = 0;
+ ioDescription.mFormatID = 0;
+ ioDescription.mBytesPerPacket = 0;
+ ioDescription.mFramesPerPacket = 0;
+ ioDescription.mBytesPerFrame = 0;
+ ioDescription.mChannelsPerFrame = 0;
+ ioDescription.mBitsPerChannel = 0;
+ ioDescription.mFormatFlags = 0;
+}
+
+void CAStreamBasicDescription::FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription)
+{
+ if(fiszero(ioDescription.mSampleRate))
+ {
+ ioDescription.mSampleRate = inTemplateDescription.mSampleRate;
+ }
+ if(ioDescription.mFormatID == 0)
+ {
+ ioDescription.mFormatID = inTemplateDescription.mFormatID;
+ }
+ if(ioDescription.mFormatFlags == 0)
+ {
+ ioDescription.mFormatFlags = inTemplateDescription.mFormatFlags;
+ }
+ if(ioDescription.mBytesPerPacket == 0)
+ {
+ ioDescription.mBytesPerPacket = inTemplateDescription.mBytesPerPacket;
+ }
+ if(ioDescription.mFramesPerPacket == 0)
+ {
+ ioDescription.mFramesPerPacket = inTemplateDescription.mFramesPerPacket;
+ }
+ if(ioDescription.mBytesPerFrame == 0)
+ {
+ ioDescription.mBytesPerFrame = inTemplateDescription.mBytesPerFrame;
+ }
+ if(ioDescription.mChannelsPerFrame == 0)
+ {
+ ioDescription.mChannelsPerFrame = inTemplateDescription.mChannelsPerFrame;
+ }
+ if(ioDescription.mBitsPerChannel == 0)
+ {
+ ioDescription.mBitsPerChannel = inTemplateDescription.mBitsPerChannel;
+ }
+}
+
+void CAStreamBasicDescription::GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate)
+{
+ switch(inDescription.mFormatID)
+ {
+ case kAudioFormatLinearPCM:
+ {
+ const char* theEndianString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0)
+ {
+ #if TARGET_RT_LITTLE_ENDIAN
+ theEndianString = "Big Endian";
+ #endif
+ }
+ else
+ {
+ #if TARGET_RT_BIG_ENDIAN
+ theEndianString = "Little Endian";
+ #endif
+ }
+
+ const char* theKindString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
+ {
+ theKindString = (inAbbreviate ? "Float" : "Floating Point");
+ }
+ else if((inDescription.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
+ {
+ theKindString = (inAbbreviate ? "SInt" : "Signed Integer");
+ }
+ else
+ {
+ theKindString = (inAbbreviate ? "UInt" : "Unsigned Integer");
+ }
+
+ const char* thePackingString = NULL;
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsPacked) == 0)
+ {
+ if((inDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0)
+ {
+ thePackingString = "High";
+ }
+ else
+ {
+ thePackingString = "Low";
+ }
+ }
+
+ const char* theMixabilityString = NULL;
+ if((inDescription.mFormatFlags & kIsNonMixableFlag) == 0)
+ {
+ theMixabilityString = "Mixable";
+ }
+ else
+ {
+ theMixabilityString = "Unmixable";
+ }
+
+ if(inAbbreviate)
+ {
+ if(theEndianString != NULL)
+ {
+ if(thePackingString != NULL)
+ {
+ sprintf(outName, "%s %d Ch %s %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ sprintf(outName, "%s %d Ch %s %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theEndianString, theKindString, (int)inDescription.mBitsPerChannel);
+ }
+ }
+ else
+ {
+ if(thePackingString != NULL)
+ {
+ sprintf(outName, "%s %d Ch %s %s%d/%s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, thePackingString, theKindString, (int)inDescription.mBitsPerChannel, theKindString, (int)((inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8));
+ }
+ else
+ {
+ sprintf(outName, "%s %d Ch %s%d", theMixabilityString, (int)inDescription.mChannelsPerFrame, theKindString, (int)inDescription.mBitsPerChannel);
+ }
+ }
+ }
+ else
+ {
+ if(theEndianString != NULL)
+ {
+ if(thePackingString != NULL)
+ {
+ sprintf(outName, "%s %d Channel %d Bit %s %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ sprintf(outName, "%s %d Channel %d Bit %s %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theEndianString, theKindString);
+ }
+ }
+ else
+ {
+ if(thePackingString != NULL)
+ {
+ sprintf(outName, "%s %d Channel %d Bit %s Aligned %s in %d Bits", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString, thePackingString, (int)(inDescription.mBytesPerFrame / inDescription.mChannelsPerFrame) * 8);
+ }
+ else
+ {
+ sprintf(outName, "%s %d Channel %d Bit %s", theMixabilityString, (int)inDescription.mChannelsPerFrame, (int)inDescription.mBitsPerChannel, theKindString);
+ }
+ }
+ }
+ }
+ break;
+
+ case kAudioFormatAC3:
+ strcpy(outName, "AC-3");
+ break;
+
+ case kAudioFormat60958AC3:
+ strcpy(outName, "AC-3 for SPDIF");
+ break;
+
+ default:
+ {
+ char* the4CCString = (char*)&inDescription.mFormatID;
+ outName[0] = the4CCString[0];
+ outName[1] = the4CCString[1];
+ outName[2] = the4CCString[2];
+ outName[3] = the4CCString[3];
+ outName[4] = 0;
+ }
+ break;
+ };
+}
+
+#if CoreAudio_Debug
+#include "CALogMacros.h"
+
+void CAStreamBasicDescription::PrintToLog(const AudioStreamBasicDescription& inDesc)
+{
+ PrintFloat (" Sample Rate: ", inDesc.mSampleRate);
+ Print4CharCode (" Format ID: ", inDesc.mFormatID);
+ PrintHex (" Format Flags: ", inDesc.mFormatFlags);
+ PrintInt (" Bytes per Packet: ", inDesc.mBytesPerPacket);
+ PrintInt (" Frames per Packet: ", inDesc.mFramesPerPacket);
+ PrintInt (" Bytes per Frame: ", inDesc.mBytesPerFrame);
+ PrintInt (" Channels per Frame: ", inDesc.mChannelsPerFrame);
+ PrintInt (" Bits per Channel: ", inDesc.mBitsPerChannel);
+}
+#endif
+
+bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ bool theAnswer = false;
+ bool isDone = false;
+
+ // note that if either side is 0, that field is skipped
+
+ // format ID is the first order sort
+ if((!isDone) && ((x.mFormatID != 0) && (y.mFormatID != 0)))
+ {
+ if(x.mFormatID != y.mFormatID)
+ {
+ // formats are sorted numerically except that linear
+ // PCM is always first
+ if(x.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = true;
+ }
+ else if(y.mFormatID == kAudioFormatLinearPCM)
+ {
+ theAnswer = false;
+ }
+ else
+ {
+ theAnswer = x.mFormatID < y.mFormatID;
+ }
+ isDone = true;
+ }
+ }
+
+
+ // mixable is always better than non-mixable for linear PCM and should be the second order sort item
+ if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if(((x.mFormatFlags & kIsNonMixableFlag) == 0) && ((y.mFormatFlags & kIsNonMixableFlag) != 0))
+ {
+ theAnswer = true;
+ isDone = true;
+ }
+ else if(((x.mFormatFlags & kIsNonMixableFlag) != 0) && ((y.mFormatFlags & kIsNonMixableFlag) == 0))
+ {
+ theAnswer = false;
+ isDone = true;
+ }
+ }
+
+ // floating point vs integer for linear PCM only
+ if((!isDone) && ((x.mFormatID == kAudioFormatLinearPCM) && (y.mFormatID == kAudioFormatLinearPCM)))
+ {
+ if((x.mFormatFlags & kAudioFormatFlagIsFloat) != (y.mFormatFlags & kAudioFormatFlagIsFloat))
+ {
+ // floating point is better than integer
+ theAnswer = y.mFormatFlags & kAudioFormatFlagIsFloat;
+ isDone = true;
+ }
+ }
+
+ // bit depth
+ if((!isDone) && ((x.mBitsPerChannel != 0) && (y.mBitsPerChannel != 0)))
+ {
+ if(x.mBitsPerChannel != y.mBitsPerChannel)
+ {
+ // deeper bit depths are higher quality
+ theAnswer = x.mBitsPerChannel < y.mBitsPerChannel;
+ isDone = true;
+ }
+ }
+
+ // sample rate
+ if((!isDone) && fnonzero(x.mSampleRate) && fnonzero(y.mSampleRate))
+ {
+ if(fnotequal(x.mSampleRate, y.mSampleRate))
+ {
+ // higher sample rates are higher quality
+ theAnswer = x.mSampleRate < y.mSampleRate;
+ isDone = true;
+ }
+ }
+
+ // number of channels
+ if((!isDone) && ((x.mChannelsPerFrame != 0) && (y.mChannelsPerFrame != 0)))
+ {
+ if(x.mChannelsPerFrame != y.mChannelsPerFrame)
+ {
+ // more channels is higher quality
+ theAnswer = x.mChannelsPerFrame < y.mChannelsPerFrame;
+ isDone = true;
+ }
+ }
+
+ return theAnswer;
+}
+
+static bool MatchFormatFlags(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ UInt32 xFlags = x.mFormatFlags;
+ UInt32 yFlags = y.mFormatFlags;
+
+ // match wildcards
+ if (x.mFormatID == 0 || y.mFormatID == 0 || xFlags == 0 || yFlags == 0)
+ return true;
+
+ if (x.mFormatID == kAudioFormatLinearPCM)
+ {
+ // knock off the all clear flag
+ xFlags = xFlags & ~kAudioFormatFlagsAreAllClear;
+ yFlags = yFlags & ~kAudioFormatFlagsAreAllClear;
+
+ // if both kAudioFormatFlagIsPacked bits are set, then we don't care about the kAudioFormatFlagIsAlignedHigh bit.
+ if (xFlags & yFlags & kAudioFormatFlagIsPacked) {
+ xFlags = xFlags & ~kAudioFormatFlagIsAlignedHigh;
+ yFlags = yFlags & ~kAudioFormatFlagIsAlignedHigh;
+ }
+
+ // if both kAudioFormatFlagIsFloat bits are set, then we don't care about the kAudioFormatFlagIsSignedInteger bit.
+ if (xFlags & yFlags & kAudioFormatFlagIsFloat) {
+ xFlags = xFlags & ~kAudioFormatFlagIsSignedInteger;
+ yFlags = yFlags & ~kAudioFormatFlagIsSignedInteger;
+ }
+
+ // if the bit depth is 8 bits or less and the format is packed, we don't care about endianness
+ if((x.mBitsPerChannel <= 8) && ((xFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+ {
+ xFlags = xFlags & ~kAudioFormatFlagIsBigEndian;
+ }
+ if((y.mBitsPerChannel <= 8) && ((yFlags & kAudioFormatFlagIsPacked) == kAudioFormatFlagIsPacked))
+ {
+ yFlags = yFlags & ~kAudioFormatFlagIsBigEndian;
+ }
+
+ // if the number of channels is 0 or 1, we don't care about non-interleavedness
+ if (x.mChannelsPerFrame <= 1 && y.mChannelsPerFrame <= 1) {
+ xFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
+ yFlags &= ~kLinearPCMFormatFlagIsNonInterleaved;
+ }
+ }
+ return xFlags == yFlags;
+}
+
+bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y)
+{
+ // the semantics for equality are:
+ // 1) Values must match exactly
+ // 2) wildcard's are ignored in the comparison
+
+#define MATCH(name) ((x.name) == 0 || (y.name) == 0 || (x.name) == (y.name))
+
+ return
+ // check the sample rate
+ (fiszero(x.mSampleRate) || fiszero(y.mSampleRate) || fequal(x.mSampleRate, y.mSampleRate))
+
+ // check the format ids
+ && MATCH(mFormatID)
+
+ // check the format flags
+ && MatchFormatFlags(x, y)
+
+ // check the bytes per packet
+ && MATCH(mBytesPerPacket)
+
+ // check the frames per packet
+ && MATCH(mFramesPerPacket)
+
+ // check the bytes per frame
+ && MATCH(mBytesPerFrame)
+
+ // check the channels per frame
+ && MATCH(mChannelsPerFrame)
+
+ // check the channels per frame
+ && MATCH(mBitsPerChannel) ;
+}
+
+bool SanityCheck(const AudioStreamBasicDescription& x)
+{
+ return (x.mSampleRate >= 0.);
+}
diff --git a/libs/appleutility/CAStreamBasicDescription.h b/libs/appleutility/CAStreamBasicDescription.h
new file mode 100644
index 0000000000..aa41c40fe4
--- /dev/null
+++ b/libs/appleutility/CAStreamBasicDescription.h
@@ -0,0 +1,224 @@
+/* Copyright: © Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs
+ copyrights in this original Apple software (the "Apple Software"), to use,
+ reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions of
+ the Apple Software. Neither the name, trademarks, service marks or logos of
+ Apple Computer, Inc. may be used to endorse or promote products derived from the
+ Apple Software without specific prior written permission from Apple. Except as
+ expressly stated in this notice, no other rights or licenses, express or implied,
+ are granted by Apple herein, including but not limited to any patent rights that
+ may be infringed by your derivative works or by other works in which the Apple
+ Software may be incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+ OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+ (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+ CAStreamBasicDescription.h
+
+=============================================================================*/
+
+#ifndef __CAStreamBasicDescription_h__
+#define __CAStreamBasicDescription_h__
+
+#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
+ #include <CoreAudio/CoreAudioTypes.h>
+ #include <CoreFoundation/CoreFoundation.h>
+#else
+ #include "CoreAudioTypes.h"
+ #include "CoreFoundation.h"
+#endif
+
+#include "CADebugMacros.h"
+#include <string.h> // for memset, memcpy
+#include <stdio.h> // for FILE *
+
+#pragma mark This file needs to compile on more earlier versions of the OS, so please keep that in mind when editing it
+
+// define the IsMixable format flag for all versions of the system
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3)
+ enum { kIsNonMixableFlag = kAudioFormatFlagIsNonMixable };
+#else
+ enum { kIsNonMixableFlag = (1L << 6) };
+#endif
+
+//=============================================================================
+// CAStreamBasicDescription
+//
+// This is a wrapper class for the AudioStreamBasicDescription struct.
+// It adds a number of convenience routines, but otherwise adds nothing
+// to the footprint of the original struct.
+//=============================================================================
+class CAStreamBasicDescription :
+ public AudioStreamBasicDescription
+{
+
+// Constants
+public:
+ static const AudioStreamBasicDescription sEmpty;
+
+// Construction/Destruction
+public:
+ CAStreamBasicDescription() { memset (this, 0, sizeof(AudioStreamBasicDescription)); }
+
+ CAStreamBasicDescription(const AudioStreamBasicDescription &desc)
+ {
+ SetFrom(desc);
+ }
+
+ CAStreamBasicDescription( double inSampleRate, UInt32 inFormatID,
+ UInt32 inBytesPerPacket, UInt32 inFramesPerPacket,
+ UInt32 inBytesPerFrame, UInt32 inChannelsPerFrame,
+ UInt32 inBitsPerChannel, UInt32 inFormatFlags);
+
+// Assignment
+ CAStreamBasicDescription& operator=(const AudioStreamBasicDescription& v) { SetFrom(v); return *this; }
+
+ void SetFrom(const AudioStreamBasicDescription &desc)
+ {
+ memcpy(this, &desc, sizeof(AudioStreamBasicDescription));
+ }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // interrogation
+
+ bool IsPCM() const { return mFormatID == kAudioFormatLinearPCM; }
+
+ bool PackednessIsSignificant() const
+ {
+ Assert(IsPCM(), "PackednessIsSignificant only applies for PCM");
+ return (SampleWordSize() << 3) != mBitsPerChannel;
+ }
+
+ bool AlignmentIsSignificant() const
+ {
+ return PackednessIsSignificant() || (mBitsPerChannel & 7) != 0;
+ }
+
+ bool IsInterleaved() const
+ {
+ return !IsPCM() || !(mFormatFlags & kAudioFormatFlagIsNonInterleaved);
+ }
+
+ // for sanity with interleaved/deinterleaved possibilities, never access mChannelsPerFrame, use these:
+ UInt32 NumberInterleavedChannels() const { return IsInterleaved() ? mChannelsPerFrame : 1; }
+ UInt32 NumberChannelStreams() const { return IsInterleaved() ? 1 : mChannelsPerFrame; }
+ UInt32 NumberChannels() const { return mChannelsPerFrame; }
+ UInt32 SampleWordSize() const { return (mBytesPerFrame > 0) ? mBytesPerFrame / NumberInterleavedChannels() : 0;}
+
+ UInt32 FramesToBytes(UInt32 nframes) const { return nframes * mBytesPerFrame; }
+ UInt32 BytesToFrames(UInt32 nbytes) const {
+ Assert(mBytesPerFrame > 0, "bytesPerFrame must be > 0 in BytesToFrames");
+ return nbytes / mBytesPerFrame;
+ }
+
+ bool SameChannelsAndInterleaving(const CAStreamBasicDescription &a) const
+ {
+ return this->NumberChannels() == a.NumberChannels() && this->IsInterleaved() == a.IsInterleaved();
+ }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // manipulation
+
+ void SetCanonical(UInt32 nChannels, bool interleaved)
+ // note: leaves sample rate untouched
+ {
+ mFormatID = kAudioFormatLinearPCM;
+ mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
+ mBitsPerChannel = 32;
+ mChannelsPerFrame = nChannels;
+ mFramesPerPacket = 1;
+ if (interleaved)
+ mBytesPerPacket = mBytesPerFrame = nChannels * sizeof(Float32);
+ else {
+ mBytesPerPacket = mBytesPerFrame = sizeof(Float32);
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ }
+ }
+
+ void ChangeNumberChannels(UInt32 nChannels, bool interleaved)
+ // alter an existing format
+ {
+ Assert(IsPCM(), "ChangeNumberChannels only works for PCM formats");
+ UInt32 wordSize = SampleWordSize(); // get this before changing ANYTHING
+ if (wordSize == 0)
+ wordSize = (mBitsPerChannel + 7) / 8;
+ mChannelsPerFrame = nChannels;
+ mFramesPerPacket = 1;
+ if (interleaved) {
+ mBytesPerPacket = mBytesPerFrame = nChannels * wordSize;
+ mFormatFlags &= ~kAudioFormatFlagIsNonInterleaved;
+ } else {
+ mBytesPerPacket = mBytesPerFrame = wordSize;
+ mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
+ }
+ }
+
+ // _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
+ //
+ // other
+
+ void Print() const
+ {
+ Print (stdout);
+ }
+
+ void Print(FILE* file) const
+ {
+ PrintFormat (file, "", "AudioStreamBasicDescription:");
+ }
+
+ void PrintFormat(FILE *f, const char *indent, const char *name) const;
+
+ OSStatus Save(CFPropertyListRef *outData) const;
+
+ OSStatus Restore(CFPropertyListRef &inData);
+
+// Operations
+ static bool IsMixable(const AudioStreamBasicDescription& inDescription) { return (inDescription.mFormatID == kAudioFormatLinearPCM) && ((inDescription.mFormatFlags & kIsNonMixableFlag) == 0); }
+ static void NormalizeLinearPCMFormat(AudioStreamBasicDescription& ioDescription);
+ static void ResetFormat(AudioStreamBasicDescription& ioDescription);
+ static void FillOutFormat(AudioStreamBasicDescription& ioDescription, const AudioStreamBasicDescription& inTemplateDescription);
+ static void GetSimpleName(const AudioStreamBasicDescription& inDescription, char* outName, bool inAbbreviate);
+#if CoreAudio_Debug
+ static void PrintToLog(const AudioStreamBasicDescription& inDesc);
+#endif
+};
+
+bool operator<(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+bool operator==(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y);
+#if TARGET_OS_MAC || (TARGET_OS_WIN32 && (_MSC_VER > 600))
+inline bool operator!=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x == y); }
+inline bool operator<=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return (x < y) || (x == y); }
+inline bool operator>=(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !(x < y); }
+inline bool operator>(const AudioStreamBasicDescription& x, const AudioStreamBasicDescription& y) { return !((x < y) || (x == y)); }
+#endif
+
+bool SanityCheck(const AudioStreamBasicDescription& x);
+
+
+#endif // __CAStreamBasicDescription_h__
diff --git a/libs/appleutility/SConscript b/libs/appleutility/SConscript
new file mode 100644
index 0000000000..2f3280f8b6
--- /dev/null
+++ b/libs/appleutility/SConscript
@@ -0,0 +1,23 @@
+# -*- python -*-
+
+import os
+import os.path
+import glob
+
+appleutility_files = glob.glob('*.cpp')
+
+Import('env install_prefix')
+appleutility = env.Copy()
+
+appleutility.Append(LINKFLAGS='-framework AudioToolbox')
+appleutility.Append(LINKFLAGS='-framework AudioUnit')
+appleutility.Append(LINKFLAGS='-framework CoreFoundation')
+appleutility.Append(LINKFLAGS='-framework CoreServices')
+
+libappleutility = appleutility.SharedLibrary('appleutility', appleutility_files)
+
+Default(libappleutility)
+
+env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libappleutility))
+
+env.Alias('tarball', env.Distribute (env['DISTTREE'], ['SConscript'] + appleutility_files + glob.glob('*.h') ))
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index a1bed7aeef..44cec8638c 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -27,9 +27,11 @@ ardour.Append(POTFILE = domain + '.pot')
ardour.Append(CPPPATH = '#libs/surfaces/control_protocol')
ardour_files=Split("""
+diskstream.cc
audio_diskstream.cc
audio_library.cc
audio_playlist.cc
+track.cc
audio_track.cc
audioengine.cc
audiofilesource.cc
@@ -88,7 +90,6 @@ sndfile_helpers.cc
sndfilesource.cc
source.cc
state_manager.cc
-stateful.cc
tempo.cc
utils.cc
version.cc
@@ -99,7 +100,7 @@ arch_specific_objects = [ ]
osc_files = [ 'osc.cc' ]
vst_files = [ 'vst_plugin.cc', 'session_vst.cc' ]
-coreaudio_files = [ 'coreaudiosource.cc' ]
+coreaudio_files = [ 'audio_unit.cc', 'coreaudiosource.cc' ]
extra_sources = [ ]
if ardour['VST']:
@@ -199,7 +200,7 @@ ardour.Merge ([
libraries['lrdf'],
libraries['samplerate'],
libraries['sigc2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['soundtouch'],
libraries['midi++2'],
libraries['glib2'],
@@ -209,6 +210,9 @@ ardour.Merge ([
if ardour['LIBLO']:
ardour.Merge ([ libraries['lo'] ])
+if ardour['COREAUDIO']:
+ ardour.Merge ([ libraries['appleutility'] ])
+
ardour.VersionBuild(['version.cc', 'ardour/version.h'], 'SConscript')
def SharedAsmObjectEmitter(target, source, env):
diff --git a/libs/ardour/ardour/ardour.h b/libs/ardour/ardour/ardour.h
index c0dfea9a95..e3b7cf2313 100644
--- a/libs/ardour/ardour/ardour.h
+++ b/libs/ardour/ardour/ardour.h
@@ -45,7 +45,7 @@ namespace ARDOUR {
static const jack_nframes_t max_frames = JACK_MAX_FRAMES;
- int init (AudioEngine&, bool with_vst, bool try_optimization);
+ int init (bool with_vst, bool try_optimization);
int cleanup ();
@@ -58,7 +58,7 @@ namespace ARDOUR {
const layer_t max_layer = UCHAR_MAX;
- id_t new_id();
+ microseconds_t get_microseconds ();
Change new_change ();
@@ -74,7 +74,7 @@ namespace ARDOUR {
const char* old;
};
-};
+}
/* how do we make these be within the Ardour namespace? */
diff --git a/libs/ardour/ardour/audio_diskstream.h b/libs/ardour/ardour/audio_diskstream.h
index 9355a3fccb..e2dfc5fd0c 100644
--- a/libs/ardour/ardour/audio_diskstream.h
+++ b/libs/ardour/ardour/audio_diskstream.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -14,12 +14,10 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
*/
-#ifndef __ardour_diskstream_h__
-#define __ardour_diskstream_h__
+#ifndef __ardour_audio_diskstream_h__
+#define __ardour_audio_diskstream_h__
#include <sigc++/signal.h>
@@ -33,7 +31,7 @@
#include <pbd/fastlog.h>
#include <pbd/ringbufferNPT.h>
-
+#include <pbd/stateful.h>
#include <ardour/ardour.h>
#include <ardour/configuration.h>
@@ -42,7 +40,8 @@
#include <ardour/route.h>
#include <ardour/port.h>
#include <ardour/utils.h>
-#include <ardour/stateful.h>
+#include <ardour/diskstream.h>
+#include <ardour/audioplaylist.h>
struct tm;
@@ -55,53 +54,20 @@ class AudioPlaylist;
class AudioFileSource;
class IO;
-class AudioDiskstream : public Stateful, public sigc::trackable
+class AudioDiskstream : public Diskstream
{
public:
- enum Flag {
- Recordable = 0x1,
- Hidden = 0x2,
- Destructive = 0x4
- };
-
- AudioDiskstream (Session &, const string& name, Flag f = Recordable);
+ AudioDiskstream (Session &, const string& name, Diskstream::Flag f = Recordable);
AudioDiskstream (Session &, const XMLNode&);
- string name() const { return _name; }
-
- ARDOUR::IO* io() const { return _io; }
- void set_io (ARDOUR::IO& io);
+ const PBD::ID& id() const { return _id; }
+ // FIXME
AudioDiskstream& ref() { _refcnt++; return *this; }
- void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
- uint32_t refcnt() const { return _refcnt; }
float playback_buffer_load() const;
float capture_buffer_load() const;
- void set_flag (Flag f) {
- _flags |= f;
- }
-
- void unset_flag (Flag f) {
- _flags &= ~f;
- }
-
- AlignStyle alignment_style() const { return _alignment_style; }
- void set_align_style (AlignStyle);
- void set_persistent_align_style (AlignStyle);
-
- bool hidden() const { return _flags & Hidden; }
- bool recordable() const { return _flags & Recordable; }
- bool destructive() const { return _flags & Destructive; }
-
- void set_destructive (bool yn);
-
- jack_nframes_t roll_delay() const { return _roll_delay; }
- void set_roll_delay (jack_nframes_t);
-
- int set_name (string str, void* src);
-
string input_source (uint32_t n=0) const {
if (n < channels.size()) {
return channels[n].source ? channels[n].source->name() : "";
@@ -114,14 +80,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
if (n < channels.size()) return channels[n].source; return 0;
}
- void set_record_enabled (bool yn, void *src);
- bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
- void punch_in ();
- void punch_out ();
-
- bool reversed() const { return _actual_speed < 0.0f; }
- double speed() const { return _visible_speed; }
- void set_speed (double);
+ void set_record_enabled (bool yn);
float peak_power(uint32_t n=0) {
float x = channels[n].peak_power;
@@ -132,14 +91,13 @@ class AudioDiskstream : public Stateful, public sigc::trackable
return minus_infinity();
}
}
+
+ AudioPlaylist* audio_playlist () { return dynamic_cast<AudioPlaylist*>(_playlist); }
- int use_playlist (AudioPlaylist *);
+ int use_playlist (Playlist *);
int use_new_playlist ();
int use_copy_playlist ();
- void start_scrub (jack_nframes_t where);
- void end_scrub ();
-
Sample *playback_buffer (uint32_t n=0) {
if (n < channels.size())
return channels[n].current_playback_buffer;
@@ -152,51 +110,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable
return 0;
}
- AudioPlaylist *playlist () { return _playlist; }
-
AudioFileSource *write_source (uint32_t n=0) {
if (n < channels.size())
return channels[n].write_source;
return 0;
}
- jack_nframes_t current_capture_start() const { return capture_start_frame; }
- jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
- jack_nframes_t get_capture_start_frame (uint32_t n=0);
- jack_nframes_t get_captured_frames (uint32_t n=0);
-
- uint32_t n_channels() { return _n_channels; }
-
int add_channel ();
int remove_channel ();
- static void set_disk_io_chunk_frames (uint32_t n) {
- disk_io_chunk_frames = n;
- }
-
- static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
- sigc::signal<void,void*> record_enable_changed;
- sigc::signal<void> speed_changed;
- sigc::signal<void,void*> reverse_changed;
- sigc::signal<void> PlaylistChanged;
- sigc::signal<void> AlignmentStyleChanged;
-
- static sigc::signal<void> DiskOverrun;
- static sigc::signal<void> DiskUnderrun;
- static sigc::signal<void,AudioDiskstream*> AudioDiskstreamCreated; // XXX use a ref with sigc2
- static sigc::signal<void,list<AudioFileSource*>*> DeleteSources;
-
/* stateful */
XMLNode& get_state(void);
- int set_state(const XMLNode& node);
+ int set_state(const XMLNode& node);
void monitor_input (bool);
- jack_nframes_t capture_offset() const { return _capture_offset; }
- void set_capture_offset ();
-
static void swap_by_ptr (Sample *first, Sample *last) {
while (first < last) {
Sample tmp = *first;
@@ -213,19 +143,7 @@ class AudioDiskstream : public Stateful, public sigc::trackable
}
}
- bool slaved() const { return _slaved; }
- void set_slaved(bool yn) { _slaved = yn; }
-
- int set_loop (Location *loc);
- sigc::signal<void,Location *> LoopSet;
-
- std::list<Region*>& last_capture_regions () {
- return _last_capture_regions;
- }
-
- void handle_input_change (IOChange, void *src);
-
- id_t id() const { return _id; }
+ std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
XMLNode* deprecated_io_node;
@@ -237,9 +155,8 @@ class AudioDiskstream : public Stateful, public sigc::trackable
while they are called.
*/
- void set_pending_overwrite (bool);
+ void set_pending_overwrite(bool);
int overwrite_existing_buffers ();
- void reverse_scrub_buffer (bool to_forward);
void set_block_size (jack_nframes_t);
int internal_playback_seek (jack_nframes_t distance);
int can_internal_playback_seek (jack_nframes_t distance);
@@ -247,9 +164,6 @@ class AudioDiskstream : public Stateful, public sigc::trackable
void reset_write_sources (bool, bool force = false);
void non_realtime_input_change ();
- uint32_t read_data_count() const { return _read_data_count; }
- uint32_t write_data_count() const { return _write_data_count; }
-
protected:
friend class Auditioner;
int seek (jack_nframes_t which_sample, bool complete_refill = false);
@@ -257,38 +171,23 @@ class AudioDiskstream : public Stateful, public sigc::trackable
protected:
friend class AudioTrack;
- void prepare ();
int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input);
bool commit (jack_nframes_t nframes);
- void recover (); /* called if commit will not be called, but process was */
private:
/* use unref() to destroy a diskstream */
-
~AudioDiskstream();
- enum TransitionType {
- CaptureStart = 0,
- CaptureEnd
- };
-
- struct CaptureTransition {
-
- TransitionType type;
- // the start or end file frame pos
- jack_nframes_t capture_val;
- };
-
struct ChannelInfo {
Sample *playback_wrap_buffer;
Sample *capture_wrap_buffer;
Sample *speed_buffer;
- float peak_power;
+ float peak_power;
- AudioFileSource *fades_source;
+ AudioFileSource *fades_source;
AudioFileSource *write_source;
Port *source;
@@ -310,129 +209,30 @@ class AudioDiskstream : public Stateful, public sigc::trackable
jack_nframes_t curr_capture_cnt;
};
- typedef vector<ChannelInfo> ChannelList;
-
-
- string _name;
- ARDOUR::Session& _session;
- ARDOUR::IO* _io;
- ChannelList channels;
- uint32_t _n_channels;
- id_t _id;
-
- mutable gint _record_enabled;
- AudioPlaylist* _playlist;
- double _visible_speed;
- double _actual_speed;
- /* items needed for speed change logic */
- bool _buffer_reallocation_required;
- bool _seek_required;
+ /* The two central butler operations */
+ int do_flush (Session::RunContext context, bool force = false);
+ int do_refill () { return _do_refill(_mixdown_buffer, _gain_buffer, _conversion_buffer); }
- bool force_refill;
- jack_nframes_t capture_start_frame;
- jack_nframes_t capture_captured;
- bool was_recording;
- jack_nframes_t adjust_capture_position;
- jack_nframes_t _capture_offset;
- jack_nframes_t _roll_delay;
- jack_nframes_t first_recordable_frame;
- jack_nframes_t last_recordable_frame;
- int last_possibly_recording;
- AlignStyle _alignment_style;
- bool _scrubbing;
- bool _slaved;
- bool _processed;
- Location* loop_location;
- jack_nframes_t overwrite_frame;
- off_t overwrite_offset;
- bool pending_overwrite;
- bool overwrite_queued;
- IOChange input_change_pending;
- jack_nframes_t wrap_buffer_size;
- jack_nframes_t speed_buffer_size;
-
- uint64_t last_phase;
- uint64_t phi;
-
- jack_nframes_t file_frame;
- jack_nframes_t playback_sample;
- jack_nframes_t playback_distance;
-
- uint32_t _read_data_count;
- uint32_t _write_data_count;
-
- bool in_set_state;
- AlignStyle _persistent_alignment_style;
- bool first_input_change;
-
- Glib::Mutex state_lock;
+ int do_refill_with_alloc();
- jack_nframes_t scrub_start;
- jack_nframes_t scrub_buffer_size;
- jack_nframes_t scrub_offset;
- uint32_t _refcnt;
-
- sigc::connection ports_created_c;
- sigc::connection plmod_connection;
- sigc::connection plstate_connection;
- sigc::connection plgone_connection;
-
- /* the two central butler operations */
-
- int do_flush (char * workbuf, bool force = false);
- int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
-
- int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
- ChannelInfo& channel_info, int channel, bool reversed);
-
- uint32_t i_am_the_modifier;
-
- /* XXX fix this redundancy ... */
-
- void playlist_changed (Change);
- void playlist_modified ();
- void playlist_deleted (Playlist*);
- void session_controls_changed (Session::ControlType);
+ int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf,
+ jack_nframes_t& start, jack_nframes_t cnt,
+ ChannelInfo& channel_info, int channel, bool reversed);
void finish_capture (bool rec_monitors_input);
- void clean_up_capture (struct tm&, time_t, bool abort);
void transport_stopped (struct tm&, time_t, bool abort);
- struct CaptureInfo {
- uint32_t start;
- uint32_t frames;
- };
-
- vector<CaptureInfo*> capture_info;
- Glib::Mutex capture_info_lock;
-
- void init (Flag);
+ void init (Diskstream::Flag);
void init_channel (ChannelInfo &chan);
void destroy_channel (ChannelInfo &chan);
- static jack_nframes_t disk_io_chunk_frames;
-
int use_new_write_source (uint32_t n=0);
- int use_new_fade_source (uint32_t n=0);
int find_and_use_playlist (const string&);
void allocate_temporary_buffers ();
- unsigned char _flags;
-
- int create_input_port ();
- int connect_input_port ();
- int seek_unlocked (jack_nframes_t which_sample);
-
- int ports_created ();
-
- bool realtime_set_speed (double, bool global_change);
- void non_realtime_set_speed ();
-
- std::list<Region*> _last_capture_regions;
- std::vector<AudioFileSource*> capturing_sources;
int use_pending_capture_data (XMLNode& node);
void get_input_sources ();
@@ -440,8 +240,29 @@ class AudioDiskstream : public Stateful, public sigc::trackable
void set_align_style_from_io();
void setup_destructive_playlist ();
void use_destructive_playlist ();
+
+ void engage_record_enable ();
+ void disengage_record_enable ();
+
+ // Working buffers for do_refill (butler thread)
+ static void allocate_working_buffers();
+ static void free_working_buffers();
+
+ static size_t _working_buffers_size;
+ static Sample* _mixdown_buffer;
+ static gain_t* _gain_buffer;
+ static char* _conversion_buffer;
+
+ // Uh, /really/ private? (death to friend classes)
+ int _do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
+
+
+ std::vector<AudioFileSource*> capturing_sources;
+
+ typedef vector<ChannelInfo> ChannelList;
+ ChannelList channels;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
-#endif /* __ardour_diskstream_h__ */
+#endif /* __ardour_audio_diskstream_h__ */
diff --git a/libs/ardour/ardour/audio_library.h b/libs/ardour/ardour/audio_library.h
index 2f9e84551b..f5ac6da654 100644
--- a/libs/ardour/ardour/audio_library.h
+++ b/libs/ardour/ardour/audio_library.h
@@ -28,18 +28,25 @@
#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+
using std::vector;
using std::string;
using std::map;
namespace ARDOUR {
-class AudioLibrary
+class AudioLibrary : public Stateful
{
public:
AudioLibrary ();
~AudioLibrary ();
+ static string state_node_name;
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
void set_paths (vector<string> paths);
vector<string> get_paths ();
void scan_paths ();
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 1c17cbc859..15b99297c8 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -21,7 +21,7 @@
#ifndef __ardour_audio_track_h__
#define __ardour_audio_track_h__
-#include <ardour/route.h>
+#include <ardour/track.h>
namespace ARDOUR {
@@ -30,79 +30,38 @@ class AudioDiskstream;
class AudioPlaylist;
class RouteGroup;
-class AudioTrack : public Route
+class AudioTrack : public Track
{
public:
AudioTrack (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal);
AudioTrack (Session&, const XMLNode&);
~AudioTrack ();
-
- int set_name (string str, void *src);
-
- int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
- int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
- int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
- jack_nframes_t offset, bool can_record, bool rec_monitors_input);
-
- void toggle_monitor_input ();
+ int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input);
+
+ int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input);
+
+ int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool can_record, bool rec_monitors_input);
- bool can_record() const { return true; }
- void set_record_enable (bool yn, void *src);
+ AudioDiskstream& audio_diskstream() const;
- AudioDiskstream& disk_stream() const { return *diskstream; }
- int set_diskstream (AudioDiskstream&, void *);
int use_diskstream (string name);
- int use_diskstream (id_t id);
-
- TrackMode mode() const { return _mode; }
- void set_mode (TrackMode m);
- sigc::signal<void> ModeChanged;
-
- jack_nframes_t update_total_latency();
- void set_latency_delay (jack_nframes_t);
+ int use_diskstream (const PBD::ID& id);
int export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame);
- sigc::signal<void,void*> diskstream_changed;
-
- enum FreezeState {
- NoFreeze,
- Frozen,
- UnFrozen
- };
-
- FreezeState freeze_state() const;
-
- sigc::signal<void> FreezeChange;
-
void freeze (InterThreadInfo&);
void unfreeze ();
void bounce (InterThreadInfo&);
void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&);
- XMLNode& get_state();
- XMLNode& get_template();
int set_state(const XMLNode& node);
- MIDI::Controllable& midi_rec_enable_control() {
- return _midi_rec_enable_control;
- }
-
- void reset_midi_control (MIDI::Port*, bool);
- void send_all_midi_feedback ();
-
- bool record_enabled() const;
- void set_meter_point (MeterPoint, void* src);
-
protected:
- AudioDiskstream *diskstream;
- MeterPoint _saved_meter_point;
- TrackMode _mode;
-
XMLNode& state (bool full);
void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
@@ -110,62 +69,14 @@ class AudioTrack : public Route
bool meter);
uint32_t n_process_buffers ();
-
+
private:
- struct FreezeRecordInsertInfo {
- FreezeRecordInsertInfo(XMLNode& st)
- : state (st), insert (0) {}
-
- XMLNode state;
- Insert* insert;
- id_t id;
- UndoAction memento;
- };
-
- struct FreezeRecord {
- FreezeRecord() {
- playlist = 0;
- have_mementos = false;
- }
-
- ~FreezeRecord();
-
- AudioPlaylist* playlist;
- vector<FreezeRecordInsertInfo*> insert_info;
- bool have_mementos;
- FreezeState state;
- };
-
- FreezeRecord _freeze_record;
- XMLNode* pending_state;
-
- void diskstream_record_enable_changed (void *src);
- void diskstream_input_channel_changed (void *src);
-
- void input_change_handler (void *src);
-
- sigc::connection recenable_connection;
- sigc::connection ic_connection;
-
- int deprecated_use_diskstream_connections ();
+ int set_diskstream (AudioDiskstream&, void *);
+ int deprecated_use_diskstream_connections ();
void set_state_part_two ();
void set_state_part_three ();
-
- struct MIDIRecEnableControl : public MIDI::Controllable {
- MIDIRecEnableControl (AudioTrack&, MIDI::Port *);
- void set_value (float);
- void send_feedback (bool);
- MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false);
- AudioTrack& track;
- bool setting;
- bool last_written;
- };
-
- MIDIRecEnableControl _midi_rec_enable_control;
-
- bool _destructive;
};
-}; /* namespace ARDOUR*/
+} // namespace ARDOUR
#endif /* __ardour_audio_track_h__ */
diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h
new file mode 100644
index 0000000000..f437ae053a
--- /dev/null
+++ b/libs/ardour/ardour/audio_unit.h
@@ -0,0 +1,111 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Taybin Rutkin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_audio_unit_h__
+#define __ardour_audio_unit_h__
+
+#include <stdint.h>
+
+#include <list>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <ardour/plugin.h>
+
+#include <boost/shared_ptr.hpp>
+
+class CAComponent;
+class CAAudioUnit;
+class CAComponentDescription;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Session;
+
+class AUPlugin : public ARDOUR::Plugin
+{
+ public:
+ AUPlugin (AudioEngine& engine, Session& session, CAComponent* comp);
+ virtual ~AUPlugin ();
+
+ uint32_t unique_id () const;
+ const char * label () const;
+ const char * name () const { return _info->name.c_str(); }
+ const char * maker () const;
+ uint32_t parameter_count () const;
+ float default_value (uint32_t port);
+ jack_nframes_t latency () const;
+ void set_parameter (uint32_t which, float val);
+ float get_parameter (uint32_t which) const;
+
+ int get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const;
+ uint32_t nth_parameter (uint32_t which, bool& ok) const;
+ void activate ();
+ void deactivate ();
+ void set_block_size (jack_nframes_t nframes);
+
+ int connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset);
+ std::set<uint32_t> automatable() const;
+ void store_state (ARDOUR::PluginState&);
+ void restore_state (ARDOUR::PluginState&);
+ string describe_parameter (uint32_t);
+ string state_node_name () const { return "audiounit"; }
+ void print_parameter (uint32_t, char*, uint32_t len) const;
+
+ bool parameter_is_audio (uint32_t) const;
+ bool parameter_is_control (uint32_t) const;
+ bool parameter_is_input (uint32_t) const;
+ bool parameter_is_output (uint32_t) const;
+
+ XMLNode& get_state();
+ int set_state(const XMLNode& node);
+
+ bool save_preset (string name);
+ bool load_preset (const string preset_label);
+ std::vector<std::string> get_presets ();
+
+ bool has_editor () const;
+
+ private:
+ CAComponent* comp;
+ CAAudioUnit* unit;
+};
+
+class AUPluginInfo : public PluginInfo {
+ public:
+ AUPluginInfo () { };
+ ~AUPluginInfo ();
+
+ CAComponentDescription* desc;
+
+ static PluginInfoList discover ();
+ PluginPtr load (Session& session);
+
+ private:
+ static std::string get_name (CAComponentDescription&);
+};
+
+typedef boost::shared_ptr<AUPluginInfo> AUPluginInfoPtr;
+
+} // namespace ARDOUR
+
+#endif // __ardour_audio_unit_h__
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 50bf7dddcc..e7500fc7a2 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -34,6 +34,8 @@
#include <ardour/ardour.h>
#include <jack/jack.h>
#include <jack/transport.h>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
namespace ARDOUR {
@@ -104,8 +106,8 @@ class AudioEngine : public sigc::trackable
virtual const char *what() const throw() { return "could not connect to engine backend"; }
};
- Port *register_audio_input_port (const std::string& portname);
- Port *register_audio_output_port (const std::string& portname);
+ Port *register_input_port (DataType type, const std::string& portname);
+ Port *register_output_port (DataType type, const std::string& portname);
int unregister_port (Port *);
int connect (const std::string& source, const std::string& destination);
@@ -243,6 +245,6 @@ class AudioEngine : public sigc::trackable
mutable gint m_meter_exit;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_audioengine_h__ */
diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h
index 36251c07ff..eb3fd750d4 100644
--- a/libs/ardour/ardour/audiofilesource.h
+++ b/libs/ardour/ardour/audiofilesource.h
@@ -42,7 +42,8 @@ class AudioFileSource : public AudioSource {
Removable = 0x8,
RemovableIfEmpty = 0x10,
RemoveAtDestroy = 0x20,
- NoPeakFile = 0x40
+ NoPeakFile = 0x40,
+ Destructive = 0x80
};
virtual ~AudioFileSource ();
@@ -95,7 +96,7 @@ class AudioFileSource : public AudioSource {
static void set_bwf_serial_number (int);
static void set_search_path (string);
- static void set_header_position_offset (jack_nframes_t offset, bool negative);
+ static void set_header_position_offset (jack_nframes_t offset );
static sigc::signal<void> HeaderPositionOffsetChanged;
@@ -107,7 +108,7 @@ class AudioFileSource : public AudioSource {
to cause issues.
*/
- void handle_header_position_change ();
+ virtual void handle_header_position_change () {}
protected:
@@ -141,7 +142,6 @@ class AudioFileSource : public AudioSource {
static char bwf_serial_number[13];
static uint64_t header_position_offset;
- static bool header_position_negative;
virtual void set_timeline_position (jack_nframes_t pos);
virtual void set_header_timeline_position () = 0;
@@ -151,7 +151,7 @@ class AudioFileSource : public AudioSource {
bool writable() const { return _flags & Writable; }
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_audiofilesource_h__ */
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index 1b60cf185d..5a77067f8f 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -77,9 +77,6 @@ class AudioPlaylist : public ARDOUR::Playlist
bool destroy_region (Region*);
- void get_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
- void get_region_list_equivalent_regions (const AudioRegion&, std::vector<AudioRegion*>&);
-
void drop_all_states ();
protected:
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 009aa4b5b0..683e946713 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -27,8 +27,9 @@
#include <pbd/undo.h>
#include <ardour/ardour.h>
-#include <ardour/gain.h>
#include <ardour/region.h>
+#include <ardour/gain.h>
+#include <ardour/logcurve.h>
#include <ardour/export.h>
class XMLNode;
@@ -43,14 +44,14 @@ class AudioSource;
struct AudioRegionState : public RegionState
{
- AudioRegionState (std::string why);
-
- Curve _fade_in;
- Curve _fade_out;
- Curve _envelope;
- gain_t _scale_amplitude;
- uint32_t _fade_in_disabled;
- uint32_t _fade_out_disabled;
+ AudioRegionState (std::string why);
+
+ Curve _fade_in;
+ Curve _fade_out;
+ Curve _envelope;
+ gain_t _scale_amplitude;
+ uint32_t _fade_in_disabled;
+ uint32_t _fade_out_disabled;
};
class AudioRegion : public Region
@@ -75,11 +76,7 @@ class AudioRegion : public Region
AudioRegion (SourceList &, const XMLNode&);
~AudioRegion();
- bool region_list_equivalent (const AudioRegion&) const ;
- bool source_equivalent (const AudioRegion&) const;
- bool equivalent (const AudioRegion&) const;
- bool size_equivalent (const AudioRegion&) const;
- bool overlap_equivalent (const AudioRegion&) const;
+ bool source_equivalent (const Region&) const;
bool speed_mismatch (float) const;
@@ -96,7 +93,7 @@ class AudioRegion : public Region
vector<string> master_source_names();
bool envelope_active () const { return _flags & Region::EnvelopeActive; }
- bool fade_in_active () const { return _flags & Region::FadeIn; }
+ bool fade_in_active () const { return _flags & Region::FadeIn; }
bool fade_out_active () const { return _flags & Region::FadeOut; }
bool captured() const { return !(_flags & (Region::Flag (Region::Import|Region::External))); }
@@ -104,20 +101,21 @@ class AudioRegion : public Region
Curve& fade_out() { return _fade_out; }
Curve& envelope() { return _envelope; }
- jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const;
-
- virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
- float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
- uint32_t chan_n = 0,
- jack_nframes_t read_frames = 0,
- jack_nframes_t skip_frames = 0) const;
+ jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks,
+ jack_nframes_t offset, jack_nframes_t cnt,
+ uint32_t chan_n=0, double samples_per_unit= 1.0) const;
- jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer,
- float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
+ virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buf,
+ float *gain_buf, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
+ uint32_t chan_n = 0,
+ jack_nframes_t read_frames = 0,
+ jack_nframes_t skip_frames = 0) const;
+ jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buf,
+ float *gain_buf, char * workbuf,
+ jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
XMLNode& state (bool);
- XMLNode& get_state ();
int set_state (const XMLNode&);
static void set_default_fade (float steepness, jack_nframes_t len);
@@ -127,8 +125,7 @@ class AudioRegion : public Region
Fast,
Slow,
LogA,
- LogB,
-
+ LogB
};
void set_fade_in_active (bool yn);
@@ -145,10 +142,6 @@ class AudioRegion : public Region
int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const;
- uint32_t read_data_count() const { return _read_data_count; }
-
- ARDOUR::Playlist* playlist() const { return _playlist; }
-
UndoAction get_memento() const;
/* filter */
@@ -172,20 +165,6 @@ class AudioRegion : public Region
friend class Playlist;
private:
- SourceList sources;
- SourceList master_sources; /* used when timefx are applied, so
- we can always use the original
- source.
- */
- mutable Curve _fade_in;
- FadeShape _fade_in_shape;
- mutable Curve _fade_out;
- FadeShape _fade_out_shape;
- mutable Curve _envelope;
- gain_t _scale_amplitude;
- uint32_t _fade_in_disabled;
- uint32_t _fade_out_disabled;
-
void set_default_fades ();
void set_default_fade_in ();
void set_default_fade_out ();
@@ -197,10 +176,6 @@ class AudioRegion : public Region
void recompute_gain_at_end ();
void recompute_gain_at_start ();
- bool copied() const { return _flags & Copied; }
- void maybe_uncopy ();
- void rename_after_first_edit ();
-
jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n = 0,
@@ -217,6 +192,21 @@ class AudioRegion : public Region
void envelope_changed (Change);
void source_deleted (Source*);
+
+
+ SourceList sources;
+
+ /** Used when timefx are applied, so we can always use the original source. */
+ SourceList master_sources;
+
+ mutable Curve _fade_in;
+ FadeShape _fade_in_shape;
+ mutable Curve _fade_out;
+ FadeShape _fade_out_shape;
+ mutable Curve _envelope;
+ gain_t _scale_amplitude;
+ uint32_t _fade_in_disabled;
+ uint32_t _fade_out_disabled;
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/audiosource.h b/libs/ardour/ardour/audiosource.h
index 1dcf5b42f3..35158a24e7 100644
--- a/libs/ardour/ardour/audiosource.h
+++ b/libs/ardour/ardour/audiosource.h
@@ -33,7 +33,7 @@
#include <ardour/source.h>
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
#include <pbd/xml++.h>
using std::list;
@@ -51,6 +51,13 @@ class AudioSource : public Source
AudioSource (const XMLNode&);
virtual ~AudioSource ();
+ /* one could argue that this should belong to Source, but other data types
+ generally do not come with a model of "offset along an audio timeline"
+ so its here in AudioSource for now.
+ */
+
+ virtual jack_nframes_t natural_position() const { return 0; }
+
/* returns the number of items in this `audio_source' */
virtual jack_nframes_t length() const {
diff --git a/libs/ardour/ardour/buffer.h b/libs/ardour/ardour/buffer.h
new file mode 100644
index 0000000000..8a88802ecb
--- /dev/null
+++ b/libs/ardour/ardour/buffer.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_buffer_h__
+#define __ardour_buffer_h__
+
+#define _XOPEN_SOURCE 600
+#include <cstdlib> // for posix_memalign
+#include <cassert>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
+
+namespace ARDOUR {
+
+
+/* Yes, this is a bit of a mess right now. I'll clean it up when everything
+ * using it works out.. */
+
+
+/** A buffer of recordable/playable data.
+ *
+ * This is a datatype-agnostic base class for all buffers (there are no
+ * methods to actually access the data). This provides a way for code that
+ * doesn't care about the data type to still deal with buffers (which is
+ * why the base class can't be a template).
+ *
+ * To actually read/write buffer contents, use the appropriate derived class.
+ */
+class Buffer
+{
+public:
+ Buffer(DataType type, size_t capacity)
+ : _type(type), _capacity(capacity), _size(0)
+ {}
+
+ virtual ~Buffer() {}
+
+ /** Maximum capacity of buffer.
+ * Note in some cases the entire buffer may not contain valid data, use size. */
+ size_t capacity() const { return _capacity; }
+
+ /** Amount of valid data in buffer. Use this over capacity almost always. */
+ size_t size() const { return _size; }
+
+ /** Type of this buffer.
+ * Based on this you can static cast a Buffer* to the desired type. */
+ DataType type() const { return _type; }
+
+protected:
+ DataType _type;
+ size_t _capacity;
+ size_t _size;
+};
+
+
+/* Inside every class with a type in it's name is a template waiting to get out... */
+
+
+/** Buffer containing 32-bit floating point (audio) data. */
+class AudioBuffer : public Buffer
+{
+public:
+ AudioBuffer(size_t capacity)
+ : Buffer(DataType::AUDIO, capacity)
+ , _data(NULL)
+ {
+ _size = capacity; // For audio buffers, size = capacity (always)
+#ifdef NO_POSIX_MEMALIGN
+ _data = (Sample *) malloc(sizeof(Sample) * capacity);
+#else
+ posix_memalign((void**)_data, 16, sizeof(Sample) * capacity);
+#endif
+ assert(_data);
+ memset(_data, 0, sizeof(Sample) * capacity);
+ }
+
+ const Sample* data() const { return _data; }
+ Sample* data() { return _data; }
+
+private:
+ // These are undefined (prevent copies)
+ AudioBuffer(const AudioBuffer& copy);
+ AudioBuffer& operator=(const AudioBuffer& copy);
+
+ Sample* _data; ///< Actual buffer contents
+};
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_buffer_h__
diff --git a/libs/ardour/ardour/configuration.h b/libs/ardour/ardour/configuration.h
index 60b5e8a2c3..dd689e9a2d 100644
--- a/libs/ardour/ardour/configuration.h
+++ b/libs/ardour/ardour/configuration.h
@@ -27,8 +27,9 @@
#include <sys/types.h>
#include <string>
+#include <pbd/stateful.h>
+
#include <ardour/types.h>
-#include <ardour/stateful.h>
#include <ardour/utils.h>
#include <ardour/configuration_variable.h>
@@ -98,6 +99,6 @@ class Configuration : public Stateful
extern Configuration *Config;
extern gain_t speed_quietning; /* see comment in configuration.cc */
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_configuration_h__ */
diff --git a/libs/ardour/ardour/connection.h b/libs/ardour/ardour/connection.h
index 899bffc06a..da4d4e2684 100644
--- a/libs/ardour/ardour/connection.h
+++ b/libs/ardour/ardour/connection.h
@@ -25,7 +25,7 @@
#include <string>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
using std::vector;
using std::string;
diff --git a/libs/ardour/ardour/control_protocol_manager.h b/libs/ardour/ardour/control_protocol_manager.h
index 03b21a299c..8eda7a4555 100644
--- a/libs/ardour/ardour/control_protocol_manager.h
+++ b/libs/ardour/ardour/control_protocol_manager.h
@@ -8,7 +8,7 @@
#include <glibmm/thread.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
namespace ARDOUR {
@@ -23,6 +23,7 @@ struct ControlProtocolInfo {
std::string path;
bool requested;
bool mandatory;
+ XMLNode* state;
};
class ControlProtocolManager : public sigc::trackable, public Stateful
diff --git a/libs/ardour/ardour/curve.h b/libs/ardour/ardour/curve.h
index ede060e1cb..7f8a43cfe1 100644
--- a/libs/ardour/ardour/curve.h
+++ b/libs/ardour/ardour/curve.h
@@ -76,7 +76,7 @@ class Curve : public AutomationList
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
extern "C" {
void curve_get_vector_from_c (void *arg, double, double, float*, int32_t);
diff --git a/libs/ardour/ardour/data_type.h b/libs/ardour/ardour/data_type.h
new file mode 100644
index 0000000000..d49ed108cd
--- /dev/null
+++ b/libs/ardour/ardour/data_type.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 2 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_data_type_h__
+#define __ardour_data_type_h__
+
+#include <jack/jack.h>
+
+namespace ARDOUR {
+
+class DataType
+{
+public:
+ enum Symbol {
+ NIL = 0,
+ AUDIO,
+ MIDI
+ };
+
+ DataType(const Symbol& symbol)
+ : _symbol(symbol)
+ {}
+
+ /** Construct from a string (Used for loading from XML) */
+ DataType(const string& str) {
+ if (str == "audio")
+ _symbol = AUDIO;
+ //else if (str == "midi")
+ // _symbol = MIDI;
+ else
+ _symbol = NIL;
+ }
+
+ bool operator==(const Symbol symbol) { return _symbol == symbol; }
+ bool operator!=(const Symbol symbol) { return _symbol != symbol; }
+
+ /** Get the Jack type this DataType corresponds to */
+ const char* to_jack_type() {
+ switch (_symbol) {
+ case AUDIO: return JACK_DEFAULT_AUDIO_TYPE;
+ //case MIDI: return JACK_DEFAULT_MIDI_TYPE;
+ default: return "";
+ }
+ }
+
+ /** Inverse of the from-string constructor */
+ const char* to_string() {
+ switch (_symbol) {
+ case AUDIO: return "audio";
+ //case MIDI: return "midi";
+ default: return "unknown"; // reeeally shouldn't ever happen
+ }
+ }
+
+private:
+ Symbol _symbol;
+};
+
+
+
+} // namespace ARDOUR
+
+#endif // __ardour_data_type_h__
+
diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h
index 2d10528ac8..5b773898c3 100644
--- a/libs/ardour/ardour/destructive_filesource.h
+++ b/libs/ardour/ardour/destructive_filesource.h
@@ -34,6 +34,8 @@ class DestructiveFileSource : public SndFileSource {
DestructiveFileSource (std::string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate,
Flag flags = AudioFileSource::Flag (AudioFileSource::Writable));
+ DestructiveFileSource (std::string path, Flag flags);
+
DestructiveFileSource (const XMLNode&);
~DestructiveFileSource ();
@@ -49,6 +51,8 @@ class DestructiveFileSource : public SndFileSource {
protected:
jack_nframes_t write_unlocked (Sample *src, jack_nframes_t cnt, char * workbuf);
+ virtual void handle_header_position_change ();
+
private:
static jack_nframes_t xfade_frames;
static gain_t* out_coefficient;
@@ -60,6 +64,7 @@ class DestructiveFileSource : public SndFileSource {
jack_nframes_t file_pos; // unit is frames
Sample* xfade_buf;
+ void init ();
jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf);
void set_timeline_position (jack_nframes_t);
};
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
new file mode 100644
index 0000000000..ebce516d8b
--- /dev/null
+++ b/libs/ardour/ardour/diskstream.h
@@ -0,0 +1,319 @@
+/*
+ Copyright (C) 2000-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: diskstream.h 579 2006-06-12 19:56:37Z essej $
+*/
+
+#ifndef __ardour_diskstream_h__
+#define __ardour_diskstream_h__
+
+#include <sigc++/signal.h>
+
+#include <cmath>
+#include <string>
+#include <queue>
+#include <map>
+#include <vector>
+
+#include <time.h>
+
+#include <pbd/fastlog.h>
+#include <pbd/ringbufferNPT.h>
+#include <pbd/stateful.h>
+
+#include <ardour/ardour.h>
+#include <ardour/configuration.h>
+#include <ardour/session.h>
+#include <ardour/route_group.h>
+#include <ardour/route.h>
+#include <ardour/port.h>
+#include <ardour/utils.h>
+
+
+struct tm;
+
+namespace ARDOUR {
+
+class AudioEngine;
+class Send;
+class Session;
+class Playlist;
+class IO;
+
+class Diskstream : public Stateful, public sigc::trackable
+{
+ public:
+ enum Flag {
+ Recordable = 0x1,
+ Hidden = 0x2,
+ Destructive = 0x4
+ };
+
+ string name () const { return _name; }
+ virtual int set_name (string str);
+
+ ARDOUR::IO* io() const { return _io; }
+ void set_io (ARDOUR::IO& io);
+
+ virtual Diskstream& ref() { _refcnt++; return *this; }
+ void unref() { if (_refcnt) _refcnt--; if (_refcnt == 0) delete this; }
+ uint32_t refcnt() const { return _refcnt; }
+
+ virtual float playback_buffer_load() const = 0;
+ virtual float capture_buffer_load() const = 0;
+
+ void set_flag (Flag f) { _flags |= f; }
+ void unset_flag (Flag f) { _flags &= ~f; }
+
+ AlignStyle alignment_style() const { return _alignment_style; }
+ void set_align_style (AlignStyle);
+ void set_persistent_align_style (AlignStyle a) { _persistent_alignment_style = a; }
+
+ jack_nframes_t roll_delay() const { return _roll_delay; }
+ void set_roll_delay (jack_nframes_t);
+
+ bool record_enabled() const { return g_atomic_int_get (&_record_enabled); }
+ virtual void set_record_enabled (bool yn) = 0;
+
+ bool destructive() const { return _flags & Destructive; }
+ virtual void set_destructive (bool yn);
+
+ const PBD::ID& id() const { return _id; }
+ bool hidden() const { return _flags & Hidden; }
+ bool recordable() const { return _flags & Recordable; }
+ bool reversed() const { return _actual_speed < 0.0f; }
+ double speed() const { return _visible_speed; }
+
+ virtual void punch_in() {}
+ virtual void punch_out() {}
+
+ void set_speed (double);
+ void non_realtime_set_speed ();
+
+ Playlist* playlist () { return _playlist; }
+
+ virtual int use_playlist (Playlist *);
+ virtual int use_new_playlist () = 0;
+ virtual int use_copy_playlist () = 0;
+
+ jack_nframes_t current_capture_start() const { return capture_start_frame; }
+ jack_nframes_t current_capture_end() const { return capture_start_frame + capture_captured; }
+ jack_nframes_t get_capture_start_frame (uint32_t n=0);
+ jack_nframes_t get_captured_frames (uint32_t n=0);
+
+ uint32_t n_channels() { return _n_channels; }
+
+ static jack_nframes_t disk_io_frames() { return disk_io_chunk_frames; }
+ static void set_disk_io_chunk_frames (uint32_t n) { disk_io_chunk_frames = n; }
+
+ /* Stateful */
+ virtual XMLNode& get_state(void) = 0;
+ virtual int set_state(const XMLNode& node) = 0;
+
+ // FIXME: makes sense for all diskstream types?
+ virtual void monitor_input (bool) {}
+
+ jack_nframes_t capture_offset() const { return _capture_offset; }
+ virtual void set_capture_offset ();
+
+ bool slaved() const { return _slaved; }
+ void set_slaved(bool yn) { _slaved = yn; }
+
+ int set_loop (Location *loc);
+
+ std::list<Region*>& last_capture_regions () { return _last_capture_regions; }
+
+ void handle_input_change (IOChange, void *src);
+
+ sigc::signal<void> RecordEnableChanged;
+ sigc::signal<void> SpeedChanged;
+ sigc::signal<void> ReverseChanged;
+ sigc::signal<void> PlaylistChanged;
+ sigc::signal<void> AlignmentStyleChanged;
+ sigc::signal<void,Location *> LoopSet;
+
+ static sigc::signal<void> DiskOverrun;
+ static sigc::signal<void> DiskUnderrun;
+ static sigc::signal<void,Diskstream*> DiskstreamCreated; // XXX use a ref with sigc2
+ static sigc::signal<void,list<Source*>*> DeleteSources;
+
+ protected:
+ friend class Session;
+
+ Diskstream (Session &, const string& name, Flag f = Recordable);
+ Diskstream (Session &, const XMLNode&);
+
+ /* the Session is the only point of access for these because they require
+ * that the Session is "inactive" while they are called.
+ */
+
+ virtual void set_pending_overwrite (bool) = 0;
+ virtual int overwrite_existing_buffers () = 0;
+ virtual void set_block_size (jack_nframes_t) = 0;
+ virtual int internal_playback_seek (jack_nframes_t distance) = 0;
+ virtual int can_internal_playback_seek (jack_nframes_t distance) = 0;
+ virtual int rename_write_sources () = 0;
+ virtual void reset_write_sources (bool, bool force = false) = 0;
+ virtual void non_realtime_input_change () = 0;
+
+ uint32_t read_data_count() const { return _read_data_count; }
+ uint32_t write_data_count() const { return _write_data_count; }
+
+ protected:
+ friend class Auditioner;
+ virtual int seek (jack_nframes_t which_sample, bool complete_refill = false) = 0;
+
+ protected:
+ friend class Track;
+
+ virtual void prepare ();
+ virtual int process (jack_nframes_t transport_frame, jack_nframes_t nframes, jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+ virtual bool commit (jack_nframes_t nframes) = 0;
+ virtual void recover (); /* called if commit will not be called, but process was */
+
+ //private:
+
+ /** Use unref() to destroy a diskstream */
+ virtual ~Diskstream();
+
+ enum TransitionType {
+ CaptureStart = 0,
+ CaptureEnd
+ };
+
+ struct CaptureTransition {
+ TransitionType type;
+ jack_nframes_t capture_val; ///< The start or end file frame position
+ };
+
+ /* The two central butler operations */
+ virtual int do_flush (Session::RunContext context, bool force = false) = 0;
+ virtual int do_refill () = 0;
+
+ /** For non-butler contexts (allocates temporary working buffers) */
+ virtual int do_refill_with_alloc() = 0;
+
+
+ /* XXX fix this redundancy ... */
+
+ virtual void playlist_changed (Change);
+ virtual void playlist_modified ();
+ virtual void playlist_deleted (Playlist*);
+
+ virtual void finish_capture (bool rec_monitors_input) = 0;
+ virtual void transport_stopped (struct tm&, time_t, bool abort) = 0;
+
+ struct CaptureInfo {
+ uint32_t start;
+ uint32_t frames;
+ };
+
+ virtual void init (Flag);
+
+ virtual int use_new_write_source (uint32_t n=0) = 0;
+
+ virtual int find_and_use_playlist (const string&) = 0;
+
+ virtual void allocate_temporary_buffers () = 0;
+
+ virtual bool realtime_set_speed (double, bool global_change);
+
+ std::list<Region*> _last_capture_regions;
+ virtual int use_pending_capture_data (XMLNode& node) = 0;
+
+ virtual void get_input_sources () = 0;
+ virtual void check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record) = 0;
+ virtual void set_align_style_from_io() {}
+ virtual void setup_destructive_playlist () = 0;
+ virtual void use_destructive_playlist () = 0;
+
+ static jack_nframes_t disk_io_chunk_frames;
+ vector<CaptureInfo*> capture_info;
+ Glib::Mutex capture_info_lock;
+
+ uint32_t i_am_the_modifier;
+
+ string _name;
+ ARDOUR::Session& _session;
+ ARDOUR::IO* _io;
+ uint32_t _n_channels;
+ PBD::ID _id;
+ Playlist* _playlist;
+
+ mutable gint _record_enabled;
+ double _visible_speed;
+ double _actual_speed;
+ /* items needed for speed change logic */
+ bool _buffer_reallocation_required;
+ bool _seek_required;
+
+ bool force_refill;
+ jack_nframes_t capture_start_frame;
+ jack_nframes_t capture_captured;
+ bool was_recording;
+ jack_nframes_t adjust_capture_position;
+ jack_nframes_t _capture_offset;
+ jack_nframes_t _roll_delay;
+ jack_nframes_t first_recordable_frame;
+ jack_nframes_t last_recordable_frame;
+ int last_possibly_recording;
+ AlignStyle _alignment_style;
+ bool _scrubbing;
+ bool _slaved;
+ bool _processed;
+ Location* loop_location;
+ jack_nframes_t overwrite_frame;
+ off_t overwrite_offset;
+ bool pending_overwrite;
+ bool overwrite_queued;
+ IOChange input_change_pending;
+ jack_nframes_t wrap_buffer_size;
+ jack_nframes_t speed_buffer_size;
+
+ uint64_t last_phase;
+ uint64_t phi;
+
+ jack_nframes_t file_frame;
+ jack_nframes_t playback_sample;
+ jack_nframes_t playback_distance;
+
+ uint32_t _read_data_count;
+ uint32_t _write_data_count;
+
+ bool in_set_state;
+ AlignStyle _persistent_alignment_style;
+ bool first_input_change;
+
+ Glib::Mutex state_lock;
+
+ jack_nframes_t scrub_start;
+ jack_nframes_t scrub_buffer_size;
+ jack_nframes_t scrub_offset;
+
+ uint32_t _refcnt;
+
+ sigc::connection ports_created_c;
+ sigc::connection plmod_connection;
+ sigc::connection plstate_connection;
+ sigc::connection plgone_connection;
+
+ unsigned char _flags;
+};
+
+}; /* namespace ARDOUR */
+
+#endif /* __ardour_diskstream_h__ */
diff --git a/libs/ardour/ardour/export.h b/libs/ardour/ardour/export.h
index 9a6da1592b..075464767e 100644
--- a/libs/ardour/ardour/export.h
+++ b/libs/ardour/ardour/export.h
@@ -83,6 +83,6 @@ namespace ARDOUR
int status;
};
-};
+} // namespace ARDOUR
#endif /* __ardour_export_h__ */
diff --git a/libs/ardour/ardour/insert.h b/libs/ardour/ardour/insert.h
index 803e16497d..a4c4439942 100644
--- a/libs/ardour/ardour/insert.h
+++ b/libs/ardour/ardour/insert.h
@@ -98,7 +98,7 @@ struct PluginInsertState : public RedirectState
class PluginInsert : public Insert
{
public:
- PluginInsert (Session&, Plugin&, Placement);
+ PluginInsert (Session&, boost::shared_ptr<Plugin>, Placement);
PluginInsert (Session&, const XMLNode&);
PluginInsert (const PluginInsert&);
~PluginInsert ();
@@ -133,9 +133,6 @@ class PluginInsert : public Insert
bool is_generator() const;
- void reset_midi_control (MIDI::Port*, bool);
- void send_all_midi_feedback ();
-
void set_parameter (uint32_t port, float val);
AutoState get_port_automation_state (uint32_t port);
@@ -144,11 +141,11 @@ class PluginInsert : public Insert
float default_parameter_value (uint32_t which);
- Plugin& plugin(uint32_t num=0) const {
+ boost::shared_ptr<Plugin> plugin(uint32_t num=0) const {
if (num < _plugins.size()) {
- return *_plugins[num];
+ return _plugins[num];
} else {
- return *_plugins[0]; // we always have one
+ return _plugins[0]; // we always have one
}
}
@@ -166,7 +163,7 @@ class PluginInsert : public Insert
void parameter_changed (uint32_t, float);
- vector<Plugin*> _plugins;
+ vector<boost::shared_ptr<Plugin> > _plugins;
void automation_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
void connect_and_run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, bool with_auto, jack_nframes_t now = 0);
@@ -175,9 +172,9 @@ class PluginInsert : public Insert
void auto_state_changed (uint32_t which);
void automation_list_creation_callback (uint32_t, AutomationList&);
- Plugin* plugin_factory (Plugin&);
+ boost::shared_ptr<Plugin> plugin_factory (boost::shared_ptr<Plugin>);
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_insert_h__ */
diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h
index 8ae45fe65c..b116a58b97 100644
--- a/libs/ardour/ardour/io.h
+++ b/libs/ardour/ardour/io.h
@@ -31,14 +31,15 @@
#include <pbd/fastlog.h>
#include <pbd/undo.h>
-
-#include <midi++/controllable.h>
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
#include <ardour/utils.h>
#include <ardour/state_manager.h>
#include <ardour/curve.h>
+#include <ardour/types.h>
+#include <ardour/data_type.h>
using std::string;
using std::vector;
@@ -53,6 +54,11 @@ class Port;
class Connection;
class Panner;
+/** A collection of input and output ports with connections.
+ *
+ * An IO can contain ports of varying types, making routes/inserts/etc with
+ * varied combinations of types (eg MIDI and audio) possible.
+ */
class IO : public Stateful, public ARDOUR::StateManager
{
@@ -61,7 +67,8 @@ class IO : public Stateful, public ARDOUR::StateManager
IO (Session&, string name,
int input_min = -1, int input_max = -1,
- int output_min = -1, int output_max = -1);
+ int output_min = -1, int output_max = -1,
+ DataType default_type = DataType::AUDIO);
virtual ~IO();
@@ -75,25 +82,29 @@ class IO : public Stateful, public ARDOUR::StateManager
void set_output_minimum (int n);
void set_output_maximum (int n);
+ DataType default_type() const { return _default_type; }
+
const string& name() const { return _name; }
virtual int set_name (string str, void *src);
virtual void silence (jack_nframes_t, jack_nframes_t offset);
+ // These should be moved in to a separate object that manipulates an IO
+
void pan (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset, gain_t gain_coeff);
void pan_automated (vector<Sample*>& bufs, uint32_t nbufs, jack_nframes_t start_frame, jack_nframes_t end_frame,
jack_nframes_t nframes, jack_nframes_t offset);
void collect_input (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
- void deliver_output (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
- void deliver_output_no_pan (vector<Sample *>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void deliver_output (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
+ void deliver_output_no_pan (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t offset);
void just_meter_input (jack_nframes_t start_frame, jack_nframes_t end_frame,
jack_nframes_t nframes, jack_nframes_t offset);
virtual uint32_t n_process_buffers () { return 0; }
virtual void set_gain (gain_t g, void *src);
- void inc_gain (gain_t delta, void *src);
- gain_t gain () const { return _desired_gain; }
+ void inc_gain (gain_t delta, void *src);
+ gain_t gain () const { return _desired_gain; }
virtual gain_t effective_gain () const;
Panner& panner() { return *_panner; }
@@ -106,8 +117,8 @@ class IO : public Stateful, public ARDOUR::StateManager
Connection *input_connection() const { return _input_connection; }
Connection *output_connection() const { return _output_connection; }
- int add_input_port (string source, void *src);
- int add_output_port (string destination, void *src);
+ int add_input_port (string source, void *src, DataType type = DataType::NIL);
+ int add_output_port (string destination, void *src, DataType type = DataType::NIL);
int remove_input_port (Port *, void *src);
int remove_output_port (Port *, void *src);
@@ -177,25 +188,10 @@ class IO : public Stateful, public ARDOUR::StateManager
static sigc::signal<void,uint32_t> MoreOutputs;
static sigc::signal<int> PortsCreated;
- /* MIDI control */
-
- void set_midi_to_gain_function (gain_t (*function)(double val)) {
- _midi_gain_control.midi_to_gain = function;
- }
-
- void set_gain_to_midi_function (double (*function)(gain_t gain)) {
- _midi_gain_control.gain_to_midi = function;
- }
-
- MIDI::Controllable& midi_gain_control() {
- return _midi_gain_control;
+ PBD::Controllable& gain_control() {
+ return _gain_control;
}
- virtual void reset_midi_control (MIDI::Port*, bool on);
-
- virtual void send_all_midi_feedback ();
- virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
-
/* Peak metering */
float peak_input_power (uint32_t n) {
@@ -257,7 +253,7 @@ public:
void start_pan_touch (uint32_t which);
void end_pan_touch (uint32_t which);
- id_t id() const { return _id; }
+ const PBD::ID& id() const { return _id; }
void defer_pan_reset ();
void allow_pan_reset ();
@@ -286,9 +282,10 @@ public:
string _name;
Connection* _input_connection;
Connection* _output_connection;
- id_t _id;
+ PBD::ID _id;
bool no_panner_reset;
XMLNode* deferred_state;
+ DataType _default_type;
virtual void set_deferred_state() {}
@@ -300,31 +297,22 @@ public:
static void apply_declick (vector<Sample*>&, uint32_t nbufs, jack_nframes_t nframes,
gain_t initial, gain_t target, bool invert_polarity);
- struct MIDIGainControl : public MIDI::Controllable {
- MIDIGainControl (IO&, MIDI::Port *);
- void set_value (float);
-
- void send_feedback (gain_t);
- MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false);
-
+ struct GainControllable : public PBD::Controllable {
+ GainControllable (IO& i) : io (i) {}
+
+ void set_value (float val);
+ float get_value (void) const;
+
IO& io;
- bool setting;
- MIDI::byte last_written;
-
- gain_t (*midi_to_gain) (double val);
- double (*gain_to_midi) (gain_t gain);
};
- MIDIGainControl _midi_gain_control;
+ GainControllable _gain_control;
/* state management */
Change restore_state (State&);
StateManager::State* state_factory (std::string why) const;
- bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional);
- bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional);
-
/* automation */
jack_nframes_t last_automation_snapshot;
@@ -406,6 +394,6 @@ public:
int32_t find_output_port_hole ();
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /*__ardour_io_h__ */
diff --git a/libs/ardour/ardour/ladspa_plugin.h b/libs/ardour/ardour/ladspa_plugin.h
index 2451953ce5..99fc884898 100644
--- a/libs/ardour/ardour/ladspa_plugin.h
+++ b/libs/ardour/ardour/ladspa_plugin.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -27,12 +27,12 @@
#include <string>
#include <dlfcn.h>
-#include <midi++/controllable.h>
#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+
#include <jack/types.h>
#include <ardour/ladspa.h>
-#include <ardour/stateful.h>
#include <ardour/plugin_state.h>
#include <ardour/plugin.h>
#include <ardour/ladspa_plugin.h>
@@ -137,6 +137,17 @@ class LadspaPlugin : public ARDOUR::Plugin
void run (jack_nframes_t nsamples);
void latency_compute_run ();
};
-}
+
+class LadspaPluginInfo : public PluginInfo {
+ public:
+ LadspaPluginInfo () { };
+ ~LadspaPluginInfo () { };
+
+ PluginPtr load (Session& session);
+};
+
+typedef boost::shared_ptr<LadspaPluginInfo> LadspaPluginInfoPtr;
+
+} // namespace ARDOUR
#endif /* __ardour_ladspa_plugin_h__ */
diff --git a/libs/ardour/ardour/location.h b/libs/ardour/ardour/location.h
index 75f4c5d12a..30c02a80a1 100644
--- a/libs/ardour/ardour/location.h
+++ b/libs/ardour/ardour/location.h
@@ -32,10 +32,10 @@
#include <glibmm/thread.h>
#include <pbd/undo.h>
+#include <pbd/stateful.h>
-#include "ardour.h"
-#include "stateful.h"
-#include "state_manager.h"
+#include <ardour/ardour.h>
+#include <ardour/state_manager.h>
using std::string;
@@ -199,6 +199,6 @@ class Locations : public Stateful, public StateManager
StateManager::State* state_factory (std::string why) const;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_location_h__ */
diff --git a/libs/ardour/ardour/logcurve.h b/libs/ardour/ardour/logcurve.h
index e65be55772..ac60a10fd7 100644
--- a/libs/ardour/ardour/logcurve.h
+++ b/libs/ardour/ardour/logcurve.h
@@ -126,7 +126,7 @@ class LogCurveOut : public LogCurve
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_logcurve_h__ */
diff --git a/libs/ardour/ardour/named_selection.h b/libs/ardour/ardour/named_selection.h
index 91bb816181..87b71e73ff 100644
--- a/libs/ardour/ardour/named_selection.h
+++ b/libs/ardour/ardour/named_selection.h
@@ -24,7 +24,7 @@
#include <string>
#include <list>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
class XMLNode;
diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h
index 806f350e03..75c59eb924 100644
--- a/libs/ardour/ardour/panner.h
+++ b/libs/ardour/ardour/panner.h
@@ -27,10 +27,10 @@
#include <iostream>
#include <sigc++/signal.h>
-#include <midi++/controllable.h>
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
#include <ardour/types.h>
-#include <ardour/stateful.h>
#include <ardour/curve.h>
using std::istream;
@@ -75,24 +75,7 @@ class StreamPanner : public sigc::trackable, public Stateful
virtual void set_automation_state (AutoState) = 0;
virtual void set_automation_style (AutoStyle) = 0;
- /* MIDI control */
-
- struct MIDIControl : public MIDI::Controllable {
- MIDIControl (StreamPanner&, MIDI::Port *);
- void set_value (float);
- void send_feedback (gain_t);
- MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force = false);
-
- pan_t (*midi_to_pan)(double val);
- double (*pan_to_midi)(pan_t p);
-
- StreamPanner& sp;
- bool setting;
- gain_t last_written;
- };
-
- MIDIControl& midi_control() { return _midi_control; }
- void reset_midi_control (MIDI::Port *, bool);
+ PBD::Controllable& control() { return _control; }
/* XXX this is wrong. for multi-dimensional panners, there
must surely be more than 1 automation curve.
@@ -100,7 +83,6 @@ class StreamPanner : public sigc::trackable, public Stateful
virtual Curve& automation() = 0;
-
virtual int load (istream&, string path, uint32_t&) = 0;
virtual int save (ostream&) const = 0;
@@ -130,12 +112,20 @@ class StreamPanner : public sigc::trackable, public Stateful
float effective_z;
bool _muted;
- MIDIControl _midi_control;
- void add_state (XMLNode&);
- bool get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional);
- bool set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional);
+ struct PanControllable : public PBD::Controllable {
+ PanControllable (StreamPanner& p) : panner (p) {}
+
+ StreamPanner& panner;
+
+ void set_value (float);
+ float get_value (void) const;
+ bool can_send_feedback() const;
+ };
+ PanControllable _control;
+
+ void add_state (XMLNode&);
virtual void update () = 0;
};
@@ -290,10 +280,6 @@ class Panner : public std::vector<StreamPanner*>, public Stateful, public sigc::
std::vector<Output> outputs;
Session& session() const { return _session; }
- void reset_midi_control (MIDI::Port *, bool);
- void send_all_midi_feedback ();
- MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
-
enum LinkDirection {
SameDirection,
OppositeDirection
@@ -326,6 +312,6 @@ class Panner : public std::vector<StreamPanner*>, public Stateful, public sigc::
static float current_automation_version_number;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /*__ardour_panner_h__ */
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index c653c8502e..9fb5b0eb2b 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -31,12 +31,13 @@
#include <glib.h>
#include <sigc++/signal.h>
+
#include <pbd/undo.h>
+#include <pbd/stateful.h>
#include <ardour/ardour.h>
#include <ardour/crossfade_compare.h>
#include <ardour/location.h>
-#include <ardour/stateful.h>
#include <ardour/state_manager.h>
namespace ARDOUR {
@@ -53,7 +54,6 @@ class Playlist : public Stateful, public StateManager {
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
- virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
virtual void clear (bool with_delete = false, bool with_save = true);
virtual void dump () const;
virtual UndoAction get_memento() const = 0;
@@ -80,13 +80,15 @@ class Playlist : public Stateful, public StateManager {
void add_region (const Region&, jack_nframes_t position, float times = 1, bool with_save = true);
void remove_region (Region *);
+ void get_equivalent_regions (const Region&, std::vector<Region*>&);
+ void get_region_list_equivalent_regions (const Region&, std::vector<Region*>&);
void replace_region (Region& old, Region& newr, jack_nframes_t pos);
void split_region (Region&, jack_nframes_t position);
void partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level);
void duplicate (Region&, jack_nframes_t position, float times);
void nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwards);
- Region* find_region (id_t) const;
+ Region* find_region (const PBD::ID&) const;
Playlist* cut (list<AudioRange>&, bool result_is_hidden = true);
Playlist* copy (list<AudioRange>&, bool result_is_hidden = true);
@@ -107,16 +109,15 @@ class Playlist : public Stateful, public StateManager {
int set_state (const XMLNode&);
XMLNode& get_template ();
- sigc::signal<void,Region *> RegionAdded;
- sigc::signal<void,Region *> RegionRemoved;
-
+ sigc::signal<void,Region *> RegionAdded;
+ sigc::signal<void,Region *> RegionRemoved;
sigc::signal<void,Playlist*,bool> InUse;
- sigc::signal<void> Modified;
- sigc::signal<void> NameChanged;
- sigc::signal<void> LengthChanged;
- sigc::signal<void> LayeringChanged;
- sigc::signal<void,Playlist *> GoingAway;
- sigc::signal<void> StatePushed;
+ sigc::signal<void> Modified;
+ sigc::signal<void> NameChanged;
+ sigc::signal<void> LengthChanged;
+ sigc::signal<void> LayeringChanged;
+ sigc::signal<void,Playlist *> GoingAway;
+ sigc::signal<void> StatePushed;
static sigc::signal<void,Playlist*> PlaylistCreated;
@@ -135,8 +136,8 @@ class Playlist : public Stateful, public StateManager {
Session& session() { return _session; }
- id_t get_orig_diskstream_id () const { return _orig_diskstream_id; }
- void set_orig_diskstream_id (id_t did) { _orig_diskstream_id = did; }
+ const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
+ void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
/* destructive editing */
@@ -190,7 +191,7 @@ class Playlist : public Stateful, public StateManager {
bool _frozen;
uint32_t subcnt;
uint32_t _read_data_count;
- id_t _orig_diskstream_id;
+ PBD::ID _orig_diskstream_id;
uint64_t layer_op_counter;
jack_nframes_t freeze_length;
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 211b00d0bb..6b11a975ca 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -18,15 +18,17 @@
$Id$
*/
-#ifndef __ardour_ladspa_h__
-#define __ardour_ladspa_h__
+#ifndef __ardour_plugin_h__
+#define __ardour_plugin_h__
-#include <midi++/controllable.h>
+#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
+
#include <jack/types.h>
#include <ardour/types.h>
-#include <ardour/stateful.h>
#include <ardour/plugin_state.h>
#include <ardour/cycles.h>
@@ -44,6 +46,9 @@ namespace ARDOUR {
class AudioEngine;
class Session;
+class Plugin;
+typedef boost::shared_ptr<Plugin> PluginPtr;
+
class PluginInfo {
public:
enum Type {
@@ -52,11 +57,12 @@ class PluginInfo {
VST
};
- PluginInfo () { };
+ PluginInfo () { }
PluginInfo (const PluginInfo &o)
: name(o.name), n_inputs(o.n_inputs), n_outputs(o.n_outputs),
unique_id(o.unique_id), path (o.path), index(o.index) {}
- ~PluginInfo () { };
+ virtual ~PluginInfo () { }
+
string name;
string category;
uint32_t n_inputs;
@@ -65,19 +71,24 @@ class PluginInfo {
long unique_id;
- private:
+ virtual PluginPtr load (Session& session) = 0;
+
+ protected:
friend class PluginManager;
string path;
uint32_t index;
};
+typedef boost::shared_ptr<PluginInfo> PluginInfoPtr;
+typedef std::list<PluginInfoPtr> PluginInfoList;
+
class Plugin : public Stateful, public sigc::trackable
{
public:
Plugin (ARDOUR::AudioEngine&, ARDOUR::Session&);
Plugin (const Plugin&);
- ~Plugin ();
+ virtual ~Plugin ();
struct ParameterDescriptor {
@@ -136,13 +147,10 @@ class Plugin : public Stateful, public sigc::trackable
sigc::signal<void,uint32_t,float> ParameterChanged;
sigc::signal<void,Plugin *> GoingAway;
- void reset_midi_control (MIDI::Port*, bool);
- void send_all_midi_feedback ();
- MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
- MIDI::Controllable *get_nth_midi_control (uint32_t);
+ PBD::Controllable *get_nth_control (uint32_t);
- PluginInfo & get_info() { return _info; }
- void set_info (const PluginInfo &inf) { _info = inf; }
+ PluginInfoPtr get_info() { return _info; }
+ void set_info (const PluginInfoPtr inf) { _info = inf; }
ARDOUR::AudioEngine& engine() const { return _engine; }
ARDOUR::Session& session() const { return _session; }
@@ -153,21 +161,19 @@ class Plugin : public Stateful, public sigc::trackable
protected:
ARDOUR::AudioEngine& _engine;
ARDOUR::Session& _session;
- PluginInfo _info;
+ PluginInfoPtr _info;
uint32_t _cycles;
map<string,string> presets;
bool save_preset(string name, string domain /* vst, ladspa etc. */);
- void setup_midi_controls ();
+ void setup_controls ();
-
- struct MIDIPortControl : public MIDI::Controllable {
- MIDIPortControl (Plugin&, uint32_t abs_port_id, MIDI::Port *,
- float lower, float upper, bool toggled, bool logarithmic);
+ struct PortControllable : public PBD::Controllable {
+ PortControllable (Plugin&, uint32_t abs_port_id,
+ float lower, float upper, bool toggled, bool logarithmic);
void set_value (float);
- void send_feedback (float);
- MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, float val, bool force = false);
+ float get_value () const;
Plugin& plugin;
uint32_t absolute_port;
@@ -176,19 +182,12 @@ class Plugin : public Stateful, public sigc::trackable
float range;
bool toggled;
bool logarithmic;
-
- bool setting;
- float last_written;
};
- vector<MIDIPortControl*> midi_controls;
-
-
+ vector<PortControllable*> controls;
};
-/* this is actually defined in plugin_manager.cc */
-
-Plugin * find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type);
+PluginPtr find_plugin(ARDOUR::Session&, string name, long unique_id, PluginInfo::Type);
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h
index 1a07c67c8d..8e6c0bd1c7 100644
--- a/libs/ardour/ardour/plugin_manager.h
+++ b/libs/ardour/ardour/plugin_manager.h
@@ -6,34 +6,33 @@
#include <string>
#include <ardour/types.h>
+#include <ardour/plugin.h>
+#include <ardour/audio_unit.h>
namespace ARDOUR {
-class PluginInfo;
class Plugin;
class Session;
class AudioEngine;
class PluginManager {
public:
- PluginManager (ARDOUR::AudioEngine&);
+ PluginManager ();
~PluginManager ();
- std::list<PluginInfo*> &vst_plugin_info () { return _vst_plugin_info; }
- std::list<PluginInfo*> &ladspa_plugin_info () { return _ladspa_plugin_info; }
+ ARDOUR::PluginInfoList &vst_plugin_info () { return _vst_plugin_info; }
+ ARDOUR::PluginInfoList &ladspa_plugin_info () { return _ladspa_plugin_info; }
+
void refresh ();
int add_ladspa_directory (std::string dirpath);
int add_vst_directory (std::string dirpath);
- Plugin *load (ARDOUR::Session& s, PluginInfo* info);
-
static PluginManager* the_manager() { return _manager; }
private:
- ARDOUR::AudioEngine& _engine;
- std::list<PluginInfo*> _vst_plugin_info;
- std::list<PluginInfo*> _ladspa_plugin_info;
+ ARDOUR::PluginInfoList _vst_plugin_info;
+ ARDOUR::PluginInfoList _ladspa_plugin_info;
std::map<uint32_t, std::string> rdf_type;
std::string ladspa_path;
@@ -61,3 +60,4 @@ class PluginManager {
} /* namespace ARDOUR */
#endif /* __ardour_plugin_manager_h__ */
+
diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h
index ff9c25e1c4..86c99cb7e3 100644
--- a/libs/ardour/ardour/port.h
+++ b/libs/ardour/ardour/port.h
@@ -33,24 +33,24 @@ class AudioEngine;
class Port : public sigc::trackable {
public:
virtual ~Port() {
- free (port);
+ free (_port);
}
Sample *get_buffer (jack_nframes_t nframes) {
if (_flags & JackPortIsOutput) {
return _buffer;
} else {
- return (Sample *) jack_port_get_buffer (port, nframes);
+ return (Sample *) jack_port_get_buffer (_port, nframes);
}
}
void reset_buffer () {
if (_flags & JackPortIsOutput) {
- _buffer = (Sample *) jack_port_get_buffer (port, 0);
+ _buffer = (Sample *) jack_port_get_buffer (_port, 0);
} else {
_buffer = 0; /* catch illegal attempts to use it */
}
- silent = false;
+ _silent = false;
}
std::string name() {
@@ -58,7 +58,7 @@ class Port : public sigc::trackable {
}
std::string short_name() {
- return jack_port_short_name (port);
+ return jack_port_short_name (_port);
}
int set_name (std::string str);
@@ -68,7 +68,7 @@ class Port : public sigc::trackable {
}
bool is_mine (jack_client_t *client) {
- return jack_port_is_mine (client, port);
+ return jack_port_is_mine (client, _port);
}
const char* type() const {
@@ -76,21 +76,21 @@ class Port : public sigc::trackable {
}
int connected () const {
- return jack_port_connected (port);
+ return jack_port_connected (_port);
}
bool connected_to (const std::string& portname) const {
- return jack_port_connected_to (port, portname.c_str());
+ return jack_port_connected_to (_port, portname.c_str());
}
const char ** get_connections () const {
- return jack_port_get_connections (port);
+ return jack_port_get_connections (_port);
}
void reset_overs () {
_short_overs = 0;
_long_overs = 0;
- overlen = 0;
+ _overlen = 0;
}
void reset_peak_meter () {
@@ -103,18 +103,18 @@ class Port : public sigc::trackable {
}
void enable_metering() {
- metering++;
+ _metering++;
}
void disable_metering () {
- if (metering) { metering--; }
+ if (_metering) { _metering--; }
}
- float peak_db() const { return _peak_db; }
+ float peak_db() const { return _peak_db; }
jack_default_audio_sample_t peak() const { return _peak; }
uint32_t short_overs () const { return _short_overs; }
- uint32_t long_overs () const { return _long_overs; }
+ uint32_t long_overs () const { return _long_overs; }
static void set_short_over_length (jack_nframes_t);
static void set_long_over_length (jack_nframes_t);
@@ -128,7 +128,7 @@ class Port : public sigc::trackable {
}
bool monitoring_input () const {
- return jack_port_monitoring_input (port);
+ return jack_port_monitoring_input (_port);
}
bool can_monitor () const {
@@ -136,30 +136,29 @@ class Port : public sigc::trackable {
}
void ensure_monitor_input (bool yn) {
- jack_port_request_monitor (port, yn);
+ jack_port_request_monitor (_port, yn);
}
void request_monitor_input (bool yn) {
- jack_port_request_monitor (port, yn);
+ jack_port_request_monitor (_port, yn);
}
jack_nframes_t latency () const {
- return jack_port_get_latency (port);
+ return jack_port_get_latency (_port);
}
void set_latency (jack_nframes_t nframes) {
- jack_port_set_latency (port, nframes);
+ jack_port_set_latency (_port, nframes);
}
sigc::signal<void,bool> MonitorInputChanged;
sigc::signal<void,bool> ClockSyncChanged;
- bool is_silent() const { return silent; }
+ bool is_silent() const { return _silent; }
+ /** Assumes that the port is an audio output port */
void silence (jack_nframes_t nframes, jack_nframes_t offset) {
- /* assumes that the port is an output port */
-
- if (!silent) {
+ if (!_silent) {
memset (_buffer + offset, 0, sizeof (Sample) * nframes);
if (offset == 0) {
/* XXX this isn't really true, but i am not sure
@@ -167,13 +166,13 @@ class Port : public sigc::trackable {
want to set it true when the entire port
buffer has been overrwritten.
*/
- silent = true;
+ _silent = true;
}
}
}
void mark_silence (bool yn) {
- silent = yn;
+ _silent = yn;
}
private:
@@ -184,7 +183,7 @@ class Port : public sigc::trackable {
/* engine isn't supposed to below here */
- Sample *_buffer;
+ Sample *_buffer;
/* cache these 3 from JACK so that we can
access them for reconnecting.
@@ -194,20 +193,20 @@ class Port : public sigc::trackable {
std::string _type;
std::string _name;
- bool last_monitor : 1;
- bool silent : 1;
- jack_port_t *port;
- jack_nframes_t overlen;
- jack_default_audio_sample_t _peak;
- float _peak_db;
- uint32_t _short_overs;
- uint32_t _long_overs;
- unsigned short metering;
+ bool _last_monitor : 1;
+ bool _silent : 1;
+ jack_port_t *_port;
+ jack_nframes_t _overlen;
+ jack_default_audio_sample_t _peak;
+ float _peak_db;
+ uint32_t _short_overs;
+ uint32_t _long_overs;
+ unsigned short _metering;
- static jack_nframes_t long_over_length;
- static jack_nframes_t short_over_length;
+ static jack_nframes_t _long_over_length;
+ static jack_nframes_t _short_over_length;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_port_h__ */
diff --git a/libs/ardour/ardour/redirect.h b/libs/ardour/ardour/redirect.h
index ede55a1d80..658cab5d3b 100644
--- a/libs/ardour/ardour/redirect.h
+++ b/libs/ardour/ardour/redirect.h
@@ -25,6 +25,7 @@
#include <vector>
#include <set>
#include <map>
+#include <boost/shared_ptr.hpp>
#include <sigc++/signal.h>
#include <glibmm/thread.h>
@@ -64,7 +65,7 @@ class Redirect : public IO
Redirect (const Redirect&);
virtual ~Redirect ();
- static Redirect *clone (const Redirect&);
+ static boost::shared_ptr<Redirect> clone (boost::shared_ptr<const Redirect>);
bool active () const { return _active; }
void set_active (bool yn, void *src);
@@ -148,6 +149,6 @@ class Redirect : public IO
void* _gui; /* generic, we don't know or care what this is */
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_redirect_h__ */
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index aae776625e..3773a3b893 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -24,7 +24,6 @@
#include <pbd/undo.h>
#include <ardour/ardour.h>
-#include <ardour/logcurve.h>
#include <ardour/state_manager.h>
class XMLNode;
@@ -36,22 +35,22 @@ class Source;
enum RegionEditState {
EditChangesNothing = 0,
- EditChangesName = 1,
- EditChangesID = 2
+ EditChangesName = 1,
+ EditChangesID = 2
};
-struct RegionState : public StateManager::State {
-
- RegionState (std::string why) : StateManager::State (why) {}
-
- jack_nframes_t _start;
- jack_nframes_t _length;
- jack_nframes_t _position;
- uint32_t _flags;
- jack_nframes_t _sync_position;
- layer_t _layer;
- string _name;
- mutable RegionEditState _first_edit;
+struct RegionState : public StateManager::State
+{
+ RegionState (std::string why) : StateManager::State (why) {}
+
+ jack_nframes_t _start;
+ jack_nframes_t _length;
+ jack_nframes_t _position;
+ uint32_t _flags;
+ jack_nframes_t _sync_position;
+ layer_t _layer;
+ string _name;
+ mutable RegionEditState _first_edit;
};
class Region : public Stateful, public StateManager
@@ -95,9 +94,9 @@ class Region : public Stateful, public StateManager
Region (const Region&, jack_nframes_t start, jack_nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags);
Region (const Region&);
Region (const XMLNode&);
- ~Region();
+ virtual ~Region();
- ARDOUR::id_t id() const { return _id; }
+ const PBD::ID& id() const { return _id; }
/* Note: changing the name of a Region does not constitute an edit */
@@ -105,9 +104,10 @@ class Region : public Stateful, public StateManager
void set_name (string str);
jack_nframes_t position () const { return _position; }
- jack_nframes_t start () const { return _start; }
- jack_nframes_t length() const { return _length; }
- layer_t layer () const { return _layer; }
+ jack_nframes_t start () const { return _start; }
+ jack_nframes_t length() const { return _length; }
+ layer_t layer () const { return _layer; }
+
jack_nframes_t sync_offset(int& dir) const;
jack_nframes_t sync_position() const;
@@ -118,14 +118,13 @@ class Region : public Stateful, public StateManager
jack_nframes_t first_frame() const { return _position; }
jack_nframes_t last_frame() const { return _position + _length - 1; }
- bool hidden() const { return _flags & Hidden; }
- bool muted() const { return _flags & Muted; }
- bool opaque () const { return _flags & Opaque; }
- bool envelope_active () const { return _flags & EnvelopeActive; }
- bool locked() const { return _flags & Locked; }
- bool automatic() const { return _flags & Automatic; }
+ bool hidden() const { return _flags & Hidden; }
+ bool muted() const { return _flags & Muted; }
+ bool opaque () const { return _flags & Opaque; }
+ bool locked() const { return _flags & Locked; }
+ bool automatic() const { return _flags & Automatic; }
bool whole_file() const { return _flags & WholeFile ; }
- Flag flags() const { return _flags; }
+ Flag flags() const { return _flags; }
virtual bool should_save_state () const { return !(_flags & DoNotSaveState); };
@@ -139,12 +138,14 @@ class Region : public Stateful, public StateManager
OverlapType coverage (jack_nframes_t start, jack_nframes_t end) const {
return ARDOUR::coverage (_position, _position + _length - 1, start, end);
}
-
- virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
- float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
- uint32_t chan_n = 0,
- jack_nframes_t read_frames = 0,
- jack_nframes_t skip_frames = 0) const = 0;
+
+ bool equivalent (const Region&) const;
+ bool size_equivalent (const Region&) const;
+ bool overlap_equivalent (const Region&) const;
+ bool region_list_equivalent (const Region&) const;
+ virtual bool source_equivalent (const Region&) const = 0;
+
+ virtual bool speed_mismatch (float) const = 0;
/* EDITING OPERATIONS */
@@ -173,7 +174,6 @@ class Region : public Stateful, public StateManager
void set_hidden (bool yn);
void set_muted (bool yn);
void set_opaque (bool yn);
- void set_envelope_active (bool yn);
void set_locked (bool yn);
virtual uint32_t read_data_count() const { return _read_data_count; }
@@ -189,9 +189,9 @@ class Region : public Stateful, public StateManager
/* serialization */
+ XMLNode& get_state ();
virtual XMLNode& state (bool);
- XMLNode& get_state ();
- int set_state (const XMLNode&);
+ virtual int set_state (const XMLNode&);
sigc::signal<void,Region*> GoingAway;
@@ -211,23 +211,6 @@ class Region : public Stateful, public StateManager
void set_last_layer_op (uint64_t when);
protected:
-
- jack_nframes_t _start;
- jack_nframes_t _length;
- jack_nframes_t _position;
- Flag _flags;
- jack_nframes_t _sync_position;
- layer_t _layer;
- string _name;
- mutable RegionEditState _first_edit;
- int _frozen;
- Glib::Mutex lock;
- ARDOUR::id_t _id;
- ARDOUR::Playlist* _playlist;
- mutable uint32_t _read_data_count; // modified in read()
- Change pending_changed;
- uint64_t _last_layer_op; // timestamp
-
XMLNode& get_short_state (); /* used only by Session */
/* state management */
@@ -251,6 +234,23 @@ class Region : public Stateful, public StateManager
virtual bool verify_length (jack_nframes_t) = 0;
virtual void recompute_at_start () = 0;
virtual void recompute_at_end () = 0;
+
+
+ jack_nframes_t _start;
+ jack_nframes_t _length;
+ jack_nframes_t _position;
+ Flag _flags;
+ jack_nframes_t _sync_position;
+ layer_t _layer;
+ string _name;
+ mutable RegionEditState _first_edit;
+ int _frozen;
+ Glib::Mutex lock;
+ PBD::ID _id;
+ ARDOUR::Playlist* _playlist;
+ mutable uint32_t _read_data_count; // modified in read()
+ Change pending_changed;
+ uint64_t _last_layer_op; // timestamp
};
} /* namespace ARDOUR */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 5686dfc908..8271c1cf6a 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -27,17 +27,20 @@
#include <map>
#include <string>
+#include <boost/shared_ptr.hpp>
+
#include <pbd/fastlog.h>
#include <glibmm/thread.h>
#include <pbd/xml++.h>
#include <pbd/undo.h>
-#include <midi++/controllable.h>
+#include <pbd/stateful.h>
+#include <pbd/controllable.h>
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
#include <ardour/io.h>
#include <ardour/session.h>
#include <ardour/redirect.h>
+#include <ardour/types.h>
namespace ARDOUR {
@@ -56,17 +59,19 @@ class Route : public IO
{
protected:
- typedef list<Redirect *> RedirectList;
+ typedef list<boost::shared_ptr<Redirect> > RedirectList;
public:
enum Flag {
Hidden = 0x1,
MasterOut = 0x2,
- ControlOut = 0x4,
+ ControlOut = 0x4
};
- Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max, Flag flags = Flag(0));
+ Route (Session&, std::string name, int input_min, int input_max, int output_min, int output_max,
+ Flag flags = Flag(0), DataType default_type = DataType::AUDIO);
+
Route (Session&, const XMLNode&);
virtual ~Route();
@@ -138,19 +143,19 @@ class Route : public IO
void flush_redirects ();
- template<class T> void foreach_redirect (T *obj, void (T::*func)(Redirect *)) {
+ template<class T> void foreach_redirect (T *obj, void (T::*func)(boost::shared_ptr<Redirect>)) {
Glib::RWLock::ReaderLock lm (redirect_lock);
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
(obj->*func) (*i);
}
}
- Redirect *nth_redirect (uint32_t n) {
+ boost::shared_ptr<Redirect> nth_redirect (uint32_t n) {
Glib::RWLock::ReaderLock lm (redirect_lock);
RedirectList::iterator i;
for (i = _redirects.begin(); i != _redirects.end() && n; ++i, --n);
if (i == _redirects.end()) {
- return 0;
+ return boost::shared_ptr<Redirect> ();
} else {
return *i;
}
@@ -158,9 +163,9 @@ class Route : public IO
uint32_t max_redirect_outs () const { return redirect_max_outs; }
- int add_redirect (Redirect *, void *src, uint32_t* err_streams = 0);
+ int add_redirect (boost::shared_ptr<Redirect>, void *src, uint32_t* err_streams = 0);
int add_redirects (const RedirectList&, void *src, uint32_t* err_streams = 0);
- int remove_redirect (Redirect *, void *src, uint32_t* err_streams = 0);
+ int remove_redirect (boost::shared_ptr<Redirect>, void *src, uint32_t* err_streams = 0);
int copy_redirects (const Route&, Placement, uint32_t* err_streams = 0);
int sort_redirects (uint32_t* err_streams = 0);
@@ -209,37 +214,31 @@ class Route : public IO
int set_control_outs (const vector<std::string>& ports);
IO* control_outs() { return _control_outs; }
- bool feeds (Route *);
- set<Route *> fed_by;
-
- struct MIDIToggleControl : public MIDI::Controllable {
- enum ToggleType {
- MuteControl = 0,
- SoloControl
- };
-
- MIDIToggleControl (Route&, ToggleType, MIDI::Port *);
- void set_value (float);
- void send_feedback (bool);
- MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force = false);
-
- Route& route;
- ToggleType type;
- bool setting;
- bool last_written;
+ bool feeds (boost::shared_ptr<Route>);
+ set<boost::shared_ptr<Route> > fed_by;
+
+ struct ToggleControllable : public PBD::Controllable {
+ enum ToggleType {
+ MuteControl = 0,
+ SoloControl
+ };
+
+ ToggleControllable (Route&, ToggleType);
+ void set_value (float);
+ float get_value (void) const;
+
+ Route& route;
+ ToggleType type;
};
- MIDI::Controllable& midi_solo_control() {
- return _midi_solo_control;
+ PBD::Controllable& solo_control() {
+ return _solo_control;
}
- MIDI::Controllable& midi_mute_control() {
- return _midi_mute_control;
+
+ PBD::Controllable& mute_control() {
+ return _mute_control;
}
- virtual void reset_midi_control (MIDI::Port*, bool);
- virtual void send_all_midi_feedback ();
- virtual MIDI::byte* write_midi_feedback (MIDI::byte*, int32_t& bufsize);
-
void automation_snapshot (jack_nframes_t now);
void protect_automation ();
@@ -299,8 +298,8 @@ class Route : public IO
std::string _comment;
bool _have_internal_generator;
- MIDIToggleControl _midi_solo_control;
- MIDIToggleControl _midi_mute_control;
+ ToggleControllable _solo_control;
+ ToggleControllable _mute_control;
void passthru (jack_nframes_t start_frame, jack_nframes_t end_frame,
jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter_inputs);
@@ -342,12 +341,12 @@ class Route : public IO
/* plugin count handling */
struct InsertCount {
- ARDOUR::Insert& insert;
+ boost::shared_ptr<ARDOUR::Insert> insert;
int32_t cnt;
int32_t in;
int32_t out;
- InsertCount (ARDOUR::Insert& ins) : insert (ins), cnt (-1) {}
+ InsertCount (boost::shared_ptr<ARDOUR::Insert> ins) : insert (ins), cnt (-1) {}
};
int32_t apply_some_plugin_counts (std::list<InsertCount>& iclist);
@@ -358,6 +357,6 @@ class Route : public IO
void redirect_active_proxy (Redirect*, void*);
};
-}; /* namespace ARDOUR*/
+} // namespace ARDOUR
#endif /* __ardour_route_h__ */
diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h
index c9f966666f..e9fad1aa2b 100644
--- a/libs/ardour/ardour/route_group.h
+++ b/libs/ardour/ardour/route_group.h
@@ -26,7 +26,7 @@
#include <string>
#include <stdint.h>
#include <sigc++/signal.h>
-#include <ardour/stateful.h>
+#include <pbd/stateful.h>
#include <ardour/types.h>
using std::string;
@@ -35,6 +35,7 @@ using std::list;
namespace ARDOUR {
class Route;
+class Track;
class AudioTrack;
class Session;
@@ -43,7 +44,7 @@ class RouteGroup : public Stateful, public sigc::trackable {
enum Flag {
Relative = 0x1,
Active = 0x2,
- Hidden = 0x4,
+ Hidden = 0x4
};
RouteGroup (Session& s, const string &n, Flag f = Flag(0));
@@ -90,7 +91,7 @@ class RouteGroup : public Stateful, public sigc::trackable {
/* to use these, #include <ardour/route_group_specialized.h> */
- template<class T> void apply (void (AudioTrack::*func)(T, void *), T val, void *src);
+ template<class T> void apply (void (Track::*func)(T, void *), T val, void *src);
/* fills at_set with all members of the group that are AudioTracks */
diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h
index 0424002dcd..250d3744df 100644
--- a/libs/ardour/ardour/route_group_specialized.h
+++ b/libs/ardour/ardour/route_group_specialized.h
@@ -7,11 +7,11 @@
namespace ARDOUR {
template<class T> void
-RouteGroup::apply (void (AudioTrack::*func)(T, void *), T val, void *src)
+RouteGroup::apply (void (Track::*func)(T, void *), T val, void *src)
{
for (list<Route *>::iterator i = routes.begin(); i != routes.end(); i++) {
- AudioTrack *at;
- if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
+ Track *at;
+ if ((at = dynamic_cast<Track*>(*i)) != 0) {
(at->*func)(val, this);
}
}
diff --git a/libs/ardour/ardour/send.h b/libs/ardour/ardour/send.h
index a94318f2a5..0a068e8af0 100644
--- a/libs/ardour/ardour/send.h
+++ b/libs/ardour/ardour/send.h
@@ -24,12 +24,12 @@
#include <sigc++/signal.h>
#include <string>
+
+#include <pbd/stateful.h>
#include <ardour/ardour.h>
#include <ardour/audioengine.h>
-
-#include "io.h"
-#include "stateful.h"
-#include "redirect.h"
+#include <ardour/io.h>
+#include <ardour/redirect.h>
namespace ARDOUR {
@@ -58,6 +58,6 @@ class Send : public Redirect {
uint32_t expected_inputs;
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_send_h__ */
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 7a9e50ae9b..0c53cc32e7 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -36,14 +36,16 @@
#include <pbd/error.h>
#include <pbd/undo.h>
#include <pbd/pool.h>
+#include <pbd/rcu.h>
#include <midi++/types.h>
#include <midi++/mmc.h>
+#include <pbd/stateful.h>
+
#include <ardour/ardour.h>
#include <ardour/configuration.h>
#include <ardour/location.h>
-#include <ardour/stateful.h>
#include <ardour/gain.h>
#include <ardour/io.h>
@@ -55,11 +57,16 @@ namespace MIDI {
class Port;
}
+namespace PBD {
+ class Controllable;
+}
+
namespace ARDOUR {
class Port;
class AudioEngine;
class Slave;
+class Diskstream;
class AudioDiskstream;
class Route;
class AuxInput;
@@ -95,9 +102,9 @@ class Session : public sigc::trackable, public Stateful
{
private:
- typedef std::pair<Route*,bool> RouteBooleanState;
+ typedef std::pair<boost::shared_ptr<Route>,bool> RouteBooleanState;
typedef vector<RouteBooleanState> GlobalRouteBooleanState;
- typedef std::pair<Route*,MeterPoint> RouteMeterState;
+ typedef std::pair<boost::shared_ptr<Route>,MeterPoint> RouteMeterState;
typedef vector<RouteMeterState> GlobalRouteMeterState;
public:
@@ -110,7 +117,7 @@ class Session : public sigc::trackable, public Stateful
enum SlaveSource {
None = 0,
MTC,
- JACK,
+ JACK
};
enum AutoConnectOption {
@@ -141,7 +148,7 @@ class Session : public sigc::trackable, public Stateful
*/
StopOnce,
- AutoLoop,
+ AutoLoop
};
enum Action {
@@ -151,16 +158,17 @@ class Session : public sigc::trackable, public Stateful
Clear
};
- Type type;
- Action action;
- jack_nframes_t action_frame;
- jack_nframes_t target_frame;
- float speed;
+ Type type;
+ Action action;
+ jack_nframes_t action_frame;
+ jack_nframes_t target_frame;
+ float speed;
union {
- void* ptr;
- bool yes_or_no;
- Session::SlaveSource slave;
+ void* ptr;
+ bool yes_or_no;
+ Session::SlaveSource slave;
+ Route* route;
};
list<AudioRange> audio_range;
@@ -262,52 +270,39 @@ class Session : public sigc::trackable, public Stateful
vector<Sample*>& get_silent_buffers (uint32_t howmany);
vector<Sample*>& get_send_buffers () { return _send_buffers; }
- AudioDiskstream *diskstream_by_id (id_t id);
- AudioDiskstream *diskstream_by_name (string name);
+ Diskstream* diskstream_by_id (const PBD::ID& id);
+ Diskstream* diskstream_by_name (string name);
bool have_captured() const { return _have_captured; }
void refill_all_diskstream_buffers ();
uint32_t diskstream_buffer_size() const { return dstream_buffer_size; }
- /* XXX fix required here when we get new diskstream types *, but
- not sure of the direction to take this in until then.
- */
-
- uint32_t get_next_diskstream_id() const { return n_audio_diskstreams(); }
- uint32_t n_audio_diskstreams() const;
+ uint32_t get_next_diskstream_id() const { return n_diskstreams(); }
+ uint32_t n_diskstreams() const;
- typedef list<AudioDiskstream *> AudioDiskstreamList;
+ typedef list<Diskstream *> DiskstreamList;
- Session::AudioDiskstreamList audio_disk_streams() const {
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- return audio_diskstreams; /* XXX yes, force a copy */
- }
-
- void foreach_audio_diskstream (void (AudioDiskstream::*func)(void));
- template<class T> void foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&));
-
- typedef list<Route *> RouteList;
+ typedef std::list<boost::shared_ptr<Route> > RouteList;
- RouteList get_routes() const {
- Glib::RWLock::ReaderLock rlock (route_lock);
- return routes; /* XXX yes, force a copy */
+ boost::shared_ptr<RouteList> get_routes() const {
+ return routes.reader ();
}
- uint32_t nroutes() const { return routes.size(); }
+ uint32_t nroutes() const { return routes.reader()->size(); }
uint32_t ntracks () const;
uint32_t nbusses () const;
struct RoutePublicOrderSorter {
- bool operator() (Route *, Route *b);
+ bool operator() (boost::shared_ptr<Route>, boost::shared_ptr<Route> b);
};
template<class T> void foreach_route (T *obj, void (T::*func)(Route&));
- template<class T> void foreach_route (T *obj, void (T::*func)(Route*));
+ template<class T> void foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>));
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
- Route *route_by_name (string);
- Route *route_by_remote_id (uint32_t id);
+ boost::shared_ptr<Route> route_by_name (string);
+ boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
bool route_name_unique (string) const;
@@ -349,8 +344,8 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void> DurationChanged;
sigc::signal<void> HaltOnXrun;
- sigc::signal<void,Route*> RouteAdded;
- sigc::signal<void,AudioDiskstream*> AudioDiskstreamAdded;
+ sigc::signal<void,boost::shared_ptr<Route> > RouteAdded;
+ sigc::signal<void,Diskstream*> DiskstreamAdded; // FIXME: make a shared_ptr
void request_roll ();
void request_bounded_roll (jack_nframes_t start, jack_nframes_t end);
@@ -362,15 +357,14 @@ class Session : public sigc::trackable, public Stateful
void goto_start () { request_locate (start_location->start(), false); }
void use_rf_shuttle_speed ();
void request_transport_speed (float speed);
- void request_overwrite_buffer (AudioDiskstream*);
- void request_diskstream_speed (AudioDiskstream&, float speed);
+ void request_overwrite_buffer (Diskstream*);
+ void request_diskstream_speed (Diskstream&, float speed);
void request_input_change_handling ();
bool locate_pending() const { return static_cast<bool>(post_transport_work&PostTransportLocate); }
bool transport_locked () const;
int wipe ();
- int wipe_diskstream (AudioDiskstream *);
int remove_region_from_region_list (Region&);
@@ -500,9 +494,6 @@ class Session : public sigc::trackable, public Stateful
void add_instant_xml (XMLNode&, const std::string& dir);
- void swap_configuration(Configuration** new_config);
- void copy_configuration(Configuration* new_config);
-
enum StateOfTheState {
Clean = 0x0,
Dirty = 0x1,
@@ -543,13 +534,13 @@ class Session : public sigc::trackable, public Stateful
/* fundamental operations. duh. */
+ boost::shared_ptr<AudioTrack> new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
+ boost::shared_ptr<Route> new_audio_route (int input_channels, int output_channels);
- AudioTrack *new_audio_track (int input_channels, int output_channels, TrackMode mode = Normal);
-
- Route *new_audio_route (int input_channels, int output_channels);
+ void remove_route (boost::shared_ptr<Route>);
- void remove_route (Route&);
- void resort_routes (void *src);
+ void resort_routes ();
+ void resort_routes_using (boost::shared_ptr<RouteList>);
AudioEngine &engine() { return _engine; };
@@ -630,7 +621,7 @@ class Session : public sigc::trackable, public Stateful
string path_from_region_name (string name, string identifier);
AudioRegion* find_whole_file_parent (AudioRegion&);
- void find_equivalent_playlist_regions (AudioRegion&, std::vector<AudioRegion*>& result);
+ void find_equivalent_playlist_regions (Region&, std::vector<Region*>& result);
AudioRegion *XMLRegionFactory (const XMLNode&, bool full);
@@ -698,7 +689,7 @@ class Session : public sigc::trackable, public Stateful
AudioFileSource *create_audio_source_for_session (ARDOUR::AudioDiskstream&, uint32_t which_channel, bool destructive);
- Source *get_source (ARDOUR::id_t);
+ Source *source_by_id (const PBD::ID&);
/* playlist management */
@@ -707,8 +698,6 @@ class Session : public sigc::trackable, public Stateful
sigc::signal<void,Playlist*> PlaylistAdded;
sigc::signal<void,Playlist*> PlaylistRemoved;
- Playlist *get_playlist (string name);
-
uint32_t n_playlists() const;
template<class T> void foreach_playlist (T *obj, void (T::*func)(Playlist *));
@@ -731,9 +720,9 @@ class Session : public sigc::trackable, public Stateful
/* auditioning */
- Auditioner& the_auditioner() { return *auditioner; }
+ boost::shared_ptr<Auditioner> the_auditioner() { return auditioner; }
void audition_playlist ();
- void audition_region (AudioRegion&);
+ void audition_region (Region&);
void cancel_audition ();
bool is_auditioning () const;
@@ -770,8 +759,8 @@ class Session : public sigc::trackable, public Stateful
/* control/master out */
- IO* control_out() const { return _control_out; }
- IO* master_out() const { return _master_out; }
+ boost::shared_ptr<IO> control_out() const { return _control_out; }
+ boost::shared_ptr<IO> master_out() const { return _master_out; }
/* insert/send management */
@@ -908,7 +897,7 @@ class Session : public sigc::trackable, public Stateful
/* clicking */
- IO& click_io() { return *_click_io; }
+ boost::shared_ptr<IO> click_io() { return _click_io; }
void set_clicking (bool yn);
bool get_clicking() const;
@@ -1003,14 +992,20 @@ class Session : public sigc::trackable, public Stateful
static apply_gain_to_buffer_t apply_gain_to_buffer;
static mix_buffers_with_gain_t mix_buffers_with_gain;
static mix_buffers_no_gain_t mix_buffers_no_gain;
-
+
+ static sigc::signal<void> SendFeedback;
+
+ /* Controllables */
+
+ PBD::Controllable* controllable_by_id (const PBD::ID&);
+
protected:
friend class AudioEngine;
void set_block_size (jack_nframes_t nframes);
void set_frame_rate (jack_nframes_t nframes);
protected:
- friend class AudioDiskstream;
+ friend class Diskstream;
void stop_butler ();
void wait_till_butler_finished();
@@ -1072,9 +1067,9 @@ class Session : public sigc::trackable, public Stateful
float _meter_falloff;
bool _end_location_is_free;
- void set_worst_io_latencies (bool take_lock);
+ void set_worst_io_latencies ();
void set_worst_io_latencies_x (IOChange asifwecare, void *ignored) {
- set_worst_io_latencies (true);
+ set_worst_io_latencies ();
}
void update_latency_compensation_proxy (void* ignored);
@@ -1472,12 +1467,12 @@ class Session : public sigc::trackable, public Stateful
bool waiting_to_start;
void set_auto_loop (bool yn);
- void overwrite_some_buffers (AudioDiskstream*);
+ void overwrite_some_buffers (Diskstream*);
void flush_all_redirects ();
void locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void start_locate (jack_nframes_t, bool with_roll, bool with_flush, bool with_loop=false);
void force_locate (jack_nframes_t frame, bool with_roll = false);
- void set_diskstream_speed (AudioDiskstream*, float speed);
+ void set_diskstream_speed (Diskstream*, float speed);
void set_transport_speed (float speed, bool abort = false);
void stop_transport (bool abort = false);
void start_transport ();
@@ -1508,21 +1503,21 @@ class Session : public sigc::trackable, public Stateful
/* disk-streams */
- AudioDiskstreamList audio_diskstreams;
+ DiskstreamList diskstreams;
mutable Glib::RWLock diskstream_lock;
uint32_t dstream_buffer_size;
- void add_diskstream (AudioDiskstream*);
+ void add_diskstream (Diskstream*);
int load_diskstreams (const XMLNode&);
/* routes stuff */
- RouteList routes;
- mutable Glib::RWLock route_lock;
- void add_route (Route*);
+ SerializedRCUManager<RouteList> routes;
+
+ void add_route (boost::shared_ptr<Route>);
uint32_t destructive_index;
int load_routes (const XMLNode&);
- Route* XMLRouteFactory (const XMLNode&);
+ boost::shared_ptr<Route> XMLRouteFactory (const XMLNode&);
/* mixer stuff */
@@ -1532,7 +1527,7 @@ class Session : public sigc::trackable, public Stateful
bool currently_soloing;
void route_mute_changed (void *src);
- void route_solo_changed (void *src, Route *);
+ void route_solo_changed (void *src, boost::shared_ptr<Route>);
void catch_up_on_solo ();
void update_route_solo_state ();
void modify_solo_mute (bool, bool);
@@ -1541,7 +1536,7 @@ class Session : public sigc::trackable, public Stateful
/* REGION MANAGEMENT */
mutable Glib::Mutex region_lock;
- typedef map<ARDOUR::id_t,AudioRegion *> AudioRegionList;
+ typedef map<PBD::ID,AudioRegion *> AudioRegionList;
AudioRegionList audio_regions;
void region_renamed (Region *);
@@ -1554,7 +1549,7 @@ class Session : public sigc::trackable, public Stateful
/* SOURCES */
mutable Glib::Mutex audio_source_lock;
- typedef std::map<id_t, AudioSource *> AudioSourceList;
+ typedef std::map<PBD::ID,AudioSource *> AudioSourceList;
AudioSourceList audio_sources;
@@ -1579,7 +1574,7 @@ class Session : public sigc::trackable, public Stateful
Playlist *XMLPlaylistFactory (const XMLNode&);
void playlist_length_changed (Playlist *);
- void diskstream_playlist_changed (AudioDiskstream *);
+ void diskstream_playlist_changed (Diskstream *);
/* NAMED SELECTIONS */
@@ -1599,7 +1594,7 @@ class Session : public sigc::trackable, public Stateful
/* AUDITIONING */
- Auditioner *auditioner;
+ boost::shared_ptr<Auditioner> auditioner;
void set_audition (AudioRegion*);
void non_realtime_set_audition ();
AudioRegion *pending_audition_region;
@@ -1716,7 +1711,7 @@ class Session : public sigc::trackable, public Stateful
Clicks clicks;
bool _clicking;
- IO* _click_io;
+ boost::shared_ptr<IO> _click_io;
Sample* click_data;
Sample* click_emphasis_data;
jack_nframes_t click_length;
@@ -1748,8 +1743,8 @@ class Session : public sigc::trackable, public Stateful
/* main outs */
uint32_t main_outs;
- IO* _master_out;
- IO* _control_out;
+ boost::shared_ptr<IO> _master_out;
+ boost::shared_ptr<IO> _control_out;
AutoConnectOption input_auto_connect;
AutoConnectOption output_auto_connect;
@@ -1782,8 +1777,15 @@ class Session : public sigc::trackable, public Stateful
LayerModel layer_model;
CrossfadeModel xfade_model;
+
+ typedef std::list<PBD::Controllable*> Controllables;
+ Glib::Mutex controllables_lock;
+ Controllables controllables;
+
+ void add_controllable (PBD::Controllable*);
+ void remove_controllable (PBD::Controllable*);
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __ardour_session_h__ */
diff --git a/libs/ardour/ardour/session_region.h b/libs/ardour/ardour/session_region.h
index 13d88a9aa4..4f0fb92e3b 100644
--- a/libs/ardour/ardour/session_region.h
+++ b/libs/ardour/ardour/session_region.h
@@ -10,7 +10,7 @@ template<class T> void Session::foreach_audio_region (T *obj, void (T::*func)(Au
{
Glib::Mutex::Lock lm (region_lock);
for (AudioRegionList::iterator i = audio_regions.begin(); i != audio_regions.end(); i++) {
- (obj->*func) ((*i).second);
+ (obj->*func) (i->second);
}
}
diff --git a/libs/ardour/ardour/session_route.h b/libs/ardour/ardour/session_route.h
index afe78b394e..feacc14775 100644
--- a/libs/ardour/ardour/session_route.h
+++ b/libs/ardour/ardour/session_route.h
@@ -33,14 +33,10 @@ namespace ARDOUR {
template<class T> void
Session::foreach_route (T *obj, void (T::*func)(Route&))
{
- RouteList public_order;
-
- {
- Glib::RWLock::ReaderLock lm (route_lock);
- public_order = routes;
- }
-
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
RoutePublicOrderSorter cmp;
+
public_order.sort (cmp);
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
@@ -49,16 +45,12 @@ Session::foreach_route (T *obj, void (T::*func)(Route&))
}
template<class T> void
-Session::foreach_route (T *obj, void (T::*func)(Route*))
+Session::foreach_route (T *obj, void (T::*func)(boost::shared_ptr<Route>))
{
- RouteList public_order;
-
- {
- Glib::RWLock::ReaderLock lm (route_lock);
- public_order = routes;
- }
-
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
RoutePublicOrderSorter cmp;
+
public_order.sort (cmp);
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
@@ -66,18 +58,13 @@ Session::foreach_route (T *obj, void (T::*func)(Route*))
}
}
-
template<class T, class A> void
Session::foreach_route (T *obj, void (T::*func)(Route&, A), A arg1)
{
- RouteList public_order;
-
- {
- Glib::RWLock::ReaderLock lm (route_lock);
- public_order = routes;
- }
-
+ boost::shared_ptr<RouteList> r = routes.reader();
+ RouteList public_order (*r);
RoutePublicOrderSorter cmp;
+
public_order.sort (cmp);
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); i++) {
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index 5e3c1f621d..4764339451 100644
--- a/libs/ardour/ardour/sndfilesource.h
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -51,7 +51,7 @@ class SndFileSource : public AudioFileSource {
int update_header (jack_nframes_t when, struct tm&, time_t);
int flush_header ();
- void handle_smpte_offset_change (jack_nframes_t offset, bool negative);
+ jack_nframes_t natural_position () const;
protected:
void set_header_timeline_position ();
@@ -75,7 +75,7 @@ class SndFileSource : public AudioFileSource {
int setup_broadcast_info (jack_nframes_t when, struct tm&, time_t);
};
-}; /* namespace ARDOUR */
+} // namespace ARDOUR
#endif /* __sndfile_source_h__ */
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index f3133c71cd..f57ea79854 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -25,8 +25,9 @@
#include <sigc++/signal.h>
+#include <pbd/stateful.h>
+
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
namespace ARDOUR {
@@ -40,7 +41,7 @@ class Source : public Stateful, public sigc::trackable
std::string name() const { return _name; }
int set_name (std::string str, bool destructive);
- ARDOUR::id_t id() const { return _id; }
+ const PBD::ID& id() const { return _id; }
uint32_t use_cnt() const { return _use_cnt; }
void use ();
@@ -60,7 +61,7 @@ class Source : public Stateful, public sigc::trackable
time_t _timestamp;
private:
- ARDOUR::id_t _id;
+ PBD::ID _id;
};
}
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index 13e8eb6348..db06894607 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -27,10 +27,10 @@
#include <cmath>
#include <glibmm/thread.h>
#include <pbd/undo.h>
+#include <pbd/stateful.h>
#include <sigc++/signal.h>
#include <ardour/ardour.h>
-#include <ardour/stateful.h>
#include <ardour/state_manager.h>
class XMLNode;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
new file mode 100644
index 0000000000..f16e9d29d9
--- /dev/null
+++ b/libs/ardour/ardour/track.h
@@ -0,0 +1,158 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __ardour_track_h__
+#define __ardour_track_h__
+
+#include <ardour/route.h>
+
+namespace ARDOUR {
+
+class Session;
+class Diskstream;
+class Playlist;
+class RouteGroup;
+
+class Track : public Route
+{
+ public:
+ Track (Session&, string name, Route::Flag f = Route::Flag (0), TrackMode m = Normal, DataType default_type = DataType::AUDIO);
+
+ virtual ~Track ();
+
+ int set_name (string str, void *src);
+
+ virtual int roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, int declick, bool can_record, bool rec_monitors_input) = 0;
+
+ virtual int no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool state_changing, bool can_record, bool rec_monitors_input) = 0;
+
+ virtual int silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t offset, bool can_record, bool rec_monitors_input) = 0;
+
+ void toggle_monitor_input ();
+
+ bool can_record() const { return true; }
+
+ Diskstream& diskstream() const { return *_diskstream; }
+
+ virtual int use_diskstream (string name) = 0;
+ virtual int use_diskstream (const PBD::ID& id) = 0;
+
+ TrackMode mode() const { return _mode; }
+ void set_mode (TrackMode m);
+
+ jack_nframes_t update_total_latency();
+ void set_latency_delay (jack_nframes_t);
+
+ enum FreezeState {
+ NoFreeze,
+ Frozen,
+ UnFrozen
+ };
+
+ FreezeState freeze_state() const;
+
+ virtual void freeze (InterThreadInfo&) = 0;
+ virtual void unfreeze () = 0;
+
+ virtual void bounce (InterThreadInfo&) = 0;
+ virtual void bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadInfo&) = 0;
+
+ XMLNode& get_state();
+ XMLNode& get_template();
+ virtual int set_state(const XMLNode& node) = 0;
+
+ PBD::Controllable& rec_enable_control() { return _rec_enable_control; }
+
+ bool record_enabled() const;
+ void set_record_enable (bool yn, void *src);
+
+ void set_meter_point (MeterPoint, void* src);
+
+ sigc::signal<void> ModeChanged;
+ sigc::signal<void> DiskstreamChanged;
+ sigc::signal<void> FreezeChange;
+
+ protected:
+ Track (Session& sess, const XMLNode& node, DataType default_type = DataType::AUDIO);
+
+ virtual XMLNode& state (bool full) = 0;
+
+ virtual void passthru_silence (jack_nframes_t start_frame, jack_nframes_t end_frame,
+ jack_nframes_t nframes, jack_nframes_t offset, int declick, bool meter) = 0;
+
+ virtual uint32_t n_process_buffers () = 0;
+
+ Diskstream *_diskstream;
+ MeterPoint _saved_meter_point;
+ TrackMode _mode;
+
+ //private: (FIXME)
+ struct FreezeRecordInsertInfo {
+ FreezeRecordInsertInfo(XMLNode& st, boost::shared_ptr<Insert> ins)
+ : state (st), insert (ins) {}
+
+ XMLNode state;
+ boost::shared_ptr<Insert> insert;
+ PBD::ID id;
+ UndoAction memento;
+ };
+
+ struct FreezeRecord {
+ FreezeRecord()
+ : playlist(0)
+ , have_mementos(false)
+ {}
+
+ ~FreezeRecord();
+
+ Playlist* playlist;
+ vector<FreezeRecordInsertInfo*> insert_info;
+ bool have_mementos;
+ FreezeState state;
+ };
+
+ struct RecEnableControllable : public PBD::Controllable {
+ RecEnableControllable (Track&);
+
+ void set_value (float);
+ float get_value (void) const;
+
+ Track& track;
+ };
+
+ //virtual void diskstream_record_enable_changed (void *src) = 0;
+ //virtual void diskstream_input_channel_changed (void *src) = 0;
+
+ //virtual void input_change_handler (void *src) = 0;
+
+ virtual void set_state_part_two () = 0;
+
+ FreezeRecord _freeze_record;
+ XMLNode* pending_state;
+ sigc::connection recenable_connection;
+ sigc::connection ic_connection;
+ RecEnableControllable _rec_enable_control;
+ bool _destructive;
+};
+
+}; /* namespace ARDOUR*/
+
+#endif /* __ardour_track_h__ */
diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h
index a0a209b569..b2230f12d7 100644
--- a/libs/ardour/ardour/types.h
+++ b/libs/ardour/ardour/types.h
@@ -30,6 +30,8 @@
#include <inttypes.h>
#include <jack/types.h>
#include <control_protocol/smpte.h>
+#include <pbd/id.h>
+
#include <map>
#if __GNUC__ < 3
@@ -45,7 +47,7 @@ namespace ARDOUR {
typedef float pan_t;
typedef float gain_t;
typedef uint32_t layer_t;
- typedef uint64_t id_t;
+ typedef uint64_t microseconds_t;
enum IOChange {
NoChange = 0,
@@ -69,7 +71,7 @@ namespace ARDOUR {
PanAutomation = 0x2,
PluginAutomation = 0x4,
SoloAutomation = 0x8,
- MuteAutomation = 0x10,
+ MuteAutomation = 0x10
};
enum AutoState {
@@ -188,10 +190,10 @@ namespace ARDOUR {
enum EditMode {
Slide,
- Splice,
+ Splice
};
- enum RegionPoint {
+ enum RegionPoint {
Start,
End,
SyncPoint
@@ -241,7 +243,7 @@ namespace ARDOUR {
PeakDatum min;
PeakDatum max;
};
-};
+}
std::istream& operator>>(std::istream& o, ARDOUR::SampleFormat& sf);
std::istream& operator>>(std::istream& o, ARDOUR::HeaderFormat& sf);
diff --git a/libs/ardour/ardour/utils.h b/libs/ardour/ardour/utils.h
index 3a9905b3ac..ee4482d260 100644
--- a/libs/ardour/ardour/utils.h
+++ b/libs/ardour/ardour/utils.h
@@ -25,6 +25,10 @@
#include <string>
#include <cmath>
+#ifdef HAVE_COREAUDIO
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
#include "ardour.h"
class XMLNode;
@@ -50,9 +54,11 @@ int tokenize_fullpath (std::string fullpath, std::string& path, std::string& nam
int touch_file(std::string path);
-uint32_t long get_uid();
-
std::string region_name_from_path (std::string path);
std::string path_expand (std::string);
+#ifdef HAVE_COREAUDIO
+std::string CFStringRefToStdString(CFStringRef stringRef);
+#endif // HAVE_COREAUDIO
+
#endif /* __ardour_utils_h__ */
diff --git a/libs/ardour/ardour/vst_plugin.h b/libs/ardour/ardour/vst_plugin.h
index ee8e6e986b..3636fe275a 100644
--- a/libs/ardour/ardour/vst_plugin.h
+++ b/libs/ardour/ardour/vst_plugin.h
@@ -28,11 +28,9 @@
#include <string>
#include <dlfcn.h>
-#include <midi++/controllable.h>
#include <sigc++/signal.h>
-
+#include <pbd/stateful.h>
#include <jack/types.h>
-#include <ardour/stateful.h>
#include <ardour/plugin_state.h>
#include <ardour/plugin.h>
@@ -106,6 +104,14 @@ class VSTPlugin : public ARDOUR::Plugin
bool been_resumed;
};
-}
+class VSTPluginInfo : public PluginInfo
+{
+ VSTPluginInfo () {}
+ ~VSTPluginInfo () {}
+
+ PluginPtr load (Session& session);
+};
+
+} // namespace ARDOUR
#endif /* __ardour_vst_plugin_h__ */
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 977616dd8b..7d2a2103bb 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000-2003 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -14,8 +14,6 @@
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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
*/
#include <fstream>
@@ -23,6 +21,7 @@
#include <unistd.h>
#include <cmath>
#include <cerrno>
+#include <cassert>
#include <string>
#include <climits>
#include <fcntl.h>
@@ -56,32 +55,30 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-jack_nframes_t AudioDiskstream::disk_io_chunk_frames;
-
-sigc::signal<void,AudioDiskstream*> AudioDiskstream::AudioDiskstreamCreated;
-sigc::signal<void,list<AudioFileSource*>*> AudioDiskstream::DeleteSources;
-sigc::signal<void> AudioDiskstream::DiskOverrun;
-sigc::signal<void> AudioDiskstream::DiskUnderrun;
+size_t AudioDiskstream::_working_buffers_size = 0;
+Sample* AudioDiskstream::_mixdown_buffer = 0;
+gain_t* AudioDiskstream::_gain_buffer = 0;
+char* AudioDiskstream::_conversion_buffer = 0;
-AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Flag flag)
- : _name (name),
- _session (sess)
+AudioDiskstream::AudioDiskstream (Session &sess, const string &name, Diskstream::Flag flag)
+ : Diskstream(sess, name, flag)
+ , deprecated_io_node(NULL)
{
/* prevent any write sources from being created */
in_set_state = true;
- init (flag);
+ init(flag);
use_new_playlist ();
in_set_state = false;
- AudioDiskstreamCreated (this); /* EMIT SIGNAL */
+ DiskstreamCreated (this); /* EMIT SIGNAL */
}
AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
- : _session (sess)
-
+ : Diskstream(sess, node)
+ , deprecated_io_node(NULL)
{
in_set_state = true;
init (Recordable);
@@ -97,7 +94,7 @@ AudioDiskstream::AudioDiskstream (Session& sess, const XMLNode& node)
use_destructive_playlist ();
}
- AudioDiskstreamCreated (this); /* EMIT SIGNAL */
+ DiskstreamCreated (this); /* EMIT SIGNAL */
}
void
@@ -130,44 +127,9 @@ AudioDiskstream::init_channel (ChannelInfo &chan)
void
-AudioDiskstream::init (Flag f)
+AudioDiskstream::init (Diskstream::Flag f)
{
- _id = new_id();
- _refcnt = 0;
- _flags = f;
- _io = 0;
- _alignment_style = ExistingMaterial;
- _persistent_alignment_style = ExistingMaterial;
- first_input_change = true;
- _playlist = 0;
- i_am_the_modifier = 0;
- g_atomic_int_set (&_record_enabled, 0);
- was_recording = false;
- capture_start_frame = 0;
- capture_captured = 0;
- _visible_speed = 1.0f;
- _actual_speed = 1.0f;
- _buffer_reallocation_required = false;
- _seek_required = false;
- first_recordable_frame = max_frames;
- last_recordable_frame = max_frames;
- _roll_delay = 0;
- _capture_offset = 0;
- _processed = false;
- _slaved = false;
- adjust_capture_position = 0;
- last_possibly_recording = 0;
- loop_location = 0;
- wrap_buffer_size = 0;
- speed_buffer_size = 0;
- last_phase = 0;
- phi = (uint64_t) (0x1000000);
- file_frame = 0;
- playback_sample = 0;
- playback_distance = 0;
- _read_data_count = 0;
- _write_data_count = 0;
- deprecated_io_node = 0;
+ Diskstream::init(f);
/* there are no channels at this point, so these
two calls just get speed_buffer_size and wrap_buffer
@@ -177,13 +139,8 @@ AudioDiskstream::init (Flag f)
set_block_size (_session.get_block_size());
allocate_temporary_buffers ();
- pending_overwrite = false;
- overwrite_frame = 0;
- overwrite_queued = false;
- input_change_pending = NoChange;
-
add_channel ();
- _n_channels = 1;
+ assert(_n_channels == 1);
}
void
@@ -217,26 +174,33 @@ AudioDiskstream::~AudioDiskstream ()
{
Glib::Mutex::Lock lm (state_lock);
- if (_playlist) {
- _playlist->unref ();
- }
-
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan)
destroy_channel((*chan));
- }
channels.clear();
}
void
-AudioDiskstream::handle_input_change (IOChange change, void *src)
+AudioDiskstream::allocate_working_buffers()
{
- Glib::Mutex::Lock lm (state_lock);
+ assert(disk_io_frames() > 0);
- if (!(input_change_pending & change)) {
- input_change_pending = IOChange (input_change_pending|change);
- _session.request_input_change_handling ();
- }
+ _working_buffers_size = disk_io_frames();
+ _mixdown_buffer = new Sample[_working_buffers_size];
+ _gain_buffer = new gain_t[_working_buffers_size];
+ _conversion_buffer = new char[_working_buffers_size * 4];
+}
+
+void
+AudioDiskstream::free_working_buffers()
+{
+ delete _mixdown_buffer;
+ delete _gain_buffer;
+ delete _conversion_buffer;
+ _working_buffers_size = 0;
+ _mixdown_buffer = 0;
+ _gain_buffer = 0;
+ _conversion_buffer = 0;
}
void
@@ -334,9 +298,9 @@ AudioDiskstream::find_and_use_playlist (const string& name)
Playlist* pl;
AudioPlaylist* playlist;
- if ((pl = _session.get_playlist (name)) == 0) {
- error << string_compose(_("AudioDiskstream: Session doesn't know about a Playlist called \"%1\""), name) << endmsg;
- return -1;
+ if ((pl = _session.playlist_by_name (name)) == 0) {
+ playlist = new AudioPlaylist(_session, name);
+ pl = playlist;
}
if ((playlist = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
@@ -348,57 +312,15 @@ AudioDiskstream::find_and_use_playlist (const string& name)
}
int
-AudioDiskstream::use_playlist (AudioPlaylist* playlist)
+AudioDiskstream::use_playlist (Playlist* playlist)
{
- {
- Glib::Mutex::Lock lm (state_lock);
-
- if (playlist == _playlist) {
- return 0;
- }
+ assert(dynamic_cast<AudioPlaylist*>(playlist));
- plstate_connection.disconnect();
- plmod_connection.disconnect ();
- plgone_connection.disconnect ();
-
- if (_playlist) {
- _playlist->unref();
- }
-
- _playlist = playlist;
- _playlist->ref();
-
- if (!in_set_state && recordable()) {
- reset_write_sources (false);
- }
-
- plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &AudioDiskstream::playlist_changed));
- plmod_connection = _playlist->Modified.connect (mem_fun (*this, &AudioDiskstream::playlist_modified));
- plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &AudioDiskstream::playlist_deleted));
- }
-
- if (!overwrite_queued) {
- _session.request_overwrite_buffer (this);
- overwrite_queued = true;
- }
-
- PlaylistChanged (); /* EMIT SIGNAL */
- _session.set_dirty ();
+ Diskstream::use_playlist(playlist);
return 0;
}
-void
-AudioDiskstream::playlist_deleted (Playlist* pl)
-{
- /* this catches an ordering issue with session destruction. playlists
- are destroyed before diskstreams. we have to invalidate any handles
- we have to the playlist.
- */
-
- _playlist = 0;
-}
-
int
AudioDiskstream::use_new_playlist ()
{
@@ -426,6 +348,8 @@ AudioDiskstream::use_new_playlist ()
int
AudioDiskstream::use_copy_playlist ()
{
+ assert(audio_playlist());
+
if (destructive()) {
return 0;
}
@@ -440,7 +364,7 @@ AudioDiskstream::use_copy_playlist ()
newname = Playlist::bump_name (_playlist->name(), _session);
- if ((playlist = new AudioPlaylist (*_playlist, newname)) != 0) {
+ if ((playlist = new AudioPlaylist (*audio_playlist(), newname)) != 0) {
playlist->set_orig_diskstream_id (id());
return use_playlist (playlist);
} else {
@@ -459,8 +383,10 @@ AudioDiskstream::setup_destructive_playlist ()
/* a single full-sized region */
+ cerr << "setup DS using " << srcs.front()->natural_position () << endl;
+
AudioRegion* region = new AudioRegion (srcs, 0, max_frames, _name);
- _playlist->add_region (*region, 0);
+ _playlist->add_region (*region, srcs.front()->natural_position());
}
void
@@ -488,6 +414,7 @@ AudioDiskstream::use_destructive_playlist ()
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
(*chan).write_source = dynamic_cast<AudioFileSource*>(&region->source (n));
+ assert((*chan).write_source);
(*chan).write_source->set_allow_remove_if_empty (false);
}
@@ -495,104 +422,6 @@ AudioDiskstream::use_destructive_playlist ()
}
void
-AudioDiskstream::set_io (IO& io)
-{
- _io = &io;
- set_align_style_from_io ();
-}
-
-int
-AudioDiskstream::set_name (string str, void *src)
-{
- if (str != _name) {
- _playlist->set_name (str);
- _name = str;
-
- if (!in_set_state && recordable()) {
- /* rename existing capture files so that they have the correct name */
- return rename_write_sources ();
- } else {
- return -1;
- }
- }
-
- return 0;
-}
-
-void
-AudioDiskstream::set_speed (double sp)
-{
- _session.request_diskstream_speed (*this, sp);
-
- /* to force a rebuffering at the right place */
- playlist_modified();
-}
-
-bool
-AudioDiskstream::realtime_set_speed (double sp, bool global)
-{
- bool changed = false;
- double new_speed = sp * _session.transport_speed();
-
- if (_visible_speed != sp) {
- _visible_speed = sp;
- changed = true;
- }
-
- if (new_speed != _actual_speed) {
-
- jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
- fabs (new_speed)) + 1;
-
- if (required_wrap_size > wrap_buffer_size) {
- _buffer_reallocation_required = true;
- }
-
- _actual_speed = new_speed;
- phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
- }
-
- if (changed) {
- if (!global) {
- _seek_required = true;
- }
- speed_changed (); /* EMIT SIGNAL */
- }
-
- return _buffer_reallocation_required || _seek_required;
-}
-
-void
-AudioDiskstream::non_realtime_set_speed ()
-{
- if (_buffer_reallocation_required)
- {
- Glib::Mutex::Lock lm (state_lock);
- allocate_temporary_buffers ();
-
- _buffer_reallocation_required = false;
- }
-
- if (_seek_required) {
- if (speed() != 1.0f || speed() != -1.0f) {
- seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
- }
- else {
- seek (_session.transport_frame(), true);
- }
-
- _seek_required = false;
- }
-}
-
-void
-AudioDiskstream::prepare ()
-{
- _processed = false;
- playback_distance = 0;
-}
-
-void
AudioDiskstream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t nframes, bool can_record)
{
int possibly_recording;
@@ -755,7 +584,7 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes
returns a non-zero value, in which case, ::commit should not be called.
*/
- // If we can't take the state lock return.
+ // If we can't take the state lock return.
if (!state_lock.trylock()) {
return 1;
}
@@ -1011,13 +840,6 @@ AudioDiskstream::process (jack_nframes_t transport_frame, jack_nframes_t nframes
return ret;
}
-void
-AudioDiskstream::recover ()
-{
- state_lock.unlock();
- _processed = false;
-}
-
bool
AudioDiskstream::commit (jack_nframes_t nframes)
{
@@ -1153,13 +975,19 @@ AudioDiskstream::seek (jack_nframes_t frame, bool complete_refill)
(*chan).capture_buf->reset ();
}
+ /* can't rec-enable in destructive mode if transport is before start */
+
+ if (destructive() && record_enabled() && frame < _session.current_start_frame()) {
+ disengage_record_enable ();
+ }
+
playback_sample = frame;
file_frame = frame;
if (complete_refill) {
- while ((ret = do_refill (0, 0, 0)) > 0);
+ while ((ret = do_refill_with_alloc ()) > 0) ;
} else {
- ret = do_refill (0, 0, 0);
+ ret = do_refill_with_alloc ();
}
return ret;
@@ -1251,7 +1079,7 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
this_read = min(cnt,this_read);
- if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
+ if (audio_playlist()->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
error << string_compose(_("AudioDiskstream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
start) << endmsg;
return -1;
@@ -1285,14 +1113,27 @@ AudioDiskstream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer,
}
int
-AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
+AudioDiskstream::do_refill_with_alloc()
+{
+ Sample* mix_buf = new Sample[disk_io_chunk_frames];
+ float* gain_buf = new float[disk_io_chunk_frames];
+ char* work_buf = new char[disk_io_chunk_frames * 4];
+
+ int ret = _do_refill(mix_buf, gain_buf, work_buf);
+
+ delete [] mix_buf;
+ delete [] gain_buf;
+ delete [] work_buf;
+
+ return ret;
+}
+
+int
+AudioDiskstream::_do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
{
int32_t ret = 0;
jack_nframes_t to_read;
RingBufferNPT<Sample>::rw_vector vector;
- bool free_mixdown;
- bool free_gain;
- bool free_workbuf;
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
jack_nframes_t total_space;
jack_nframes_t zero_fill;
@@ -1300,6 +1141,10 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
ChannelList::iterator i;
jack_nframes_t ts;
+ assert(mixdown_buffer);
+ assert(gain_buffer);
+ assert(workbuf);
+
channels.front().playback_buf->get_write_vector (&vector);
if ((total_space = vector.len[0] + vector.len[1]) == 0) {
@@ -1406,33 +1251,6 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
zero_fill = 0;
}
}
-
- /* Please note: the code to allocate buffers isn't run
- during normal butler thread operation. Its there
- for other times when we need to call do_refill()
- from somewhere other than the butler thread.
- */
-
- if (mixdown_buffer == 0) {
- mixdown_buffer = new Sample[disk_io_chunk_frames];
- free_mixdown = true;
- } else {
- free_mixdown = false;
- }
-
- if (gain_buffer == 0) {
- gain_buffer = new float[disk_io_chunk_frames];
- free_gain = true;
- } else {
- free_gain = false;
- }
-
- if (workbuf == 0) {
- workbuf = new char[disk_io_chunk_frames * 4];
- free_workbuf = true;
- } else {
- free_workbuf = false;
- }
jack_nframes_t file_frame_tmp = 0;
@@ -1501,37 +1319,30 @@ AudioDiskstream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * w
file_frame = file_frame_tmp;
out:
- if (free_mixdown) {
- delete [] mixdown_buffer;
- }
- if (free_gain) {
- delete [] gain_buffer;
- }
- if (free_workbuf) {
- delete [] workbuf;
- }
return ret;
}
+/** Flush pending data to disk.
+ *
+ * Important note: this function will write *AT MOST* disk_io_chunk_frames
+ * of data to disk. it will never write more than that. If it writes that
+ * much and there is more than that waiting to be written, it will return 1,
+ * otherwise 0 on success or -1 on failure.
+ *
+ * If there is less than disk_io_chunk_frames to be written, no data will be
+ * written at all unless @a force_flush is true.
+ */
int
-AudioDiskstream::do_flush (char * workbuf, bool force_flush)
+AudioDiskstream::do_flush (Session::RunContext context, bool force_flush)
{
+ char* workbuf = _session.conversion_buffer(context);
+
uint32_t to_write;
int32_t ret = 0;
RingBufferNPT<Sample>::rw_vector vector;
RingBufferNPT<CaptureTransition>::rw_vector transvec;
jack_nframes_t total;
-
- /* important note: this function will write *AT MOST*
- disk_io_chunk_frames of data to disk. it will never
- write more than that. if its writes that much and there
- is more than that waiting to be written, it will return 1,
- otherwise 0 on success or -1 on failure.
-
- if there is less than disk_io_chunk_frames to be written,
- no data will be written at all unless `force_flush' is true.
- */
_write_data_count = 0;
@@ -1546,7 +1357,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
goto out;
}
-
/* if there are 2+ chunks of disk i/o possible for
this track, let the caller know so that it can arrange
for us to be called again, ASAP.
@@ -1564,7 +1374,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
-
// check the transition buffer when recording destructive
// important that we get this after the capture buf
@@ -1652,21 +1461,6 @@ AudioDiskstream::do_flush (char * workbuf, bool force_flush)
}
void
-AudioDiskstream::playlist_changed (Change ignored)
-{
- playlist_modified ();
-}
-
-void
-AudioDiskstream::playlist_modified ()
-{
- if (!i_am_the_modifier && !overwrite_queued) {
- _session.request_overwrite_buffer (this);
- overwrite_queued = true;
- }
-}
-
-void
AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture)
{
uint32_t buffer_position;
@@ -1679,7 +1473,6 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
ChannelList::iterator chan;
vector<CaptureInfo*>::iterator ci;
uint32_t n = 0;
- list<AudioFileSource*>* deletion_list;
bool mark_write_completed = false;
finish_capture (true);
@@ -1689,7 +1482,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
*/
while (more_work && !err) {
- switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
+ switch (do_flush (Session::TransportContext, true)) {
case 0:
more_work = false;
break;
@@ -1712,7 +1505,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
ChannelList::iterator chan;
- deletion_list = new list<AudioFileSource*>;
+ list<Source*>* deletion_list = new list<Source*>;
for ( chan = channels.begin(); chan != channels.end(); ++chan) {
@@ -1900,17 +1693,17 @@ AudioDiskstream::finish_capture (bool rec_monitors_input)
}
void
-AudioDiskstream::set_record_enabled (bool yn, void* src)
+AudioDiskstream::set_record_enabled (bool yn)
{
- bool rolling = _session.transport_speed() != 0.0f;
-
if (!recordable() || !_session.record_enabling_legal()) {
return;
}
-
- /* if we're turning on rec-enable, there needs to be an
- input connection.
- */
+
+ /* can't rec-enable in destructive mode if transport is before start */
+
+ if (destructive() && yn && _session.transport_frame() < _session.current_start_frame()) {
+ return;
+ }
if (yn && channels[0].source == 0) {
@@ -1927,42 +1720,57 @@ AudioDiskstream::set_record_enabled (bool yn, void* src)
if (record_enabled() != yn) {
if (yn) {
- g_atomic_int_set (&_record_enabled, 1);
- capturing_sources.clear ();
- if (Config->get_use_hardware_monitoring()) {
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
- if ((*chan).source) {
- (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
- }
- capturing_sources.push_back ((*chan).write_source);
- }
- } else {
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
- capturing_sources.push_back ((*chan).write_source);
- }
- }
-
+ engage_record_enable ();
} else {
- g_atomic_int_set (&_record_enabled, 0);
- if (Config->get_use_hardware_monitoring()) {
- for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
- if ((*chan).source) {
- (*chan).source->request_monitor_input (false);
- }
- }
+ disengage_record_enable ();
+ }
+ }
+}
+
+void
+AudioDiskstream::engage_record_enable ()
+{
+ bool rolling = _session.transport_speed() != 0.0f;
+
+ g_atomic_int_set (&_record_enabled, 1);
+ capturing_sources.clear ();
+ if (Config->get_use_hardware_monitoring()) {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ if ((*chan).source) {
+ (*chan).source->request_monitor_input (!(_session.get_auto_input() && rolling));
}
- capturing_sources.clear ();
+ capturing_sources.push_back ((*chan).write_source);
+ }
+ } else {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ capturing_sources.push_back ((*chan).write_source);
}
+ }
+
+ RecordEnableChanged (); /* EMIT SIGNAL */
+}
- record_enable_changed (src); /* EMIT SIGNAL */
+void
+AudioDiskstream::disengage_record_enable ()
+{
+ g_atomic_int_set (&_record_enabled, 0);
+ if (Config->get_use_hardware_monitoring()) {
+ for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
+ if ((*chan).source) {
+ (*chan).source->request_monitor_input (false);
+ }
+ }
}
+ capturing_sources.clear ();
+ RecordEnableChanged (); /* EMIT SIGNAL */
}
+
XMLNode&
AudioDiskstream::get_state ()
{
XMLNode* node = new XMLNode ("AudioDiskstream");
- char buf[64];
+ char buf[64] = "";
LocaleGuard lg (X_("POSIX"));
snprintf (buf, sizeof(buf), "0x%x", _flags);
@@ -1977,7 +1785,7 @@ AudioDiskstream::get_state ()
node->add_property ("speed", buf);
node->add_property("name", _name);
- snprintf (buf, sizeof(buf), "%" PRIu64, id());
+ id().print (buf);
node->add_property("id", buf);
if (!capturing_sources.empty() && _session.get_record_enabled()) {
@@ -2044,11 +1852,11 @@ AudioDiskstream::set_state (const XMLNode& node)
if (deprecated_io_node) {
if ((prop = deprecated_io_node->property ("id")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+ _id = prop->value ();
}
} else {
if ((prop = node.property ("id")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+ _id = prop->value ();
}
}
@@ -2061,8 +1869,7 @@ AudioDiskstream::set_state (const XMLNode& node)
}
// create necessary extra channels
- // we are always constructed with one
- // and we always need one
+ // we are always constructed with one and we always need one
if (nchans > _n_channels) {
@@ -2293,23 +2100,6 @@ AudioDiskstream::monitor_input (bool yn)
}
void
-AudioDiskstream::set_capture_offset ()
-{
- if (_io == 0) {
- /* can't capture, so forget it */
- return;
- }
-
- _capture_offset = _io->input_latency();
-}
-
-void
-AudioDiskstream::set_persistent_align_style (AlignStyle a)
-{
- _persistent_alignment_style = a;
-}
-
-void
AudioDiskstream::set_align_style_from_io ()
{
bool have_physical = false;
@@ -2334,20 +2124,6 @@ AudioDiskstream::set_align_style_from_io ()
}
}
-void
-AudioDiskstream::set_align_style (AlignStyle a)
-{
- if (record_enabled() && _session.actively_recording()) {
- return;
- }
-
-
- if (a != _alignment_style) {
- _alignment_style = a;
- AlignmentStyleChanged ();
- }
-}
-
int
AudioDiskstream::add_channel ()
{
@@ -2399,58 +2175,6 @@ AudioDiskstream::capture_buffer_load () const
}
int
-AudioDiskstream::set_loop (Location *location)
-{
- if (location) {
- if (location->start() >= location->end()) {
- error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
- return -1;
- }
- }
-
- loop_location = location;
-
- LoopSet (location); /* EMIT SIGNAL */
- return 0;
-}
-
-jack_nframes_t
-AudioDiskstream::get_capture_start_frame (uint32_t n)
-{
- Glib::Mutex::Lock lm (capture_info_lock);
-
- if (capture_info.size() > n) {
- return capture_info[n]->start;
- }
- else {
- return capture_start_frame;
- }
-}
-
-jack_nframes_t
-AudioDiskstream::get_captured_frames (uint32_t n)
-{
- Glib::Mutex::Lock lm (capture_info_lock);
-
- if (capture_info.size() > n) {
- return capture_info[n]->frames;
- }
- else {
- return capture_captured;
- }
-}
-
-void
-AudioDiskstream::punch_in ()
-{
-}
-
-void
-AudioDiskstream::punch_out ()
-{
-}
-
-int
AudioDiskstream::use_pending_capture_data (XMLNode& node)
{
const XMLProperty* prop;
@@ -2545,22 +2269,3 @@ AudioDiskstream::use_pending_capture_data (XMLNode& node)
return 0;
}
-
-void
-AudioDiskstream::set_roll_delay (jack_nframes_t nframes)
-{
- _roll_delay = nframes;
-}
-
-void
-AudioDiskstream::set_destructive (bool yn)
-{
- if (yn != destructive()) {
- reset_write_sources (true, true);
- if (yn) {
- _flags |= Destructive;
- } else {
- _flags &= ~Destructive;
- }
- }
-}
diff --git a/libs/ardour/audio_library.cc b/libs/ardour/audio_library.cc
index 7f421e86c8..ad008f6312 100644
--- a/libs/ardour/audio_library.cc
+++ b/libs/ardour/audio_library.cc
@@ -46,6 +46,8 @@ using namespace PBD;
static char* SOUNDFILE = "http://ardour.org/ontology/Soundfile";
+string AudioLibrary::state_node_name = "AudioLibrary";
+
AudioLibrary::AudioLibrary ()
{
// sfdb_paths.push_back("/Users/taybin/sounds");
@@ -74,8 +76,6 @@ AudioLibrary::AudioLibrary ()
}
lrdf_free_statements(matches);
-
- scan_paths();
}
AudioLibrary::~AudioLibrary ()
@@ -356,6 +356,8 @@ void
AudioLibrary::set_paths (vector<string> paths)
{
sfdb_paths = paths;
+
+ scan_paths ();
}
vector<string>
@@ -429,5 +431,50 @@ AudioLibrary::safe_file_extension(string file)
file.rfind(".maud")== string::npos &&
file.rfind(".vwe") == string::npos &&
file.rfind(".paf") == string::npos &&
+#ifdef HAVE_COREAUDIO
+ file.rfind(".mp3") == string::npos &&
+ file.rfind(".aac") == string::npos &&
+ file.rfind(".mp4") == string::npos &&
+#endif // HAVE_COREAUDIO
file.rfind(".voc") == string::npos);
}
+
+XMLNode&
+AudioLibrary::get_state ()
+{
+ XMLNode* root = new XMLNode(X_("AudioLibrary"));
+
+ for (vector<string>::iterator i = sfdb_paths.begin(); i != sfdb_paths.end(); ++i) {
+ XMLNode* node = new XMLNode(X_("Path"));
+ node->add_property("value", *i);
+ root->add_child_nocopy(*node);
+ }
+
+ return *root;
+}
+
+int
+AudioLibrary::set_state (const XMLNode& node)
+{
+ if (node.name() != X_("AudioLibrary")) {
+ fatal << "programming error: AudioLibrary: incorrect XML node sent to set_state()" << endmsg;
+ return -1;
+ }
+
+ XMLNodeList nodes = node.children(X_("Path"));
+
+ vector<string> paths;
+ XMLProperty* prop;
+ XMLNode* child;
+ for (XMLNodeConstIterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
+ child = *iter;
+
+ if ((prop = child->property(X_("value"))) != 0) {
+ paths.push_back(prop->value());
+ }
+ }
+
+ set_paths (paths);
+
+ return 0;
+}
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index 85c11647f4..93d380679d 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -243,16 +243,18 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ch
for (vector<uint32_t>::iterator l = relevant_layers.begin(); l != relevant_layers.end(); ++l) {
+ // FIXME: Should be vector<AudioRegion*>
vector<Region*>& r (relevant_regions[*l]);
vector<Crossfade*>& x (relevant_xfades[*l]);
for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
- (*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
- _read_data_count += (*i)->read_data_count();
+ AudioRegion* const ar = dynamic_cast<AudioRegion*>(*i);
+ assert(ar);
+ ar->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
+ _read_data_count += ar->read_data_count();
}
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
-
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
/* don't JACK up _read_data_count, since its the same data as we just
@@ -880,38 +882,6 @@ AudioPlaylist::crossfade_changed (Change ignored)
notify_modified ();
}
-void
-AudioPlaylist::get_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
-{
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
- AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
-
- if (ar) {
- if (Config->get_use_overlap_equivalency()) {
- if (ar->overlap_equivalent (other)) {
- results.push_back (ar);
- } else if (ar->equivalent (other)) {
- results.push_back (ar);
- }
- }
- }
- }
-}
-
-void
-AudioPlaylist::get_region_list_equivalent_regions (const AudioRegion& other, vector<AudioRegion*>& results)
-{
- for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-
- AudioRegion* ar = dynamic_cast<AudioRegion*> (*i);
-
- if (ar && ar->region_list_equivalent (other)) {
- results.push_back (ar);
- }
- }
-}
-
bool
AudioPlaylist::region_changed (Change what_changed, Region* region)
{
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 74b7dd071c..78af23e3df 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -41,9 +41,7 @@ using namespace ARDOUR;
using namespace PBD;
AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode mode)
- : Route (sess, name, 1, -1, -1, -1, flag),
- diskstream (0),
- _midi_rec_enable_control (*this, _session.midi_port())
+ : Track (sess, name, flag, mode)
{
AudioDiskstream::Flag dflags = AudioDiskstream::Flag (0);
@@ -59,54 +57,34 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode
AudioDiskstream* ds = new AudioDiskstream (_session, name, dflags);
- _declickable = true;
- _freeze_record.state = NoFreeze;
- _saved_meter_point = _meter_point;
- _mode = mode;
-
set_diskstream (*ds, this);
-
- // session.SMPTEOffsetChanged.connect (mem_fun (*this, &AudioTrack::handle_smpte_offset_change));
-
- // we do this even though Route already did it in it's init
- reset_midi_control (_session.midi_port(), _session.get_midi_control());
-
}
AudioTrack::AudioTrack (Session& sess, const XMLNode& node)
- : Route (sess, "to be renamed", 0, 0, -1, -1),
- diskstream (0),
- _midi_rec_enable_control (*this, _session.midi_port())
+ : Track (sess, node)
{
- _freeze_record.state = NoFreeze;
set_state (node);
- _declickable = true;
- _saved_meter_point = _meter_point;
-
- // we do this even though Route already did it in it's init
- reset_midi_control (_session.midi_port(), _session.get_midi_control());
}
AudioTrack::~AudioTrack ()
{
- if (diskstream) {
- diskstream->unref();
- }
}
int
AudioTrack::deprecated_use_diskstream_connections ()
{
- if (diskstream->deprecated_io_node == 0) {
+ AudioDiskstream& diskstream = audio_diskstream();
+
+ if (diskstream.deprecated_io_node == 0) {
return 0;
}
const XMLProperty* prop;
- XMLNode& node (*diskstream->deprecated_io_node);
+ XMLNode& node (*diskstream.deprecated_io_node);
/* don't do this more than once. */
- diskstream->deprecated_io_node = 0;
+ diskstream.deprecated_io_node = 0;
set_input_minimum (-1);
set_input_maximum (-1);
@@ -149,15 +127,15 @@ AudioTrack::deprecated_use_diskstream_connections ()
int
AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
{
- if (diskstream) {
- diskstream->unref();
+ if (_diskstream) {
+ _diskstream->unref();
}
- diskstream = &ds.ref();
- diskstream->set_io (*this);
- diskstream->set_destructive (_mode == Destructive);
+ _diskstream = &ds.ref();
+ _diskstream->set_io (*this);
+ _diskstream->set_destructive (_mode == Destructive);
- if (diskstream->deprecated_io_node) {
+ if (audio_diskstream().deprecated_io_node) {
if (!connecting_legal) {
ConnectingLegal.connect (mem_fun (*this, &AudioTrack::deprecated_use_diskstream_connections));
@@ -166,13 +144,13 @@ AudioTrack::set_diskstream (AudioDiskstream& ds, void *src)
}
}
- diskstream->set_record_enabled (false, this);
- diskstream->monitor_input (false);
+ _diskstream->set_record_enabled (false);
+ _diskstream->monitor_input (false);
ic_connection.disconnect();
- ic_connection = input_changed.connect (mem_fun (*diskstream, &AudioDiskstream::handle_input_change));
+ ic_connection = input_changed.connect (mem_fun (*_diskstream, &Diskstream::handle_input_change));
- diskstream_changed (src); /* EMIT SIGNAL */
+ DiskstreamChanged (); /* EMIT SIGNAL */
return 0;
}
@@ -182,8 +160,8 @@ AudioTrack::use_diskstream (string name)
{
AudioDiskstream *dstream;
- if ((dstream = _session.diskstream_by_name (name)) == 0) {
- error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), name) << endmsg;
+ if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_name (name))) == 0) {
+ error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), name) << endmsg;
return -1;
}
@@ -191,60 +169,22 @@ AudioTrack::use_diskstream (string name)
}
int
-AudioTrack::use_diskstream (id_t id)
+AudioTrack::use_diskstream (const PBD::ID& id)
{
AudioDiskstream *dstream;
- if ((dstream = _session.diskstream_by_id (id)) == 0) {
- error << string_compose(_("AudioTrack: diskstream \"%1\" not known by session"), id) << endmsg;
+ if ((dstream = dynamic_cast<AudioDiskstream*>(_session.diskstream_by_id (id))) == 0) {
+ error << string_compose(_("AudioTrack: audio diskstream \"%1\" not known by session"), id) << endmsg;
return -1;
}
return set_diskstream (*dstream, this);
}
-bool
-AudioTrack::record_enabled () const
+AudioDiskstream&
+AudioTrack::audio_diskstream() const
{
- return diskstream->record_enabled ();
-}
-
-void
-AudioTrack::set_record_enable (bool yn, void *src)
-{
- if (_freeze_record.state == Frozen) {
- return;
- }
-
- if (_mix_group && src != _mix_group && _mix_group->is_active()) {
- _mix_group->apply (&AudioTrack::set_record_enable, yn, _mix_group);
- return;
- }
-
- /* keep track of the meter point as it was before we rec-enabled */
-
- if (!diskstream->record_enabled()) {
- _saved_meter_point = _meter_point;
- }
-
- diskstream->set_record_enabled (yn, src);
-
- if (diskstream->record_enabled()) {
- set_meter_point (MeterInput, this);
- } else {
- set_meter_point (_saved_meter_point, this);
- }
-
- if (_session.get_midi_feedback()) {
- _midi_rec_enable_control.send_feedback (record_enabled());
- }
-
-}
-
-void
-AudioTrack::set_meter_point (MeterPoint p, void *src)
-{
- Route::set_meter_point (p, src);
+ return *dynamic_cast<AudioDiskstream*>(_diskstream);
}
int
@@ -252,7 +192,6 @@ AudioTrack::set_state (const XMLNode& node)
{
const XMLProperty *prop;
XMLNodeConstIterator iter;
- XMLNodeList midi_kids;
if (Route::set_state (node)) {
return -1;
@@ -271,36 +210,6 @@ AudioTrack::set_state (const XMLNode& node)
_mode = Normal;
}
- midi_kids = node.children ("MIDI");
-
- for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
-
- XMLNodeList kids;
- XMLNodeConstIterator miter;
- XMLNode* child;
-
- kids = (*iter)->children ();
-
- for (miter = kids.begin(); miter != kids.end(); ++miter) {
-
- child =* miter;
-
- if (child->name() == "rec_enable") {
-
- MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
- MIDI::byte additional = 0; /* ditto */
- MIDI::channel_t chn = 0; /* ditto */
-
- if (get_midi_node_info (child, ev, chn, additional)) {
- _midi_rec_enable_control.set_control_type (chn, ev, additional);
- } else {
- error << string_compose(_("MIDI rec_enable control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
- }
- }
- }
- }
-
-
if ((prop = node.property ("diskstream-id")) == 0) {
/* some old sessions use the diskstream name rather than the ID */
@@ -317,7 +226,7 @@ AudioTrack::set_state (const XMLNode& node)
} else {
- id_t id = strtoull (prop->value().c_str(), 0, 10);
+ PBD::ID id (prop->value());
if (use_diskstream (id)) {
return -1;
@@ -349,24 +258,12 @@ AudioTrack::set_state (const XMLNode& node)
return 0;
}
-XMLNode&
-AudioTrack::get_template ()
-{
- return state (false);
-}
-
-XMLNode&
-AudioTrack::get_state ()
-{
- return state (true);
-}
-
XMLNode&
AudioTrack::state(bool full_state)
{
XMLNode& root (Route::state(full_state));
XMLNode* freeze_node;
- char buf[32];
+ char buf[64];
if (_freeze_record.playlist) {
XMLNode* inode;
@@ -378,7 +275,7 @@ AudioTrack::state(bool full_state)
for (vector<FreezeRecordInsertInfo*>::iterator i = _freeze_record.insert_info.begin(); i != _freeze_record.insert_info.end(); ++i) {
inode = new XMLNode (X_("insert"));
- snprintf (buf, sizeof (buf), "%" PRIu64, (*i)->id);
+ (*i)->id.print (buf);
inode->add_property (X_("id"), buf);
inode->add_child_copy ((*i)->state);
@@ -391,7 +288,7 @@ AudioTrack::state(bool full_state)
/* Alignment: act as a proxy for the diskstream */
XMLNode* align_node = new XMLNode (X_("alignment"));
- switch (diskstream->alignment_style()) {
+ switch (_diskstream->alignment_style()) {
case ExistingMaterial:
snprintf (buf, sizeof (buf), X_("existing"));
break;
@@ -402,29 +299,6 @@ AudioTrack::state(bool full_state)
align_node->add_property (X_("style"), buf);
root.add_child_nocopy (*align_node);
- /* MIDI control */
-
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte additional;
- XMLNode* midi_node = 0;
- XMLNode* child;
- XMLNodeList midikids;
-
- midikids = root.children ("MIDI");
- if (!midikids.empty()) {
- midi_node = midikids.front();
- }
- else {
- midi_node = root.add_child ("MIDI");
- }
-
- if (_midi_rec_enable_control.get_control_info (chn, ev, additional) && midi_node) {
-
- child = midi_node->add_child ("rec_enable");
- set_midi_node_info (child, ev, chn, additional);
- }
-
XMLNode* remote_control_node = new XMLNode (X_("remote_control"));
snprintf (buf, sizeof (buf), "%d", _remote_control_id);
remote_control_node->add_property (X_("id"), buf);
@@ -445,7 +319,7 @@ AudioTrack::state(bool full_state)
diskstream.
*/
- snprintf (buf, sizeof (buf), "%" PRIu64, diskstream->id());
+ _diskstream->id().print (buf);
root.add_property ("diskstream-id", buf);
return root;
@@ -504,9 +378,9 @@ AudioTrack::set_state_part_two ()
continue;
}
- FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()));
- frii->insert = 0;
- sscanf (prop->value().c_str(), "%" PRIu64, &frii->id);
+ FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo (*((*citer)->children().front()),
+ boost::shared_ptr<Insert>());
+ frii->id = prop->value ();
_freeze_record.insert_info.push_back (frii);
}
}
@@ -517,9 +391,9 @@ AudioTrack::set_state_part_two ()
if ((prop = fnode->property (X_("style"))) != 0) {
if (prop->value() == "existing") {
- diskstream->set_persistent_align_style (ExistingMaterial);
+ _diskstream->set_persistent_align_style (ExistingMaterial);
} else if (prop->value() == "capture") {
- diskstream->set_persistent_align_style (CaptureTime);
+ _diskstream->set_persistent_align_style (CaptureTime);
}
}
}
@@ -529,7 +403,7 @@ AudioTrack::set_state_part_two ()
uint32_t
AudioTrack::n_process_buffers ()
{
- return max ((uint32_t) diskstream->n_channels(), redirect_max_outs);
+ return max ((uint32_t) _diskstream->n_channels(), redirect_max_outs);
}
void
@@ -560,7 +434,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
return 0;
}
- diskstream->check_record_status (start_frame, nframes, can_record);
+ audio_diskstream().check_record_status (start_frame, nframes, can_record);
bool send_silence;
@@ -579,7 +453,7 @@ AudioTrack::no_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nf
send_silence = true;
}
} else {
- if (diskstream->record_enabled()) {
+ if (_diskstream->record_enabled()) {
if (Config->get_use_sw_monitoring()) {
send_silence = false;
} else {
@@ -627,7 +501,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
Sample* b;
Sample* tmpb;
jack_nframes_t transport_frame;
-
+ AudioDiskstream& diskstream = audio_diskstream();
+
{
Glib::RWLock::ReaderLock lm (redirect_lock, Glib::TRY_LOCK);
if (lm.locked()) {
@@ -653,13 +528,13 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
playback distance to zero, thus causing diskstream::commit
to do nothing.
*/
- return diskstream->process (transport_frame, 0, 0, can_record, rec_monitors_input);
+ return diskstream.process (transport_frame, 0, 0, can_record, rec_monitors_input);
}
_silent = false;
apply_gain_automation = false;
- if ((dret = diskstream->process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
+ if ((dret = diskstream.process (transport_frame, nframes, offset, can_record, rec_monitors_input)) != 0) {
silence (nframes, offset);
@@ -672,7 +547,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
just_meter_input (start_frame, end_frame, nframes, offset);
}
- if (diskstream->record_enabled() && !can_record && !_session.get_auto_input()) {
+ if (diskstream.record_enabled() && !can_record && !_session.get_auto_input()) {
/* not actually recording, but we want to hear the input material anyway,
at least potentially (depending on monitoring options)
@@ -680,7 +555,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
passthru (start_frame, end_frame, nframes, offset, 0, true);
- } else if ((b = diskstream->playback_buffer(0)) != 0) {
+ } else if ((b = diskstream.playback_buffer(0)) != 0) {
/*
XXX is it true that the earlier test on n_outputs()
@@ -702,8 +577,8 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
for (i = 0, n = 1; i < limit; ++i, ++n) {
memcpy (bufs[i], b, sizeof (Sample) * nframes);
- if (n < diskstream->n_channels()) {
- tmpb = diskstream->playback_buffer(n);
+ if (n < diskstream.n_channels()) {
+ tmpb = diskstream.playback_buffer(n);
if (tmpb!=0) {
b = tmpb;
}
@@ -712,7 +587,7 @@ AudioTrack::roll (jack_nframes_t nframes, jack_nframes_t start_frame, jack_nfram
/* don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
- if (!diskstream->record_enabled() && _session.transport_rolling()) {
+ if (!diskstream.record_enabled() && _session.transport_rolling()) {
Glib::Mutex::Lock am (automation_lock, Glib::TRY_LOCK);
if (am.locked() && gain_automation_playback()) {
@@ -748,37 +623,7 @@ AudioTrack::silent_roll (jack_nframes_t nframes, jack_nframes_t start_frame, jac
silence (nframes, offset);
- return diskstream->process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
-}
-
-void
-AudioTrack::toggle_monitor_input ()
-{
- for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
- (*i)->request_monitor_input(!(*i)->monitoring_input());
- }
-}
-
-int
-AudioTrack::set_name (string str, void *src)
-{
- int ret;
-
- if (record_enabled() && _session.actively_recording()) {
- /* this messes things up if done while recording */
- return -1;
- }
-
- if (diskstream->set_name (str, src)) {
- return -1;
- }
-
- /* save state so that the statefile fully reflects any filename changes */
-
- if ((ret = IO::set_name (str, src)) == 0) {
- _session.save_state ("");
- }
- return ret;
+ return audio_diskstream().process (_session.transport_frame() + offset, nframes, offset, can_record, rec_monitors_input);
}
int
@@ -792,10 +637,15 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
gain_t this_gain = _gain;
vector<Sample*>::iterator bi;
Sample * b;
+ AudioDiskstream& diskstream = audio_diskstream();
Glib::RWLock::ReaderLock rlock (redirect_lock);
-
- if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
+
+ // FIXME
+ AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(diskstream.playlist());
+ assert(apl);
+
+ if (apl->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
return -1;
}
@@ -804,8 +654,8 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
b = buffers[0];
++bi;
for (; bi != buffers.end(); ++bi, ++n) {
- if (n < diskstream->n_channels()) {
- if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
+ if (n < diskstream.n_channels()) {
+ if (apl->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
return -1;
}
b = (*bi);
@@ -822,9 +672,9 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
*/
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
- Insert *insert;
+ boost::shared_ptr<Insert> insert;
- if ((insert = dynamic_cast<Insert*>(*i)) != 0) {
+ if ((insert = boost::dynamic_pointer_cast<Insert>(*i)) != 0) {
switch (insert->placement()) {
case PreFader:
insert->run (buffers, nbufs, nframes, 0);
@@ -860,9 +710,9 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
if (post_fader_work) {
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
- PluginInsert *insert;
+ boost::shared_ptr<PluginInsert> insert;
- if ((insert = dynamic_cast<PluginInsert*>(*i)) != 0) {
+ if ((insert = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
switch ((*i)->placement()) {
case PreFader:
break;
@@ -878,29 +728,6 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbu
}
void
-AudioTrack::set_latency_delay (jack_nframes_t longest_session_latency)
-{
- Route::set_latency_delay (longest_session_latency);
- diskstream->set_roll_delay (_roll_delay);
-}
-
-jack_nframes_t
-AudioTrack::update_total_latency ()
-{
- _own_latency = 0;
-
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- if ((*i)->active ()) {
- _own_latency += (*i)->latency ();
- }
- }
-
- set_port_latency (_own_latency);
-
- return _own_latency;
-}
-
-void
AudioTrack::bounce (InterThreadInfo& itt)
{
vector<AudioSource*> srcs;
@@ -918,15 +745,15 @@ AudioTrack::bounce_range (jack_nframes_t start, jack_nframes_t end, InterThreadI
void
AudioTrack::freeze (InterThreadInfo& itt)
{
- Insert* insert;
vector<AudioSource*> srcs;
string new_playlist_name;
Playlist* new_playlist;
string dir;
AudioRegion* region;
string region_name;
+ AudioDiskstream& diskstream = audio_diskstream();
- if ((_freeze_record.playlist = diskstream->playlist()) == 0) {
+ if ((_freeze_record.playlist = dynamic_cast<AudioPlaylist*>(diskstream.playlist())) == 0) {
return;
}
@@ -948,7 +775,7 @@ AudioTrack::freeze (InterThreadInfo& itt)
}
if (n == (UINT_MAX-1)) {
- error << string_compose (X_("There Are too many frozen versions of playlist \"%1\""
+ error << string_compose (X_("There are too many frozen versions of playlist \"%1\""
" to create another one"), _freeze_record.playlist->name())
<< endmsg;
return;
@@ -966,11 +793,12 @@ AudioTrack::freeze (InterThreadInfo& itt)
for (RedirectList::iterator r = _redirects.begin(); r != _redirects.end(); ++r) {
- if ((insert = dynamic_cast<Insert*>(*r)) != 0) {
+ boost::shared_ptr<Insert> insert;
+
+ if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
- FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state());
+ FreezeRecordInsertInfo* frii = new FreezeRecordInsertInfo ((*r)->get_state(), insert);
- frii->insert = insert;
frii->id = insert->id();
frii->memento = (*r)->get_memento();
@@ -993,13 +821,13 @@ AudioTrack::freeze (InterThreadInfo& itt)
(AudioRegion::Flag) (AudioRegion::WholeFile|AudioRegion::DefaultFlags),
false);
- new_playlist->set_orig_diskstream_id (diskstream->id());
+ new_playlist->set_orig_diskstream_id (diskstream.id());
new_playlist->add_region (*region, 0);
new_playlist->set_frozen (true);
region->set_locked (true);
- diskstream->use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
- diskstream->set_record_enabled (false, this);
+ diskstream.use_playlist (dynamic_cast<AudioPlaylist*>(new_playlist));
+ diskstream.set_record_enabled (false);
_freeze_record.state = Frozen;
FreezeChange(); /* EMIT SIGNAL */
@@ -1009,7 +837,7 @@ void
AudioTrack::unfreeze ()
{
if (_freeze_record.playlist) {
- diskstream->use_playlist (_freeze_record.playlist);
+ audio_diskstream().use_playlist (_freeze_record.playlist);
if (_freeze_record.have_mementos) {
@@ -1037,116 +865,3 @@ AudioTrack::unfreeze ()
FreezeChange (); /* EMIT SIGNAL */
}
-AudioTrack::FreezeRecord::~FreezeRecord ()
-{
- for (vector<FreezeRecordInsertInfo*>::iterator i = insert_info.begin(); i != insert_info.end(); ++i) {
- delete *i;
- }
-}
-
-AudioTrack::FreezeState
-AudioTrack::freeze_state() const
-{
- return _freeze_record.state;
-}
-
-
-void
-AudioTrack::reset_midi_control (MIDI::Port* port, bool on)
-{
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte extra;
-
- Route::reset_midi_control (port, on);
-
- _midi_rec_enable_control.get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
- }
- _midi_rec_enable_control.midi_rebind (port, chn);
-}
-
-void
-AudioTrack::send_all_midi_feedback ()
-{
- if (_session.get_midi_feedback()) {
-
- Route::send_all_midi_feedback();
-
- _midi_rec_enable_control.send_feedback (record_enabled());
- }
-}
-
-
-AudioTrack::MIDIRecEnableControl::MIDIRecEnableControl (AudioTrack& s, MIDI::Port* port)
- : MIDI::Controllable (port, 0), track (s), setting(false)
-{
- last_written = false; /* XXX need a good out of bound value */
-}
-
-void
-AudioTrack::MIDIRecEnableControl::set_value (float val)
-{
- bool bval = ((val >= 0.5f) ? true: false);
-
- setting = true;
- track.set_record_enable (bval, this);
- setting = false;
-}
-
-void
-AudioTrack::MIDIRecEnableControl::send_feedback (bool value)
-{
-
- if (!setting && get_midi_feedback()) {
- MIDI::byte val = (MIDI::byte) (value ? 127: 0);
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::EventTwoBytes data;
-
- if (get_control_info (ch, ev, additional)) {
- data.controller_number = additional;
- data.value = val;
-
- track._session.send_midi_message (get_port(), ev, ch, data);
- }
- }
-
-}
-
-MIDI::byte*
-AudioTrack::MIDIRecEnableControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force)
-{
- if (get_midi_feedback()) {
-
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
-
- if (get_control_info (ch, ev, additional)) {
- if (val != last_written || force) {
- *buf++ = ev & ch;
- *buf++ = additional; /* controller number */
- *buf++ = (MIDI::byte) (val ? 127: 0);
- last_written = val;
- bufsize -= 3;
- }
- }
- }
-
- return buf;
-}
-
-void
-AudioTrack::set_mode (TrackMode m)
-{
- if (diskstream) {
- if (_mode != m) {
- _mode = m;
- diskstream->set_destructive (m == Destructive);
- ModeChanged();
- }
- }
-}
diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc
new file mode 100644
index 0000000000..0756f55a59
--- /dev/null
+++ b/libs/ardour/audio_unit.cc
@@ -0,0 +1,362 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ Written by Taybin Rutkin
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <pbd/transmitter.h>
+#include <pbd/xml++.h>
+
+#include <ardour/audioengine.h>
+#include <ardour/audio_unit.h>
+#include <ardour/session.h>
+#include <ardour/utils.h>
+
+#include <appleutility/CAAudioUnit.h>
+
+#include <CoreServices/CoreServices.h>
+#include <AudioUnit/AudioUnit.h>
+
+#include "i18n.h"
+
+using namespace std;
+using namespace PBD;
+using namespace ARDOUR;
+
+AUPlugin::AUPlugin (AudioEngine& engine, Session& session, CAComponent* _comp)
+ :
+ Plugin (engine, session),
+ comp (_comp),
+ unit (new CAAudioUnit)
+{
+ OSErr err = CAAudioUnit::Open (*comp, *unit);
+ if (err != noErr) {
+ error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg;
+ delete unit;
+ delete comp;
+ throw failed_constructor ();
+ }
+
+ unit->Initialize ();
+}
+
+AUPlugin::~AUPlugin ()
+{
+ if (unit) {
+ unit->Uninitialize ();
+ delete unit;
+ }
+
+ if (comp) {
+ delete comp;
+ }
+}
+
+AUPluginInfo::~AUPluginInfo ()
+{
+ if (desc) {
+ delete desc;
+ }
+}
+
+uint32_t
+AUPlugin::unique_id () const
+{
+ return 0;
+}
+
+const char *
+AUPlugin::label () const
+{
+ return "";
+}
+
+const char *
+AUPlugin::maker () const
+{
+ return "";
+}
+
+uint32_t
+AUPlugin::parameter_count () const
+{
+ return 0;
+}
+
+float
+AUPlugin::default_value (uint32_t port)
+{
+ return 0.0;
+}
+
+jack_nframes_t
+AUPlugin::latency () const
+{
+ return 0;
+}
+
+void
+AUPlugin::set_parameter (uint32_t which, float val)
+{
+
+}
+
+float
+AUPlugin::get_parameter (uint32_t which) const
+{
+ return 0.0;
+}
+
+int
+AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
+{
+ return -1;
+}
+
+uint32_t
+AUPlugin::nth_parameter (uint32_t which, bool& ok) const
+{
+ return 0;
+}
+
+void
+AUPlugin::activate ()
+{
+
+}
+
+void
+AUPlugin::deactivate ()
+{
+
+}
+
+void
+AUPlugin::set_block_size (jack_nframes_t nframes)
+{
+
+}
+
+int
+AUPlugin::connect_and_run (vector<Sample*>& bufs, uint32_t maxbuf, int32_t& in, int32_t& out, jack_nframes_t nframes, jack_nframes_t offset)
+{
+ return -1;
+}
+
+set<uint32_t>
+AUPlugin::automatable() const
+{
+ set<uint32_t> automates;
+
+ return automates;
+}
+
+void
+AUPlugin::store_state (ARDOUR::PluginState&)
+{
+
+}
+
+void
+AUPlugin::restore_state (ARDOUR::PluginState&)
+{
+
+}
+
+string
+AUPlugin::describe_parameter (uint32_t)
+{
+ return "";
+}
+
+void
+AUPlugin::print_parameter (uint32_t, char*, uint32_t len) const
+{
+
+}
+
+bool
+AUPlugin::parameter_is_audio (uint32_t) const
+{
+ return false;
+}
+
+bool
+AUPlugin::parameter_is_control (uint32_t) const
+{
+ return false;
+}
+
+bool
+AUPlugin::parameter_is_input (uint32_t) const
+{
+ return false;
+}
+
+bool
+AUPlugin::parameter_is_output (uint32_t) const
+{
+ return false;
+}
+
+XMLNode&
+AUPlugin::get_state()
+{
+ XMLNode* root = new XMLNode (state_node_name());
+
+ return *root;
+}
+
+int
+AUPlugin::set_state(const XMLNode& node)
+{
+ return -1;
+}
+
+bool
+AUPlugin::save_preset (string name)
+{
+ return false;
+}
+
+bool
+AUPlugin::load_preset (const string preset_label)
+{
+ return false;
+}
+
+vector<string>
+AUPlugin::get_presets ()
+{
+ vector<string> presets;
+
+ return presets;
+}
+
+bool
+AUPlugin::has_editor () const
+{
+ return false;
+}
+
+PluginPtr
+AUPluginInfo::load (Session& session)
+{
+ try {
+ PluginPtr plugin;
+
+ CAComponent* comp = new CAComponent(*desc);
+
+ if (!comp->IsValid()) {
+ error << ("AudioUnit: not a valid Component") << endmsg;
+ } else {
+ plugin.reset (new AUPlugin (session.engine(), session, comp));
+ }
+
+ plugin->set_info(PluginInfoPtr(new AUPluginInfo(*this)));
+ return plugin;
+ }
+
+ catch (failed_constructor &err) {
+ return PluginPtr ((Plugin*) 0);
+ }
+}
+
+PluginInfoList
+AUPluginInfo::discover ()
+{
+ PluginInfoList plugs;
+
+ int numTypes = 2; // this magic number was retrieved from the apple AUHost example.
+
+ CAComponentDescription desc;
+ desc.componentFlags = 0;
+ desc.componentFlagsMask = 0;
+ desc.componentSubType = 0;
+ desc.componentManufacturer = 0;
+
+ for (int i = 0; i < numTypes; ++i) {
+ if (i == 1) {
+ desc.componentType = kAudioUnitType_MusicEffect;
+ } else {
+ desc.componentType = kAudioUnitType_Effect;
+ }
+
+ Component comp = 0;
+
+ comp = FindNextComponent (NULL, &desc);
+ while (comp != NULL) {
+ CAComponentDescription temp;
+ GetComponentInfo (comp, &temp, NULL, NULL, NULL);
+
+ AUPluginInfoPtr plug(new AUPluginInfo);
+ plug->name = AUPluginInfo::get_name (temp);
+ plug->type = PluginInfo::AudioUnit;
+ plug->n_inputs = 0;
+ plug->n_outputs = 0;
+ plug->category = "AudioUnit";
+ plug->desc = new CAComponentDescription(temp);
+
+ plugs.push_back(plug);
+
+ comp = FindNextComponent (comp, &desc);
+ }
+ }
+
+ return plugs;
+}
+
+string
+AUPluginInfo::get_name (CAComponentDescription& comp_desc)
+{
+ CFStringRef itemName = NULL;
+ // Marc Poirier -style item name
+ CAComponent auComponent (comp_desc);
+ if (auComponent.IsValid()) {
+ CAComponentDescription dummydesc;
+ Handle nameHandle = NewHandle(sizeof(void*));
+ if (nameHandle != NULL) {
+ OSErr err = GetComponentInfo(auComponent.Comp(), &dummydesc, nameHandle, NULL, NULL);
+ if (err == noErr) {
+ ConstStr255Param nameString = (ConstStr255Param) (*nameHandle);
+ if (nameString != NULL) {
+ itemName = CFStringCreateWithPascalString(kCFAllocatorDefault, nameString, CFStringGetSystemEncoding());
+ }
+ }
+ DisposeHandle(nameHandle);
+ }
+ }
+
+ // if Marc-style fails, do the original way
+ if (itemName == NULL) {
+ CFStringRef compTypeString = UTCreateStringForOSType(comp_desc.componentType);
+ CFStringRef compSubTypeString = UTCreateStringForOSType(comp_desc.componentSubType);
+ CFStringRef compManufacturerString = UTCreateStringForOSType(comp_desc.componentManufacturer);
+
+ itemName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@ - %@ - %@"),
+ compTypeString, compManufacturerString, compSubTypeString);
+
+ if (compTypeString != NULL)
+ CFRelease(compTypeString);
+ if (compSubTypeString != NULL)
+ CFRelease(compSubTypeString);
+ if (compManufacturerString != NULL)
+ CFRelease(compManufacturerString);
+ }
+
+ return CFStringRefToStdString(itemName);
+}
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 5a5e200531..982a7c5971 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -26,6 +26,7 @@
#include <pbd/pthread_utils.h>
#include <ardour/audioengine.h>
+#include <ardour/buffer.h>
#include <ardour/port.h>
#include <ardour/session.h>
#include <ardour/cycle_timer.h>
@@ -42,8 +43,8 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-jack_nframes_t Port::short_over_length = 2;
-jack_nframes_t Port::long_over_length = 10;
+jack_nframes_t Port::_short_over_length = 2;
+jack_nframes_t Port::_long_over_length = 10;
AudioEngine::AudioEngine (string client_name)
{
@@ -274,8 +275,8 @@ AudioEngine::process_callback (jack_nframes_t nframes)
Port *port = (*i);
bool x;
- if (port->last_monitor != (x = port->monitoring_input ())) {
- port->last_monitor = x;
+ if (port->_last_monitor != (x = port->monitoring_input ())) {
+ port->_last_monitor = x;
/* XXX I think this is dangerous, due to
a likely mutex in the signal handlers ...
*/
@@ -388,18 +389,19 @@ AudioEngine::remove_session ()
}
Port *
-AudioEngine::register_audio_input_port (const string& portname)
+AudioEngine::register_input_port (DataType type, const string& portname)
{
if (!_running) {
if (!_has_run) {
- fatal << _("register audio input port called before engine was started") << endmsg;
+ fatal << _("register input port called before engine was started") << endmsg;
/*NOTREACHED*/
} else {
return 0;
}
}
- jack_port_t *p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
+ jack_port_t *p = jack_port_register (_jack, portname.c_str(),
+ type.to_jack_type(), JackPortIsInput, 0);
if (p) {
@@ -419,11 +421,11 @@ AudioEngine::register_audio_input_port (const string& portname)
}
Port *
-AudioEngine::register_audio_output_port (const string& portname)
+AudioEngine::register_output_port (DataType type, const string& portname)
{
if (!_running) {
if (!_has_run) {
- fatal << _("register audio output port called before engine was started") << endmsg;
+ fatal << _("register output port called before engine was started") << endmsg;
/*NOTREACHED*/
} else {
return 0;
@@ -432,7 +434,8 @@ AudioEngine::register_audio_output_port (const string& portname)
jack_port_t *p;
- if ((p = jack_port_register (_jack, portname.c_str(), JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)) != 0) {
+ if ((p = jack_port_register (_jack, portname.c_str(),
+ type.to_jack_type(), JackPortIsOutput, 0)) != 0) {
Port *newport = new Port (p);
ports.insert (ports.begin(), newport);
return newport;
@@ -446,6 +449,7 @@ AudioEngine::register_audio_output_port (const string& portname)
return 0;
}
+
int
AudioEngine::unregister_port (Port *port)
{
@@ -458,7 +462,7 @@ AudioEngine::unregister_port (Port *port)
if (port) {
- int ret = jack_port_unregister (_jack, port->port);
+ int ret = jack_port_unregister (_jack, port->_port);
if (ret == 0) {
@@ -549,7 +553,7 @@ AudioEngine::disconnect (Port *port)
}
}
- int ret = jack_port_disconnect (_jack, port->port);
+ int ret = jack_port_disconnect (_jack, port->_port);
if (ret == 0) {
remove_connections_for (port);
@@ -699,7 +703,6 @@ AudioEngine::n_physical_inputs () const
}
string
-
AudioEngine::get_nth_physical (uint32_t n, int flag)
{
const char ** ports;
@@ -747,7 +750,7 @@ AudioEngine::get_port_total_latency (const Port& port)
}
}
- return jack_port_get_total_latency (_jack, port.port);
+ return jack_port_get_total_latency (_jack, port._port);
}
void
@@ -825,7 +828,7 @@ AudioEngine::remove_all_ports ()
if (_jack) {
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
- jack_port_unregister (_jack, (*i)->port);
+ jack_port_unregister (_jack, (*i)->_port);
}
}
@@ -948,7 +951,7 @@ AudioEngine::reconnect_to_jack ()
short_name = long_name.substr (long_name.find_last_of (':') + 1);
- if (((*i)->port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
+ if (((*i)->_port = jack_port_register (_jack, short_name.c_str(), (*i)->type(), (*i)->flags(), 0)) == 0) {
error << string_compose (_("could not reregister %1"), (*i)->name()) << endmsg;
break;
} else {
@@ -963,7 +966,7 @@ AudioEngine::reconnect_to_jack ()
if (i != ports.end()) {
for (Ports::iterator i = ports.begin(); i != ports.end(); ++i) {
- jack_port_unregister (_jack, (*i)->port);
+ jack_port_unregister (_jack, (*i)->_port);
}
return -1;
}
diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc
index 0663f5f9b1..ee35f3068a 100644
--- a/libs/ardour/audiofilesource.cc
+++ b/libs/ardour/audiofilesource.cc
@@ -56,8 +56,7 @@ string AudioFileSource::peak_dir = "";
string AudioFileSource::search_path;
sigc::signal<void> AudioFileSource::HeaderPositionOffsetChanged;
-bool AudioFileSource::header_position_negative;
-uint64_t AudioFileSource::header_position_offset;
+uint64_t AudioFileSource::header_position_offset = 0;
char AudioFileSource::bwf_country_code[3] = "US";
char AudioFileSource::bwf_organization_code[4] = "LAS";
@@ -214,6 +213,10 @@ AudioFileSource::create (const string& idstr, Flag flags)
{
AudioFileSource* es = 0;
+ if (flags & Destructive) {
+ return new DestructiveFileSource (idstr, flags);
+ }
+
try {
es = new CoreAudioSource (idstr, flags);
}
@@ -235,25 +238,6 @@ AudioFileSource::create (const string& idstr, Flag flags)
#endif // HAVE_COREAUDIO
-#ifdef HAVE_COREAUDIO
-std::string
-CFStringRefToStdString(CFStringRef stringRef)
-{
- CFIndex size =
- CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) ,
- kCFStringEncodingASCII);
- char *buf = new char[size];
-
- std::string result;
-
- if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingASCII)) {
- result = buf;
- }
- delete [] buf;
- return result;
-}
-#endif // HAVE_COREAUDIO
-
bool
AudioFileSource::get_soundfile_info (string path, SoundFileInfo& _info, string& error_msg)
{
@@ -592,23 +576,13 @@ AudioFileSource::set_search_path (string p)
}
void
-AudioFileSource::set_header_position_offset (jack_nframes_t offset, bool negative)
+AudioFileSource::set_header_position_offset (jack_nframes_t offset)
{
header_position_offset = offset;
- header_position_negative = negative;
-
+ cerr << "hpo set to " << offset << endl;
HeaderPositionOffsetChanged ();
}
-void
-AudioFileSource::handle_header_position_change ()
-{
- if (writable()) {
- set_header_timeline_position ();
- flush_header ();
- }
-}
-
void
AudioFileSource::set_timeline_position (jack_nframes_t pos)
{
@@ -635,6 +609,12 @@ AudioFileSource::set_name (string newname, bool destructive)
return -1;
}
+ // Test whether newpath exists, if yes notify the user but continue.
+ if (access(newpath.c_str(),F_OK) == 0) {
+ error << _("Programming error! Ardour tried to rename a file over another file! It's safe to continue working, but please report this to the developers.") << endmsg;
+ return -1;
+ }
+
if (rename (oldpath.c_str(), newpath.c_str()) != 0) {
error << string_compose (_("cannot rename audio file for %1 to %2"), _name, newpath) << endmsg;
return -1;
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index 6b118faa51..20d1dbfbd6 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -48,13 +48,13 @@ using namespace ARDOUR;
/* a Session will reset these to its chosen defaults by calling AudioRegion::set_default_fade() */
-Change AudioRegion::FadeInChanged = ARDOUR::new_change();
-Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
-Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
-Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
+Change AudioRegion::FadeInChanged = ARDOUR::new_change();
+Change AudioRegion::FadeOutChanged = ARDOUR::new_change();
+Change AudioRegion::FadeInActiveChanged = ARDOUR::new_change();
+Change AudioRegion::FadeOutActiveChanged = ARDOUR::new_change();
Change AudioRegion::EnvelopeActiveChanged = ARDOUR::new_change();
Change AudioRegion::ScaleAmplitudeChanged = ARDOUR::new_change();
-Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
+Change AudioRegion::EnvelopeChanged = ARDOUR::new_change();
AudioRegionState::AudioRegionState (string why)
: RegionState (why),
@@ -267,8 +267,6 @@ AudioRegion::AudioRegion (SourceList& srcs, const XMLNode& node)
_fade_out (0.0, 2.0, 1.0, false),
_envelope (0.0, 2.0, 1.0, false)
{
- /* basic AudioRegion constructor */
-
set<AudioSource*> unique_srcs;
for (SourceList::iterator i=srcs.begin(); i != srcs.end(); ++i) {
@@ -636,12 +634,6 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
}
XMLNode&
-AudioRegion::get_state ()
-{
- return state (true);
-}
-
-XMLNode&
AudioRegion::state (bool full)
{
XMLNode& node (Region::state (full));
@@ -652,12 +644,12 @@ AudioRegion::state (bool full)
snprintf (buf, sizeof (buf), "0x%x", (int) _flags);
node.add_property ("flags", buf);
- snprintf (buf, sizeof(buf), "%f", _scale_amplitude);
+ snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude);
node.add_property ("scale-gain", buf);
for (uint32_t n=0; n < sources.size(); ++n) {
snprintf (buf2, sizeof(buf2), "source-%d", n);
- snprintf (buf, sizeof(buf), "%" PRIu64, sources[n]->id());
+ sources[n]->id().print (buf);
node.add_property (buf2, buf);
}
@@ -1141,24 +1133,22 @@ AudioRegion::master_source_names ()
}
bool
-AudioRegion::region_list_equivalent (const AudioRegion& other) const
+AudioRegion::source_equivalent (const Region& o) const
{
- return size_equivalent (other) && source_equivalent (other) && _name == other._name;
-}
+ const AudioRegion* other = dynamic_cast<const AudioRegion*>(&o);
+ if (!other)
+ return false;
-bool
-AudioRegion::source_equivalent (const AudioRegion& other) const
-{
SourceList::const_iterator i;
SourceList::const_iterator io;
- for (i = sources.begin(), io = other.sources.begin(); i != sources.end() && io != other.sources.end(); ++i, ++io) {
+ for (i = sources.begin(), io = other->sources.begin(); i != sources.end() && io != other->sources.end(); ++i, ++io) {
if ((*i)->id() != (*io)->id()) {
return false;
}
}
- for (i = master_sources.begin(), io = other.master_sources.begin(); i != master_sources.end() && io != other.master_sources.end(); ++i, ++io) {
+ for (i = master_sources.begin(), io = other->master_sources.begin(); i != master_sources.end() && io != other->master_sources.end(); ++i, ++io) {
if ((*i)->id() != (*io)->id()) {
return false;
}
@@ -1167,27 +1157,6 @@ AudioRegion::source_equivalent (const AudioRegion& other) const
return true;
}
-bool
-AudioRegion::overlap_equivalent (const AudioRegion& other) const
-{
- return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
-}
-
-bool
-AudioRegion::equivalent (const AudioRegion& other) const
-{
- return _start == other._start &&
- _position == other._position &&
- _length == other._length;
-}
-
-bool
-AudioRegion::size_equivalent (const AudioRegion& other) const
-{
- return _start == other._start &&
- _length == other._length;
-}
-
int
AudioRegion::apply (AudioFilter& filter)
{
@@ -1289,7 +1258,7 @@ AudioRegion::set_scale_amplitude (gain_t g)
void
AudioRegion::normalize_to (float target_dB)
{
- const jack_nframes_t blocksize = 256 * 1048;
+ const jack_nframes_t blocksize = 64 * 1024;
Sample buf[blocksize];
char workbuf[blocksize * 4];
jack_nframes_t fpos;
@@ -1410,7 +1379,7 @@ AudioRegion::speed_mismatch (float sr) const
float fsr = sources.front()->sample_rate();
- return fsr == sr;
+ return fsr != sr;
}
extern "C" {
diff --git a/libs/ardour/audiosource.cc b/libs/ardour/audiosource.cc
index add9364cad..bf7a32c885 100644
--- a/libs/ardour/audiosource.cc
+++ b/libs/ardour/audiosource.cc
@@ -640,7 +640,7 @@ AudioSource::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t
to_read = min (chunksize, (_length - current_frame));
- if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) {
+ if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) == 0) {
error << string_compose(_("AudioSource[%1]: peak read - cannot read %2 samples at offset %3")
, _name, to_read, current_frame)
<< endmsg;
diff --git a/libs/ardour/auditioner.cc b/libs/ardour/auditioner.cc
index 2f0b943c0e..e48f103b9f 100644
--- a/libs/ardour/auditioner.cc
+++ b/libs/ardour/auditioner.cc
@@ -27,6 +27,7 @@
#include <ardour/auditioner.h>
#include <ardour/audioplaylist.h>
#include <ardour/panner.h>
+#include <ardour/data_type.h>
using namespace std;
using namespace ARDOUR;
@@ -44,12 +45,12 @@ Auditioner::Auditioner (Session& s)
defer_pan_reset ();
if (left.length()) {
- add_output_port (left, this);
+ add_output_port (left, this, DataType::AUDIO);
}
if (right.length()) {
- disk_stream().add_channel();
- add_output_port (right, this);
+ audio_diskstream().add_channel();
+ add_output_port (right, this, DataType::AUDIO);
}
allow_pan_reset ();
@@ -67,8 +68,12 @@ Auditioner::~Auditioner ()
AudioPlaylist&
Auditioner::prepare_playlist ()
{
- diskstream->playlist()->clear (false, false);
- return *diskstream->playlist();
+ // FIXME auditioner is still audio-only
+ AudioPlaylist* const apl = dynamic_cast<AudioPlaylist*>(_diskstream->playlist());
+ assert(apl);
+
+ apl->clear (false, false);
+ return *apl;
}
void
@@ -82,13 +87,13 @@ Auditioner::audition_current_playlist ()
}
Glib::Mutex::Lock lm (lock);
- diskstream->seek (0);
- length = diskstream->playlist()->get_maximum_extent();
+ _diskstream->seek (0);
+ length = _diskstream->playlist()->get_maximum_extent();
current_frame = 0;
/* force a panner reset now that we have all channels */
- _panner->reset (n_outputs(), diskstream->n_channels());
+ _panner->reset (n_outputs(), _diskstream->n_channels());
g_atomic_int_set (&_active, 1);
}
@@ -108,23 +113,23 @@ Auditioner::audition_region (AudioRegion& region)
the_region = new AudioRegion (region);
the_region->set_position (0, this);
- diskstream->playlist()->clear (true, false);
- diskstream->playlist()->add_region (*the_region, 0, 1, false);
+ _diskstream->playlist()->clear (true, false);
+ _diskstream->playlist()->add_region (*the_region, 0, 1, false);
- while (diskstream->n_channels() < the_region->n_channels()) {
- diskstream->add_channel ();
+ while (_diskstream->n_channels() < the_region->n_channels()) {
+ audio_diskstream().add_channel ();
}
- while (diskstream->n_channels() > the_region->n_channels()) {
- diskstream->remove_channel ();
+ while (_diskstream->n_channels() > the_region->n_channels()) {
+ audio_diskstream().remove_channel ();
}
/* force a panner reset now that we have all channels */
- _panner->reset (n_outputs(), diskstream->n_channels());
+ _panner->reset (n_outputs(), _diskstream->n_channels());
length = the_region->length();
- diskstream->seek (0);
+ _diskstream->seek (0);
current_frame = 0;
g_atomic_int_set (&_active, 1);
}
@@ -143,14 +148,14 @@ Auditioner::play_audition (jack_nframes_t nframes)
this_nframes = min (nframes, length - current_frame);
- diskstream->prepare ();
+ _diskstream->prepare ();
if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) {
silence (nframes, 0);
return ret;
}
- need_butler = diskstream->commit (this_nframes);
+ need_butler = _diskstream->commit (this_nframes);
current_frame += this_nframes;
if (current_frame >= length) {
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index a9e76ac55c..dc1767d1e7 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -1211,7 +1211,7 @@ AutomationList::store_state (XMLNode& node) const
snprintf (buf, sizeof (buf), "%" PRIu32, (jack_nframes_t) floor ((*i)->when));
pointnode->add_property ("x", buf);
- snprintf (buf, sizeof (buf), "%f", (*i)->value);
+ snprintf (buf, sizeof (buf), "%.12g", (*i)->value);
pointnode->add_property ("y", buf);
node.add_child_nocopy (*pointnode);
diff --git a/libs/ardour/configuration.cc b/libs/ardour/configuration.cc
index fc708f805d..58da77f933 100644
--- a/libs/ardour/configuration.cc
+++ b/libs/ardour/configuration.cc
@@ -25,6 +25,7 @@
#include <pbd/xml++.h>
#include <ardour/ardour.h>
+#include <ardour/audio_library.h>
#include <ardour/configuration.h>
#include <ardour/audio_diskstream.h>
#include <ardour/destructive_filesource.h>
@@ -178,6 +179,7 @@ Configuration::state (bool user_only)
}
root->add_child_nocopy (ControlProtocolManager::instance().get_state());
+ root->add_child_nocopy (Library->get_state());
return *root;
}
@@ -229,6 +231,8 @@ Configuration::set_state (const XMLNode& root)
} else if (node->name() == ControlProtocolManager::state_node_name) {
_control_protocol_state = new XMLNode (*node);
+ } else if (node->name() == AudioLibrary::state_node_name) {
+ Library->set_state (*node);
}
}
diff --git a/libs/ardour/control_protocol_manager.cc b/libs/ardour/control_protocol_manager.cc
index c2fb188953..0370886a35 100644
--- a/libs/ardour/control_protocol_manager.cc
+++ b/libs/ardour/control_protocol_manager.cc
@@ -49,6 +49,10 @@ ControlProtocolManager::set_session (Session& s)
if ((*i)->requested || (*i)->mandatory) {
instantiate (**i);
(*i)->requested = false;
+
+ if ((*i)->state) {
+ (*i)->protocol->set_state (*(*i)->state);
+ }
}
}
}
@@ -181,6 +185,7 @@ ControlProtocolManager::control_protocol_discover (string path)
cpi->protocol = 0;
cpi->requested = false;
cpi->mandatory = descriptor->mandatory;
+ cpi->state = 0;
control_protocol_info.push_back (cpi);
diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc
index 55409a8524..5e9de225d4 100644
--- a/libs/ardour/coreaudiosource.cc
+++ b/libs/ardour/coreaudiosource.cc
@@ -68,13 +68,13 @@ CoreAudioSource::init (const string& idstr)
FSRef fsr;
err = FSPathMakeRef ((UInt8*)file.c_str(), &fsr, 0);
if (err != noErr) {
- cerr << "FSPathMakeRef " << err << endl;
+ error << string_compose (_("Could not make reference to file: %1"), name()) << endmsg;
throw failed_constructor();
}
err = ExtAudioFileOpen (&fsr, &af);
if (err != noErr) {
- cerr << "ExtAudioFileOpen " << err << endl;
+ error << string_compose (_("Could not open file: %1"), name()) << endmsg;
ExtAudioFileDispose (af);
throw failed_constructor();
}
@@ -85,7 +85,7 @@ CoreAudioSource::init (const string& idstr)
err = ExtAudioFileGetProperty(af,
kExtAudioFileProperty_FileDataFormat, &asbd_size, &file_asbd);
if (err != noErr) {
- cerr << "ExtAudioFileGetProperty1 " << err << endl;
+ error << string_compose (_("Could not get file data format for file: %1"), name()) << endmsg;
ExtAudioFileDispose (af);
throw failed_constructor();
}
@@ -104,7 +104,7 @@ CoreAudioSource::init (const string& idstr)
err = ExtAudioFileGetProperty(af, kExtAudioFileProperty_FileLengthFrames, &prop_size, &ca_frames);
if (err != noErr) {
- cerr << "ExtAudioFileGetProperty2 " << err << endl;
+ error << string_compose (_("Could not get file length for file: %1"), name()) << endmsg;
ExtAudioFileDispose (af);
throw failed_constructor();
}
@@ -125,14 +125,14 @@ CoreAudioSource::init (const string& idstr)
err = ExtAudioFileSetProperty (af, kExtAudioFileProperty_ClientDataFormat, asbd_size, &client_asbd);
if (err != noErr) {
- cerr << "ExtAudioFileSetProperty3 " << err << endl;
+ error << string_compose (_("Could not set client data format for file: %1"), name()) << endmsg;
ExtAudioFileDispose (af);
throw failed_constructor ();
}
if (_build_peakfiles) {
if (initialize_peakfile (false, file)) {
- error << "initialize peakfile failed" << endmsg;
+ error << string_compose(_("initialize peakfile failed for file %1"), name()) << endmsg;
ExtAudioFileDispose (af);
throw failed_constructor ();
}
@@ -212,7 +212,24 @@ CoreAudioSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_
float
CoreAudioSource::sample_rate() const
{
- /* XXX taybin fill me in please */
+ AudioStreamBasicDescription client_asbd;
+ memset(&client_asbd, 0, sizeof(AudioStreamBasicDescription));
- return 44100.0f;
+ OSStatus err = noErr;
+ size_t asbd_size = sizeof(AudioStreamBasicDescription);
+
+ err = ExtAudioFileSetProperty (af, kExtAudioFileProperty_ClientDataFormat, asbd_size, &client_asbd);
+ if (err != noErr) {
+ error << string_compose(_("Could not detect samplerate for: %1"), name()) << endmsg;
+ return 0.0;
+ }
+
+ return client_asbd.mSampleRate;
}
+
+int
+CoreAudioSource::update_header (jack_nframes_t when, struct tm&, time_t)
+{
+ return 0;
+}
+
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 5d36c63f01..dc4c074844 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -112,7 +112,6 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
{
Region* r;
XMLProperty* prop;
- id_t id;
LocaleGuard lg (X_("POSIX"));
/* we have to find the in/out regions before we can do anything else */
@@ -122,7 +121,7 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- sscanf (prop->value().c_str(), "%" PRIu64, &id);
+ PBD::ID id (prop->value());
if ((r = playlist.find_region (id)) == 0) {
error << string_compose (_("Crossfade: no \"in\" region %1 found in playlist %2"), id, playlist.name())
@@ -139,10 +138,10 @@ Crossfade::Crossfade (const Playlist& playlist, XMLNode& node)
throw failed_constructor();
}
- sscanf (prop->value().c_str(), "%" PRIu64, &id);
+ PBD::ID id2 (prop->value());
- if ((r = playlist.find_region (id)) == 0) {
- error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id, playlist.name())
+ if ((r = playlist.find_region (id2)) == 0) {
+ error << string_compose (_("Crossfade: no \"out\" region %1 found in playlist %2"), id2, playlist.name())
<< endmsg;
throw failed_constructor();
}
@@ -680,9 +679,9 @@ Crossfade::get_state ()
char buf[64];
LocaleGuard lg (X_("POSIX"));
- snprintf (buf, sizeof(buf), "%" PRIu64, _out->id());
+ _out->id().print (buf);
node->add_property ("out", buf);
- snprintf (buf, sizeof(buf), "%" PRIu64, _in->id());
+ _in->id().print (buf);
node->add_property ("in", buf);
node->add_property ("active", (_active ? "yes" : "no"));
node->add_property ("follow-overlap", (_follow_overlap ? "yes" : "no"));
@@ -703,7 +702,7 @@ Crossfade::get_state ()
snprintf (buf, sizeof (buf), "%" PRIu32, (jack_nframes_t) floor ((*ii)->when));
pnode->add_property ("x", buf);
- snprintf (buf, sizeof (buf), "%f", (*ii)->value);
+ snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
pnode->add_property ("y", buf);
child->add_child_nocopy (*pnode);
}
@@ -717,7 +716,7 @@ Crossfade::get_state ()
snprintf (buf, sizeof (buf), "%" PRIu32, (jack_nframes_t) floor ((*ii)->when));
pnode->add_property ("x", buf);
- snprintf (buf, sizeof (buf), "%f", (*ii)->value);
+ snprintf (buf, sizeof (buf), "%.12g", (*ii)->value);
pnode->add_property ("y", buf);
child->add_child_nocopy (*pnode);
}
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index cce757509a..43fafff30a 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -70,21 +70,33 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64;
DestructiveFileSource::DestructiveFileSource (string path, SampleFormat samp_format, HeaderFormat hdr_format, jack_nframes_t rate, Flag flags)
: SndFileSource (path, samp_format, hdr_format, rate, flags)
{
- xfade_buf = new Sample[xfade_frames];
+ init ();
+}
- _capture_start = false;
- _capture_end = false;
- file_pos = 0;
+
+DestructiveFileSource::DestructiveFileSource (string path, Flag flags)
+ : SndFileSource (path, flags)
+{
+ init ();
}
DestructiveFileSource::DestructiveFileSource (const XMLNode& node)
: SndFileSource (node)
{
+ init ();
+}
+
+void
+DestructiveFileSource::init ()
+{
xfade_buf = new Sample[xfade_frames];
_capture_start = false;
_capture_end = false;
file_pos = 0;
+
+ timeline_position = header_position_offset;
+ AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &DestructiveFileSource::handle_header_position_change));
}
DestructiveFileSource::~DestructiveFileSource()
@@ -124,8 +136,12 @@ DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate)
void
DestructiveFileSource::mark_capture_start (jack_nframes_t pos)
{
- _capture_start = true;
- capture_start_frame = pos;
+ if (pos < timeline_position) {
+ _capture_start = false;
+ } else {
+ _capture_start = true;
+ capture_start_frame = pos;
+ }
}
void
@@ -265,6 +281,11 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt, char *
}
if (_capture_start && _capture_end) {
+
+ /* start and end of capture both occur within the data we are writing,
+ so do both crossfades.
+ */
+
_capture_start = false;
_capture_end = false;
@@ -290,8 +311,12 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt, char *
}
file_pos = ofilepos; // adjusted below
- }
- else if (_capture_start) {
+
+ } else if (_capture_start) {
+
+ /* start of capture both occur within the data we are writing,
+ so do the fade in
+ */
_capture_start = false;
_capture_end = false;
@@ -305,6 +330,10 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt, char *
} else if (_capture_end) {
+ /* end of capture both occur within the data we are writing,
+ so do the fade out
+ */
+
_capture_start = false;
_capture_end = false;
@@ -314,6 +343,8 @@ DestructiveFileSource::write_unlocked (Sample* data, jack_nframes_t cnt, char *
} else {
+ /* in the middle of recording */
+
if (write_float (data, file_pos, cnt) != cnt) {
return 0;
}
@@ -366,8 +397,19 @@ DestructiveFileSource::get_state ()
}
void
+DestructiveFileSource::handle_header_position_change ()
+{
+ if ( _length != 0 ) {
+ error << string_compose(_("Filesource: start time is already set for existing file (%1): Cannot change start time."), _path ) << endmsg;
+ //in the future, pop up a dialog here that allows user to regenerate file with new start offset
+ } else if (writable()) {
+ timeline_position = header_position_offset;
+ set_header_timeline_position (); //this will get flushed if/when the file is recorded to
+ }
+}
+
+void
DestructiveFileSource::set_timeline_position (jack_nframes_t pos)
{
- /* destructive tracks always start at where our reference frame zero is */
- timeline_position = 0;
+ //destructive track timeline postion does not change except at instantion or when header_position_offset (session start) changes
}
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
new file mode 100644
index 0000000000..9312de5bf1
--- /dev/null
+++ b/libs/ardour/diskstream.cc
@@ -0,0 +1,401 @@
+/*
+ Copyright (C) 2000-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: diskstream.cc 567 2006-06-07 14:54:12Z trutkin $
+*/
+
+#include <fstream>
+#include <cstdio>
+#include <unistd.h>
+#include <cmath>
+#include <cerrno>
+#include <string>
+#include <climits>
+#include <fcntl.h>
+#include <cstdlib>
+#include <ctime>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#include <pbd/error.h>
+#include <pbd/basename.h>
+#include <glibmm/thread.h>
+#include <pbd/xml++.h>
+
+#include <ardour/ardour.h>
+#include <ardour/audioengine.h>
+#include <ardour/diskstream.h>
+#include <ardour/utils.h>
+#include <ardour/configuration.h>
+#include <ardour/audiofilesource.h>
+#include <ardour/destructive_filesource.h>
+#include <ardour/send.h>
+#include <ardour/playlist.h>
+#include <ardour/cycle_timer.h>
+#include <ardour/region.h>
+
+#include "i18n.h"
+#include <locale.h>
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+jack_nframes_t Diskstream::disk_io_chunk_frames = 0;
+
+sigc::signal<void,Diskstream*> Diskstream::DiskstreamCreated;
+sigc::signal<void,list<Source*>*> Diskstream::DeleteSources;
+sigc::signal<void> Diskstream::DiskOverrun;
+sigc::signal<void> Diskstream::DiskUnderrun;
+
+Diskstream::Diskstream (Session &sess, const string &name, Flag flag)
+ : _name (name)
+ , _session (sess)
+ , _playlist(NULL)
+{
+ init (flag);
+}
+
+Diskstream::Diskstream (Session& sess, const XMLNode& node)
+ : _session (sess)
+ , _playlist(NULL)
+{
+ init (Recordable);
+}
+
+void
+Diskstream::init (Flag f)
+{
+ _refcnt = 0;
+ _flags = f;
+ _io = 0;
+ _alignment_style = ExistingMaterial;
+ _persistent_alignment_style = ExistingMaterial;
+ first_input_change = true;
+ i_am_the_modifier = 0;
+ g_atomic_int_set (&_record_enabled, 0);
+ was_recording = false;
+ capture_start_frame = 0;
+ capture_captured = 0;
+ _visible_speed = 1.0f;
+ _actual_speed = 1.0f;
+ _buffer_reallocation_required = false;
+ _seek_required = false;
+ first_recordable_frame = max_frames;
+ last_recordable_frame = max_frames;
+ _roll_delay = 0;
+ _capture_offset = 0;
+ _processed = false;
+ _slaved = false;
+ adjust_capture_position = 0;
+ last_possibly_recording = 0;
+ loop_location = 0;
+ wrap_buffer_size = 0;
+ speed_buffer_size = 0;
+ last_phase = 0;
+ phi = (uint64_t) (0x1000000);
+ file_frame = 0;
+ playback_sample = 0;
+ playback_distance = 0;
+ _read_data_count = 0;
+ _write_data_count = 0;
+
+ pending_overwrite = false;
+ overwrite_frame = 0;
+ overwrite_queued = false;
+ input_change_pending = NoChange;
+
+ _n_channels = 0;
+}
+
+Diskstream::~Diskstream ()
+{
+ // Taken by derived class destrctors.. should assure locked here somehow?
+ //Glib::Mutex::Lock lm (state_lock);
+
+ if (_playlist)
+ _playlist->unref ();
+}
+
+void
+Diskstream::set_io (IO& io)
+{
+ _io = &io;
+ set_align_style_from_io ();
+}
+
+void
+Diskstream::handle_input_change (IOChange change, void *src)
+{
+ Glib::Mutex::Lock lm (state_lock);
+
+ if (!(input_change_pending & change)) {
+ input_change_pending = IOChange (input_change_pending|change);
+ _session.request_input_change_handling ();
+ }
+}
+
+void
+Diskstream::non_realtime_set_speed ()
+{
+ if (_buffer_reallocation_required)
+ {
+ Glib::Mutex::Lock lm (state_lock);
+ allocate_temporary_buffers ();
+
+ _buffer_reallocation_required = false;
+ }
+
+ if (_seek_required) {
+ if (speed() != 1.0f || speed() != -1.0f) {
+ seek ((jack_nframes_t) (_session.transport_frame() * (double) speed()), true);
+ }
+ else {
+ seek (_session.transport_frame(), true);
+ }
+
+ _seek_required = false;
+ }
+}
+
+bool
+Diskstream::realtime_set_speed (double sp, bool global)
+{
+ bool changed = false;
+ double new_speed = sp * _session.transport_speed();
+
+ if (_visible_speed != sp) {
+ _visible_speed = sp;
+ changed = true;
+ }
+
+ if (new_speed != _actual_speed) {
+
+ jack_nframes_t required_wrap_size = (jack_nframes_t) floor (_session.get_block_size() *
+ fabs (new_speed)) + 1;
+
+ if (required_wrap_size > wrap_buffer_size) {
+ _buffer_reallocation_required = true;
+ }
+
+ _actual_speed = new_speed;
+ phi = (uint64_t) (0x1000000 * fabs(_actual_speed));
+ }
+
+ if (changed) {
+ if (!global) {
+ _seek_required = true;
+ }
+ SpeedChanged (); /* EMIT SIGNAL */
+ }
+
+ return _buffer_reallocation_required || _seek_required;
+}
+
+void
+Diskstream::prepare ()
+{
+ _processed = false;
+ playback_distance = 0;
+}
+
+void
+Diskstream::recover ()
+{
+ state_lock.unlock();
+ _processed = false;
+}
+
+void
+Diskstream::set_capture_offset ()
+{
+ if (_io == 0) {
+ /* can't capture, so forget it */
+ return;
+ }
+
+ _capture_offset = _io->input_latency();
+}
+
+void
+Diskstream::set_align_style (AlignStyle a)
+{
+ if (record_enabled() && _session.actively_recording()) {
+ return;
+ }
+
+ if (a != _alignment_style) {
+ _alignment_style = a;
+ AlignmentStyleChanged ();
+ }
+}
+
+int
+Diskstream::set_loop (Location *location)
+{
+ if (location) {
+ if (location->start() >= location->end()) {
+ error << string_compose(_("Location \"%1\" not valid for track loop (start >= end)"), location->name()) << endl;
+ return -1;
+ }
+ }
+
+ loop_location = location;
+
+ LoopSet (location); /* EMIT SIGNAL */
+ return 0;
+}
+
+jack_nframes_t
+Diskstream::get_capture_start_frame (uint32_t n)
+{
+ Glib::Mutex::Lock lm (capture_info_lock);
+
+ if (capture_info.size() > n) {
+ return capture_info[n]->start;
+ }
+ else {
+ return capture_start_frame;
+ }
+}
+
+jack_nframes_t
+Diskstream::get_captured_frames (uint32_t n)
+{
+ Glib::Mutex::Lock lm (capture_info_lock);
+
+ if (capture_info.size() > n) {
+ return capture_info[n]->frames;
+ }
+ else {
+ return capture_captured;
+ }
+}
+
+void
+Diskstream::set_roll_delay (jack_nframes_t nframes)
+{
+ _roll_delay = nframes;
+}
+
+void
+Diskstream::set_speed (double sp)
+{
+ _session.request_diskstream_speed (*this, sp);
+
+ /* to force a rebuffering at the right place */
+ playlist_modified();
+}
+
+int
+Diskstream::use_playlist (Playlist* playlist)
+{
+ {
+ Glib::Mutex::Lock lm (state_lock);
+
+ if (playlist == _playlist) {
+ return 0;
+ }
+
+ plstate_connection.disconnect();
+ plmod_connection.disconnect ();
+ plgone_connection.disconnect ();
+
+ if (_playlist) {
+ _playlist->unref();
+ }
+
+ _playlist = playlist;
+ _playlist->ref();
+
+ if (!in_set_state && recordable()) {
+ reset_write_sources (false);
+ }
+
+ plstate_connection = _playlist->StateChanged.connect (mem_fun (*this, &Diskstream::playlist_changed));
+ plmod_connection = _playlist->Modified.connect (mem_fun (*this, &Diskstream::playlist_modified));
+ plgone_connection = _playlist->GoingAway.connect (mem_fun (*this, &Diskstream::playlist_deleted));
+ }
+
+ if (!overwrite_queued) {
+ _session.request_overwrite_buffer (this);
+ overwrite_queued = true;
+ }
+
+ PlaylistChanged (); /* EMIT SIGNAL */
+ _session.set_dirty ();
+
+ return 0;
+}
+
+void
+Diskstream::playlist_changed (Change ignored)
+{
+ playlist_modified ();
+}
+
+void
+Diskstream::playlist_modified ()
+{
+ if (!i_am_the_modifier && !overwrite_queued) {
+ _session.request_overwrite_buffer (this);
+ overwrite_queued = true;
+ }
+}
+
+void
+Diskstream::playlist_deleted (Playlist* pl)
+{
+ /* this catches an ordering issue with session destruction. playlists
+ are destroyed before diskstreams. we have to invalidate any handles
+ we have to the playlist.
+ */
+
+ _playlist = 0;
+}
+
+int
+Diskstream::set_name (string str)
+{
+ if (str != _name) {
+ assert(playlist());
+ playlist()->set_name (str);
+ _name = str;
+
+ if (!in_set_state && recordable()) {
+ /* rename existing capture files so that they have the correct name */
+ return rename_write_sources ();
+ } else {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void
+Diskstream::set_destructive (bool yn)
+{
+ if (yn != destructive()) {
+ reset_write_sources (true, true);
+ if (yn) {
+ _flags |= Destructive;
+ } else {
+ _flags &= ~Destructive;
+ }
+ }
+}
diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc
index f80c9dc287..1342c0147b 100644
--- a/libs/ardour/globals.cc
+++ b/libs/ardour/globals.cc
@@ -32,6 +32,7 @@
#include <lrdf.h>
#include <pbd/error.h>
+#include <pbd/id.h>
#include <pbd/strsplit.h>
#include <midi++/port.h>
@@ -189,12 +190,17 @@ setup_midi ()
}
int
-ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization)
+ARDOUR::init (bool use_vst, bool try_optimization)
{
bool generic_mix_functions = true;
(void) bindtextdomain(PACKAGE, LOCALEDIR);
+ PBD::ID::init ();
+
+ lrdf_init();
+ Library = new AudioLibrary;
+
Config = new Configuration;
if (Config->load_state ()) {
@@ -292,12 +298,9 @@ ARDOUR::init (AudioEngine& engine, bool use_vst, bool try_optimization)
info << "No H/W specific optimizations in use" << endmsg;
}
-
- lrdf_init();
- Library = new AudioLibrary;
/* singleton - first object is "it" */
- new PluginManager (engine);
+ new PluginManager ();
/* singleton - first object is "it" */
new ControlProtocolManager ();
@@ -322,10 +325,15 @@ ARDOUR::cleanup ()
return 0;
}
-ARDOUR::id_t
-ARDOUR::new_id ()
+
+microseconds_t
+ARDOUR::get_microseconds ()
{
- return get_uid();
+ /* XXX need JACK to export its functionality */
+
+ struct timeval now;
+ gettimeofday (&now, 0);
+ return now.tv_sec * 1000000ULL + now.tv_usec;
}
ARDOUR::Change
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index fc05355d4a..a057fef931 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -62,12 +62,12 @@ Insert::Insert(Session& s, string name, Placement p)
const string PluginInsert::port_automation_node_name = "PortAutomation";
-PluginInsert::PluginInsert (Session& s, Plugin& plug, Placement placement)
- : Insert (s, plug.name(), placement)
+PluginInsert::PluginInsert (Session& s, boost::shared_ptr<Plugin> plug, Placement placement)
+ : Insert (s, plug->name(), placement)
{
/* the first is the master */
- _plugins.push_back(&plug);
+ _plugins.push_back (plug);
_plugins[0]->ParameterChanged.connect (mem_fun (*this, &PluginInsert::parameter_changed));
@@ -103,13 +103,13 @@ PluginInsert::PluginInsert (Session& s, const XMLNode& node)
}
PluginInsert::PluginInsert (const PluginInsert& other)
- : Insert (other._session, other.plugin().name(), other.placement())
+ : Insert (other._session, other.plugin()->name(), other.placement())
{
uint32_t count = other._plugins.size();
/* make as many copies as requested */
for (uint32_t n = 0; n < count; ++n) {
- _plugins.push_back (plugin_factory (other.plugin()));
+ _plugins.push_back (plugin_factory (other.plugin (n)));
}
@@ -137,7 +137,7 @@ PluginInsert::set_count (uint32_t num)
uint32_t diff = num - _plugins.size();
for (uint32_t n = 0; n < diff; ++n) {
- _plugins.push_back (plugin_factory (*_plugins[0]));
+ _plugins.push_back (plugin_factory (_plugins[0]));
if (require_state) {
/* XXX do something */
@@ -147,9 +147,7 @@ PluginInsert::set_count (uint32_t num)
} else if (num < _plugins.size()) {
uint32_t diff = _plugins.size() - num;
for (uint32_t n= 0; n < diff; ++n) {
- Plugin * plug = _plugins.back();
_plugins.pop_back();
- delete plug;
}
}
@@ -167,12 +165,6 @@ PluginInsert::init ()
PluginInsert::~PluginInsert ()
{
GoingAway (this); /* EMIT SIGNAL */
-
- while (!_plugins.empty()) {
- Plugin* p = _plugins.back();
- _plugins.pop_back();
- delete p;
- }
}
void
@@ -194,25 +186,25 @@ PluginInsert::auto_state_changed (uint32_t which)
uint32_t
PluginInsert::output_streams() const
{
- return _plugins[0]->get_info().n_outputs * _plugins.size();
+ return _plugins[0]->get_info()->n_outputs * _plugins.size();
}
uint32_t
PluginInsert::input_streams() const
{
- return _plugins[0]->get_info().n_inputs * _plugins.size();
+ return _plugins[0]->get_info()->n_inputs * _plugins.size();
}
uint32_t
PluginInsert::natural_output_streams() const
{
- return _plugins[0]->get_info().n_outputs;
+ return _plugins[0]->get_info()->n_outputs;
}
uint32_t
PluginInsert::natural_input_streams() const
{
- return _plugins[0]->get_info().n_inputs;
+ return _plugins[0]->get_info()->n_inputs;
}
bool
@@ -222,7 +214,7 @@ PluginInsert::is_generator() const
a specific "instrument" flag, for example.
*/
- return _plugins[0]->get_info().n_inputs == 0;
+ return _plugins[0]->get_info()->n_inputs == 0;
}
void
@@ -240,7 +232,7 @@ PluginInsert::set_automatable ()
void
PluginInsert::parameter_changed (uint32_t which, float val)
{
- vector<Plugin*>::iterator i = _plugins.begin();
+ vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin();
/* don't set the first plugin, just all the slaves */
@@ -255,7 +247,7 @@ PluginInsert::parameter_changed (uint32_t which, float val)
void
PluginInsert::set_block_size (jack_nframes_t nframes)
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->set_block_size (nframes);
}
}
@@ -263,7 +255,7 @@ PluginInsert::set_block_size (jack_nframes_t nframes)
void
PluginInsert::activate ()
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->activate ();
}
}
@@ -271,7 +263,7 @@ PluginInsert::activate ()
void
PluginInsert::deactivate ()
{
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->deactivate ();
}
}
@@ -309,7 +301,7 @@ PluginInsert::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, jack_nfram
}
}
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->connect_and_run (bufs, nbufs, in_index, out_index, nframes, offset);
}
@@ -357,8 +349,8 @@ PluginInsert::silence (jack_nframes_t nframes, jack_nframes_t offset)
uint32_t n;
if (active()) {
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
- n = (*i) -> get_info().n_inputs;
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ n = (*i) -> get_info()->n_inputs;
(*i)->connect_and_run (_session.get_silent_buffers (n), n, in_index, out_index, nframes, offset);
}
}
@@ -375,8 +367,8 @@ PluginInsert::run (vector<Sample *>& bufs, uint32_t nbufs, jack_nframes_t nframe
connect_and_run (bufs, nbufs, nframes, offset, false);
}
} else {
- uint32_t in = _plugins[0]->get_info().n_inputs;
- uint32_t out = _plugins[0]->get_info().n_outputs;
+ uint32_t in = _plugins[0]->get_info()->n_inputs;
+ uint32_t out = _plugins[0]->get_info()->n_outputs;
if (out > in) {
@@ -506,19 +498,19 @@ PluginInsert::protect_automation ()
}
}
-Plugin*
-PluginInsert::plugin_factory (Plugin& other)
+boost::shared_ptr<Plugin>
+PluginInsert::plugin_factory (boost::shared_ptr<Plugin> other)
{
- LadspaPlugin* lp;
+ boost::shared_ptr<LadspaPlugin> lp;
#ifdef VST_SUPPORT
- VSTPlugin* vp;
+ boost::shared_ptr<VSTPlugin> vp;
#endif
- if ((lp = dynamic_cast<LadspaPlugin*> (&other)) != 0) {
- return new LadspaPlugin (*lp);
+ if ((lp = boost::dynamic_pointer_cast<LadspaPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new LadspaPlugin (*lp));
#ifdef VST_SUPPORT
- } else if ((vp = dynamic_cast<VSTPlugin*> (&other)) != 0) {
- return new VSTPlugin (*vp);
+ } else if ((vp = boost::dynamic_pointer_cast<VSTPlugin> (other)) != 0) {
+ return boost::shared_ptr<Plugin> (new VSTPlugin (*vp));
#endif
}
@@ -526,13 +518,13 @@ PluginInsert::plugin_factory (Plugin& other)
X_("unknown plugin type in PluginInsert::plugin_factory"))
<< endmsg;
/*NOTREACHED*/
- return 0;
+ return boost::shared_ptr<Plugin> ((Plugin*) 0);
}
int32_t
PluginInsert::compute_output_streams (int32_t cnt) const
{
- return _plugins[0]->get_info().n_outputs * cnt;
+ return _plugins[0]->get_info()->n_outputs * cnt;
}
int32_t
@@ -544,8 +536,8 @@ PluginInsert::configure_io (int32_t magic, int32_t in, int32_t out)
int32_t
PluginInsert::can_support_input_configuration (int32_t in) const
{
- int32_t outputs = _plugins[0]->get_info().n_outputs;
- int32_t inputs = _plugins[0]->get_info().n_inputs;
+ int32_t outputs = _plugins[0]->get_info()->n_outputs;
+ int32_t inputs = _plugins[0]->get_info()->n_inputs;
if (inputs == 0) {
@@ -599,7 +591,7 @@ PluginInsert::state (bool full)
node->add_property("id", string(buf));
if (_plugins[0]->state_node_name() == "ladspa") {
char buf[32];
- snprintf (buf, 31, "%ld", _plugins[0]->get_info().unique_id);
+ snprintf (buf, sizeof (buf), "%ld", _plugins[0]->get_info()->unique_id);
node->add_property("unique-id", string(buf));
}
node->add_property("count", string_compose("%1", _plugins.size()));
@@ -666,7 +658,7 @@ PluginInsert::set_state(const XMLNode& node)
return -1;
}
- Plugin* plugin;
+ boost::shared_ptr<Plugin> plugin;
if (unique != 0) {
plugin = find_plugin (_session, "", unique, type);
@@ -692,13 +684,13 @@ PluginInsert::set_state(const XMLNode& node)
_plugins.push_back (plugin);
for (uint32_t n=1; n < count; ++n) {
- _plugins.push_back (plugin_factory (*plugin));
+ _plugins.push_back (plugin_factory (plugin));
}
}
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == plugin->state_node_name()) {
- for (vector<Plugin*>::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
+ for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->set_state (**niter);
}
break;
@@ -769,7 +761,7 @@ PluginInsert::set_state(const XMLNode& node)
}
// The name of the PluginInsert comes from the plugin, nothing else
- set_name(plugin->get_info().name,this);
+ set_name(plugin->get_info()->name,this);
return 0;
}
@@ -780,18 +772,6 @@ PluginInsert::describe_parameter (uint32_t what)
return _plugins[0]->describe_parameter (what);
}
-void
-PluginInsert::reset_midi_control (MIDI::Port* port, bool on)
-{
- _plugins[0]->reset_midi_control (port, on);
-}
-
-void
-PluginInsert::send_all_midi_feedback ()
-{
- _plugins[0]->send_all_midi_feedback();
-}
-
jack_nframes_t
PluginInsert::latency()
{
diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc
index 87c03c6b70..2dfd735a6b 100644
--- a/libs/ardour/io.cc
+++ b/libs/ardour/io.cc
@@ -74,17 +74,17 @@ sigc::signal<int> IO::PortsCreated;
Glib::StaticMutex IO::m_meter_signal_lock = GLIBMM_STATIC_MUTEX_INIT;
-/* this is a default mapper of MIDI control values to a gain coefficient.
- others can be imagined. see IO::set_midi_to_gain_function().
+/* this is a default mapper of [0 .. 1.0] control values to a gain coefficient.
+ others can be imagined.
*/
-static gain_t direct_midi_to_gain (double fract) {
+static gain_t direct_control_to_gain (double fract) {
/* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
/* this maxes at +6dB */
return pow (2.0,(sqrt(sqrt(sqrt(fract)))*198.0-192.0)/6.0);
}
-static double direct_gain_to_midi (gain_t gain) {
+static double direct_gain_to_control (gain_t gain) {
/* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
if (gain == 0) return 0.0;
@@ -97,19 +97,22 @@ static bool sort_ports_by_name (Port* a, Port* b)
}
+/** @param default_type The type of port that will be created by ensure_io
+ * and friends if no type is explicitly requested (to avoid breakage).
+ */
IO::IO (Session& s, string name,
-
- int input_min, int input_max, int output_min, int output_max)
+ int input_min, int input_max, int output_min, int output_max,
+ DataType default_type)
: _session (s),
_name (name),
- _midi_gain_control (*this, _session.midi_port()),
+ _default_type(default_type),
+ _gain_control (*this),
_gain_automation_curve (0.0, 2.0, 1.0),
_input_minimum (input_min),
_input_maximum (input_max),
_output_minimum (output_min),
_output_maximum (output_max)
{
- _id = new_id();
_panner = new Panner (name, _session);
_gain = 1.0;
_desired_gain = 1.0;
@@ -121,9 +124,6 @@ IO::IO (Session& s, string name,
no_panner_reset = false;
deferred_state = 0;
- _midi_gain_control.midi_to_gain = direct_midi_to_gain;
- _midi_gain_control.gain_to_midi = direct_gain_to_midi;
-
apply_gain_automation = false;
last_automation_snapshot = 0;
@@ -785,11 +785,20 @@ IO::remove_output_port (Port* port, void* src)
return -1;
}
+/** Add an output port.
+ *
+ * @param destination Name of input port to connect new port to.
+ * @param src Source for emitted ConfigurationChanged signal.
+ * @param type Data type of port. Default value (NIL) will use this IO's default type.
+ */
int
-IO::add_output_port (string destination, void* src)
+IO::add_output_port (string destination, void* src, DataType type)
{
Port* our_port;
- char buf[64];
+ char name[64];
+
+ if (type == DataType::NIL)
+ type = _default_type;
{
Glib::Mutex::Lock em(_session.engine().process_lock());
@@ -803,14 +812,15 @@ IO::add_output_port (string destination, void* src)
/* Create a new output port */
+ // FIXME: naming scheme for differently typed ports?
if (_output_maximum == 1) {
- snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str());
+ snprintf (name, sizeof (name), _("%s/out"), _name.c_str());
} else {
- snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
+ snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole());
}
- if ((our_port = _session.engine().register_audio_output_port (buf)) == 0) {
- error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
+ if ((our_port = _session.engine().register_output_port (type, name)) == 0) {
+ error << string_compose(_("IO: cannot register output port %1"), name) << endmsg;
return -1;
}
@@ -886,11 +896,21 @@ IO::remove_input_port (Port* port, void* src)
return -1;
}
+
+/** Add an input port.
+ *
+ * @param type Data type of port. The appropriate Jack port type, and @ref Port will be created.
+ * @param destination Name of input port to connect new port to.
+ * @param src Source for emitted ConfigurationChanged signal.
+ */
int
-IO::add_input_port (string source, void* src)
+IO::add_input_port (string source, void* src, DataType type)
{
Port* our_port;
- char buf[64];
+ char name[64];
+
+ if (type == DataType::NIL)
+ type = _default_type;
{
Glib::Mutex::Lock em (_session.engine().process_lock());
@@ -904,14 +924,15 @@ IO::add_input_port (string source, void* src)
/* Create a new input port */
+ // FIXME: naming scheme for differently typed ports?
if (_input_maximum == 1) {
- snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
+ snprintf (name, sizeof (name), _("%s/in"), _name.c_str());
} else {
- snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole());
+ snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole());
}
- if ((our_port = _session.engine().register_audio_input_port (buf)) == 0) {
- error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
+ if ((our_port = _session.engine().register_input_port (type, name)) == 0) {
+ error << string_compose(_("IO: cannot register input port %1"), name) << endmsg;
return -1;
}
@@ -1005,7 +1026,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
char buf[64];
- /* Create a new input port */
+ /* Create a new input port (of the default type) */
if (_input_maximum == 1) {
snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str());
@@ -1016,7 +1037,7 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src)
try {
- if ((input_port = _session.engine().register_audio_input_port (buf)) == 0) {
+ if ((input_port = _session.engine().register_input_port (_default_type, buf)) == 0) {
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
return -1;
}
@@ -1105,7 +1126,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
out_changed = true;
}
- /* create any necessary new ports */
+ /* create any necessary new ports (of the default type) */
while (_ninputs < nin) {
@@ -1121,7 +1142,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
}
try {
- if ((port = _session.engine().register_audio_input_port (buf)) == 0) {
+ if ((port = _session.engine().register_input_port (_default_type, buf)) == 0) {
error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg;
return -1;
}
@@ -1154,7 +1175,7 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src)
}
try {
- if ((port = _session.engine().register_audio_output_port (buf)) == 0) {
+ if ((port = _session.engine().register_output_port (_default_type, buf)) == 0) {
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
return -1;
}
@@ -1279,7 +1300,7 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src)
snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole());
}
- if ((output_port = _session.engine().register_audio_output_port (buf)) == 0) {
+ if ((output_port = _session.engine().register_output_port (_default_type, buf)) == 0) {
error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg;
return -1;
}
@@ -1397,7 +1418,7 @@ XMLNode&
IO::state (bool full_state)
{
XMLNode* node = new XMLNode (state_node_name);
- char buf[32];
+ char buf[64];
string str;
bool need_ins = true;
bool need_outs = true;
@@ -1405,7 +1426,7 @@ IO::state (bool full_state)
Glib::Mutex::Lock lm (io_lock);
node->add_property("name", _name);
- snprintf (buf, sizeof(buf), "%" PRIu64, id());
+ id().print (buf);
node->add_property("id", buf);
str = "";
@@ -1499,22 +1520,6 @@ IO::state (bool full_state)
node->add_property ("iolimits", buf);
- /* MIDI control */
-
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte additional;
- XMLNode* midi_node = 0;
- XMLNode* child;
-
- if (_midi_gain_control.get_control_info (chn, ev, additional)) {
-
- midi_node = node->add_child ("MIDI");
-
- child = midi_node->add_child ("gain");
- set_midi_node_info (child, ev, chn, additional);
- }
-
/* automation */
if (full_state) {
@@ -1583,7 +1588,6 @@ IO::set_state (const XMLNode& node)
{
const XMLProperty* prop;
XMLNodeConstIterator iter;
- XMLNodeList midi_kids;
LocaleGuard lg (X_("POSIX"));
/* force use of non-localized representation of decimal point,
@@ -1601,7 +1605,7 @@ IO::set_state (const XMLNode& node)
}
if ((prop = node.property ("id")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+ _id = prop->value ();
}
if ((prop = node.property ("iolimits")) != 0) {
@@ -1623,35 +1627,6 @@ IO::set_state (const XMLNode& node)
}
}
- midi_kids = node.children ("MIDI");
-
- for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
-
- XMLNodeList kids;
- XMLNodeConstIterator miter;
- XMLNode* child;
-
- kids = (*iter)->children ();
-
- for (miter = kids.begin(); miter != kids.end(); ++miter) {
-
- child =* miter;
-
- if (child->name() == "gain") {
-
- MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
- MIDI::byte additional = 0; /* ditto */
- MIDI::channel_t chn = 0; /* ditto */
-
- if (get_midi_node_info (child, ev, chn, additional)) {
- _midi_gain_control.set_control_type (chn, ev, additional);
- } else {
- error << string_compose(_("MIDI gain control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
- }
- }
- }
- }
-
if ((prop = node.property ("automation-state")) != 0) {
long int x;
@@ -1769,50 +1744,6 @@ IO::create_ports (const XMLNode& node)
return 0;
}
-bool
-IO::get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional)
-{
- bool ok = true;
- const XMLProperty* prop;
- int xx;
-
- if ((prop = node->property ("event")) != 0) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- ev = (MIDI::eventType) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = node->property ("channel")) != 0)) {
- sscanf (prop->value().c_str(), "%d", &xx);
- chan = (MIDI::channel_t) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = node->property ("additional")) != 0)) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- additional = (MIDI::byte) xx;
- }
-
- return ok;
-}
-
-bool
-IO::set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional)
-{
- char buf[32];
-
- snprintf (buf, sizeof(buf), "0x%x", ev);
- node->add_property ("event", buf);
- snprintf (buf, sizeof(buf), "%d", chan);
- node->add_property ("channel", buf);
- snprintf (buf, sizeof(buf), "0x%x", additional);
- node->add_property ("additional", buf);
-
- return true;
-}
-
int
IO::make_connections (const XMLNode& node)
@@ -2339,69 +2270,16 @@ IO::output_connection_configuration_changed ()
use_output_connection (*_output_connection, this);
}
-IO::MIDIGainControl::MIDIGainControl (IO& i, MIDI::Port* port)
- : MIDI::Controllable (port, 0), io (i), setting(false)
-{
- midi_to_gain = 0;
- gain_to_midi = 0;
- setting = false;
- last_written = 0; /* XXX need a good out-of-bound-value */
-}
-
void
-IO::MIDIGainControl::set_value (float val)
+IO::GainControllable::set_value (float val)
{
- if (midi_to_gain == 0) return;
-
- setting = true;
- io.set_gain (midi_to_gain (val), this);
- setting = false;
+ io.set_gain (direct_control_to_gain (val), this);
}
-void
-IO::MIDIGainControl::send_feedback (gain_t gain)
-{
- if (!setting && get_midi_feedback() && gain_to_midi) {
- MIDI::byte val = (MIDI::byte) (gain_to_midi (gain) * 127.0);
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::EventTwoBytes data;
-
- if (get_control_info (ch, ev, additional)) {
- data.controller_number = additional;
- data.value = val;
- last_written = val;
-
- io._session.send_midi_message (get_port(), ev, ch, data);
- }
- //send_midi_feedback (gain_to_midi (gain));
- }
-}
-
-MIDI::byte*
-IO::MIDIGainControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, gain_t val, bool force)
+float
+IO::GainControllable::get_value (void) const
{
- if (get_midi_feedback() && gain_to_midi && bufsize > 2) {
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::byte gm;
-
- if (get_control_info (ch, ev, additional)) {
- gm = (MIDI::byte) (gain_to_midi (val) * 127.0);
-
- if (gm != last_written) {
- *buf++ = (0xF0 & ev) | (0xF & ch);
- *buf++ = additional; /* controller number */
- *buf++ = gm;
- last_written = gm;
- bufsize -= 3;
- }
- }
- }
-
- return buf;
+ return direct_gain_to_control (io.effective_gain());
}
void
@@ -2493,23 +2371,6 @@ IO::meter ()
}
}
-void
-IO::reset_midi_control (MIDI::Port* port, bool on)
-{
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte extra;
-
- _midi_gain_control.get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
- }
- _midi_gain_control.midi_rebind (port, chn);
-
- _panner->reset_midi_control (port, on);
-}
-
-
int
IO::save_automation (const string& path)
{
@@ -2699,10 +2560,7 @@ IO::set_gain (gain_t val, void *src)
}
gain_changed (src);
-
- if (_session.get_midi_feedback()) {
- _midi_gain_control.send_feedback (_desired_gain);
- }
+ _gain_control.Changed (); /* EMIT SIGNAL */
if (_session.transport_stopped() && src != 0 && src != this && gain_automation_recording()) {
_gain_automation_curve.add (_session.transport_frame(), val);
@@ -2713,30 +2571,6 @@ IO::set_gain (gain_t val, void *src)
}
void
-IO::send_all_midi_feedback ()
-{
- if (_session.get_midi_feedback()) {
- _midi_gain_control.send_feedback (_effective_gain);
-
- // panners
- _panner->send_all_midi_feedback();
- }
-}
-
-MIDI::byte*
-IO::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize)
-{
- if (_session.get_midi_feedback()) {
- if (gain_automation_playback ()) {
- buf = _midi_gain_control.write_feedback (buf, bufsize, _effective_gain);
- }
- buf = _panner->write_midi_feedback (buf, bufsize);
- }
-
- return buf;
-}
-
-void
IO::start_gain_touch ()
{
_gain_automation_curve.start_touch ();
diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc
index 11001655d2..6b773b9e0b 100644
--- a/libs/ardour/ladspa_plugin.cc
+++ b/libs/ardour/ladspa_plugin.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000-2002 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -133,20 +133,9 @@ LadspaPlugin::init (void *mod, uint32_t index, jack_nframes_t rate)
}
}
- Plugin::setup_midi_controls ();
+ Plugin::setup_controls ();
latency_compute_run ();
-
- MIDI::Controllable *mcontrol;
-
- for (uint32_t i = 0; i < parameter_count(); ++i) {
- if (LADSPA_IS_PORT_INPUT(port_descriptor (i)) &&
- LADSPA_IS_PORT_CONTROL(port_descriptor (i))) {
- if ((mcontrol = get_nth_midi_control (i)) != 0) {
- mcontrol->midi_rebind (_session.midi_port(), 0);
- }
- }
- }
}
LadspaPlugin::~LadspaPlugin ()
@@ -318,17 +307,14 @@ LadspaPlugin::set_parameter (uint32_t which, float val)
shadow_data[which] = (LADSPA_Data) val;
ParameterChanged (which, val); /* EMIT SIGNAL */
- if (session().get_midi_feedback()) {
-
- if (which < parameter_count() && midi_controls[which]) {
- midi_controls[which]->send_feedback (val);
- }
+ if (which < parameter_count() && controls[which]) {
+ controls[which]->Changed ();
}
-
+
} else {
warning << string_compose (_("illegal parameter number used with plugin \"%1\". This may"
- "indicate a change in the plugin design, and presets may be"
- "invalid"), name())
+ "indicate a change in the plugin design, and presets may be"
+ "invalid"), name())
<< endmsg;
}
}
@@ -380,28 +366,6 @@ LadspaPlugin::get_state()
snprintf(buf, sizeof(buf), "%+f", shadow_data[i]);
child->add_property("value", string(buf));
root->add_child_nocopy (*child);
-
- MIDI::Controllable *pcontrol = get_nth_midi_control (i);
-
- if (pcontrol) {
-
- MIDI::eventType ev;
- MIDI::byte additional;
- MIDI::channel_t chn;
- XMLNode* midi_node;
-
- if (pcontrol->get_control_info (chn, ev, additional)) {
-
- midi_node = child->add_child ("midi-control");
-
- snprintf (buf, sizeof(buf), "0x%x", ev);
- midi_node->add_property ("event", buf);
- snprintf (buf, sizeof(buf), "%d", chn);
- midi_node->add_property ("channel", buf);
- snprintf (buf, sizeof(buf), "0x%x", additional);
- midi_node->add_property ("additional", buf);
- }
- }
}
}
@@ -452,52 +416,6 @@ LadspaPlugin::set_state(const XMLNode& node)
sscanf (port, "%" PRIu32, &port_id);
set_parameter (port_id, atof(data));
-
- XMLNodeList midi_kids;
- XMLNodeConstIterator iter;
-
- midi_kids = child->children ("midi-control");
-
- for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
-
- child = *iter;
-
- MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
- MIDI::byte additional = 0; /* initialize to keep gcc happy */
- MIDI::channel_t chn = 0; /* initialize to keep gcc happy */
- bool ok = true;
- int xx;
-
- if ((prop = child->property ("event")) != 0) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- ev = (MIDI::eventType) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = child->property ("channel")) != 0)) {
- sscanf (prop->value().c_str(), "%d", &xx);
- chn = (MIDI::channel_t) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = child->property ("additional")) != 0)) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- additional = (MIDI::byte) xx;
- }
-
- if (ok) {
- MIDI::Controllable* pcontrol = get_nth_midi_control (port_id);
-
- if (pcontrol) {
- pcontrol->set_control_type (chn, ev, additional);
- }
-
- } else {
- error << string_compose(_("LADSPA LadspaPlugin MIDI control specification for port %1 is incomplete, so it has been ignored"), port) << endl;
- }
- }
}
latency_compute_run ();
@@ -723,3 +641,26 @@ LadspaPlugin::latency_compute_run ()
run (bufsize);
deactivate ();
}
+
+PluginPtr
+LadspaPluginInfo::load (Session& session)
+{
+ try {
+ PluginPtr plugin;
+ void *module;
+
+ if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
+ error << string_compose(_("LADSPA: cannot load module from \"%1\""), path) << endmsg;
+ error << dlerror() << endmsg;
+ } else {
+ plugin.reset (new LadspaPlugin (module, session.engine(), session, index, session.frame_rate()));
+ }
+
+ plugin->set_info(PluginInfoPtr(new LadspaPluginInfo(*this)));
+ return plugin;
+ }
+
+ catch (failed_constructor &err) {
+ return PluginPtr ((Plugin*) 0);
+ }
+}
diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc
index b2af52284e..5b5f733138 100644
--- a/libs/ardour/location.cc
+++ b/libs/ardour/location.cc
@@ -30,6 +30,7 @@
#include <pbd/xml++.h>
#include <ardour/location.h>
+#include <ardour/audiofilesource.h>
#include "i18n.h"
@@ -44,6 +45,10 @@ Location::Location (const Location& other)
_end (other._end),
_flags (other._flags)
{
+ /* start and end flags can never be copied, because there can only ever be one of each */
+
+ _flags = Flags (_flags & ~IsStart);
+ _flags = Flags (_flags & ~IsEnd);
}
Location*
@@ -71,6 +76,9 @@ Location::set_start (jack_nframes_t s)
_start = s;
_end = s;
start_changed(this); /* EMIT SIGNAL */
+ if ( is_start() ) {
+ AudioFileSource::set_header_position_offset ( s );
+ }
}
return 0;
}
diff --git a/libs/ardour/mix.cc b/libs/ardour/mix.cc
index ab0d1dde59..c6e234d87b 100644
--- a/libs/ardour/mix.cc
+++ b/libs/ardour/mix.cc
@@ -22,6 +22,7 @@
#include <ardour/types.h>
#include <ardour/utils.h>
#include <ardour/mix.h>
+#include <stdint.h>
#if defined (ARCH_X86) && defined (BUILD_SSE_OPTIMIZATIONS)
@@ -119,8 +120,9 @@ mix_buffers_no_gain (ARDOUR::Sample *dst, ARDOUR::Sample *src, jack_nframes_t nf
float
veclib_compute_peak (ARDOUR::Sample *buf, jack_nframes_t nsamples, float current)
{
- vDSP_maxv(buf, 1, &current, nsamples);
- return current;
+ float tmpmax = 0.0f;
+ vDSP_maxmgv(buf, 1, &tmpmax, nsamples);
+ return f_max(current, tmpmax);
}
void
diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc
index 83c9e6eb4d..8336c4697c 100644
--- a/libs/ardour/panner.cc
+++ b/libs/ardour/panner.cc
@@ -53,21 +53,21 @@ float Panner::current_automation_version_number = 1.0;
string EqualPowerStereoPanner::name = "Equal Power Stereo";
string Multi2dPanner::name = "Multiple (2D)";
-/* this is a default mapper of MIDI control values to a pan position
- others can be imagined. see Panner::set_midi_to_pan_function().
+/* this is a default mapper of control values to a pan position
+ others can be imagined.
*/
-static pan_t direct_midi_to_pan (double fract) {
+static pan_t direct_control_to_pan (double fract) {
return fract;
}
-static double direct_pan_to_midi (pan_t val) {
+static double direct_pan_to_control (pan_t val) {
return val;
}
StreamPanner::StreamPanner (Panner& p)
: parent (p),
- _midi_control (*this, (MIDI::Port*) 0)
+ _control (*this)
{
_muted = false;
@@ -80,84 +80,30 @@ StreamPanner::~StreamPanner ()
{
}
-StreamPanner::MIDIControl::MIDIControl (StreamPanner& s, MIDI::Port* port)
- : MIDI::Controllable (port, 0), sp (s), setting(false)
-{
- midi_to_pan = direct_midi_to_pan;
- pan_to_midi = direct_pan_to_midi;
- last_written = 0; /* XXX need a good out-of-bound-value */
-}
-
void
-StreamPanner::MIDIControl::set_value (float val)
+StreamPanner::PanControllable::set_value (float val)
{
- setting = true;
- sp.set_position (midi_to_pan (val));
- setting = false;
-}
-
-void
-StreamPanner::MIDIControl::send_feedback (pan_t value)
-{
-
- if (!setting && get_midi_feedback() && pan_to_midi) {
- MIDI::byte val = (MIDI::byte) (pan_to_midi (value) * 127.0f);
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::EventTwoBytes data;
-
- if (get_control_info (ch, ev, additional)) {
- data.controller_number = additional;
- data.value = val;
- last_written = val;
-
- sp.get_parent().session().send_midi_message (get_port(), ev, ch, data);
- }
-
- // send_midi_feedback (pan_to_midi (val));
- }
-
+ panner.set_position (direct_control_to_pan (val));
}
-MIDI::byte*
-StreamPanner::MIDIControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, pan_t val, bool force)
+float
+StreamPanner::PanControllable::get_value (void) const
{
- if (get_midi_feedback() && pan_to_midi && bufsize > 2) {
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::byte pm;
- if (get_control_info (ch, ev, additional)) {
-
- pm = (MIDI::byte) (pan_to_midi (val) * 127.0);
-
- if (pm != last_written || force) {
- *buf++ = (0xF0 & ev) | (0xF & ch);
- *buf++ = additional; /* controller number */
- *buf++ = pm;
- last_written = pm;
- bufsize -= 3;
- }
- }
- }
-
- return buf;
+ float xpos;
+ panner.get_effective_position (xpos);
+ return direct_pan_to_control (xpos);
}
-
-void
-StreamPanner::reset_midi_control (MIDI::Port* port, bool on)
+bool
+StreamPanner::PanControllable::can_send_feedback () const
{
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte extra;
+ AutoState astate = panner.get_parent().automation_state ();
- _midi_control.get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
+ if ((astate == Play) || (astate == Touch && !panner.get_parent().touching())) {
+ return true;
}
- _midi_control.midi_rebind (port, chn);
+
+ return false;
}
void
@@ -180,10 +126,7 @@ StreamPanner::set_position (float xpos, bool link_call)
x = xpos;
update ();
Changed ();
-
- if (parent.session().get_midi_feedback()) {
- _midi_control.send_feedback (x);
- }
+ _control.Changed ();
}
}
@@ -224,42 +167,11 @@ StreamPanner::set_state (const XMLNode& node)
{
const XMLProperty* prop;
XMLNodeConstIterator iter;
- XMLNodeList midi_kids;
if ((prop = node.property (X_("muted")))) {
set_muted (prop->value() == "yes");
}
- midi_kids = node.children ("MIDI");
-
- for (iter = midi_kids.begin(); iter != midi_kids.end(); ++iter) {
-
- XMLNodeList kids;
- XMLNodeConstIterator miter;
- XMLNode* child;
-
- kids = (*iter)->children ();
-
- for (miter = kids.begin(); miter != kids.end(); ++miter) {
-
- child =* miter;
-
- if (child->name() == "pan") {
-
- MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
- MIDI::byte additional = 0; /* ditto */
- MIDI::channel_t chn = 0; /* ditto */
-
- if (get_midi_node_info (child, ev, chn, additional)) {
- _midi_control.set_control_type (chn, ev, additional);
- } else {
- error << _("MIDI pan control specification is incomplete, so it has been ignored") << endmsg;
- }
- }
- }
- }
-
-
return 0;
}
@@ -267,68 +179,6 @@ void
StreamPanner::add_state (XMLNode& node)
{
node.add_property (X_("muted"), (muted() ? "yes" : "no"));
-
- /* MIDI control */
-
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte additional;
- XMLNode* midi_node = 0;
- XMLNode* child;
-
- if (_midi_control.get_control_info (chn, ev, additional)) {
-
- midi_node = node.add_child ("MIDI");
-
- child = midi_node->add_child ("pan");
- set_midi_node_info (child, ev, chn, additional);
- }
-
-}
-
-
-bool
-StreamPanner::get_midi_node_info (XMLNode * node, MIDI::eventType & ev, MIDI::channel_t & chan, MIDI::byte & additional)
-{
- bool ok = true;
- const XMLProperty* prop;
- int xx;
-
- if ((prop = node->property ("event")) != 0) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- ev = (MIDI::eventType) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = node->property ("channel")) != 0)) {
- sscanf (prop->value().c_str(), "%d", &xx);
- chan = (MIDI::channel_t) xx;
- } else {
- ok = false;
- }
-
- if (ok && ((prop = node->property ("additional")) != 0)) {
- sscanf (prop->value().c_str(), "0x%x", &xx);
- additional = (MIDI::byte) xx;
- }
-
- return ok;
-}
-
-bool
-StreamPanner::set_midi_node_info (XMLNode * node, MIDI::eventType ev, MIDI::channel_t chan, MIDI::byte additional)
-{
- char buf[32];
-
- snprintf (buf, sizeof(buf), "0x%x", ev);
- node->add_property ("event", buf);
- snprintf (buf, sizeof(buf), "%d", chan);
- node->add_property ("channel", buf);
- snprintf (buf, sizeof(buf), "0x%x", additional);
- node->add_property ("additional", buf);
-
- return true;
}
/*---------------------------------------------------------------------- */
@@ -679,7 +529,7 @@ EqualPowerStereoPanner::state (bool full_state)
char buf[64];
LocaleGuard lg (X_("POSIX"));
- snprintf (buf, sizeof (buf), "%f", x);
+ snprintf (buf, sizeof (buf), "%.12g", x);
root->add_property (X_("x"), buf);
root->add_property (X_("type"), EqualPowerStereoPanner::name);
if (full_state) {
@@ -913,9 +763,9 @@ Multi2dPanner::state (bool full_state)
char buf[64];
LocaleGuard lg (X_("POSIX"));
- snprintf (buf, sizeof (buf), "%f", x);
+ snprintf (buf, sizeof (buf), "%.12g", x);
root->add_property (X_("x"), buf);
- snprintf (buf, sizeof (buf), "%f", y);
+ snprintf (buf, sizeof (buf), "%.12g", y);
root->add_property (X_("y"), buf);
root->add_property (X_("type"), Multi2dPanner::name);
@@ -959,8 +809,6 @@ Panner::Panner (string name, Session& s)
_linked = false;
_link_direction = SameDirection;
_bypassed = false;
-
- reset_midi_control (_session.mmc_port(), _session.get_mmc_control());
}
Panner::~Panner ()
@@ -1107,8 +955,6 @@ Panner::reset (uint32_t nouts, uint32_t npans)
(*x)->update ();
}
- reset_midi_control (_session.mmc_port(), _session.get_mmc_control());
-
/* force hard left/right panning in a common case: 2in/2out
*/
@@ -1333,7 +1179,7 @@ struct PanPlugins {
PanPlugins pan_plugins[] = {
{ EqualPowerStereoPanner::name, 2, EqualPowerStereoPanner::factory },
{ Multi2dPanner::name, 3, Multi2dPanner::factory },
- { string (""), 0 }
+ { string (""), 0, 0 }
};
XMLNode&
@@ -1361,9 +1207,9 @@ Panner::state (bool full)
for (vector<Panner::Output>::iterator o = outputs.begin(); o != outputs.end(); ++o) {
XMLNode* onode = new XMLNode (X_("Output"));
- snprintf (buf, sizeof (buf), "%f", (*o).x);
+ snprintf (buf, sizeof (buf), "%.12g", (*o).x);
onode->add_property (X_("x"), buf);
- snprintf (buf, sizeof (buf), "%f", (*o).y);
+ snprintf (buf, sizeof (buf), "%.12g", (*o).y);
onode->add_property (X_("y"), buf);
root->add_child_nocopy (*onode);
}
@@ -1412,10 +1258,10 @@ Panner::set_state (const XMLNode& node)
float x, y;
prop = (*niter)->property (X_("x"));
- sscanf (prop->value().c_str(), "%f", &x);
+ sscanf (prop->value().c_str(), "%.12g", &x);
prop = (*niter)->property (X_("y"));
- sscanf (prop->value().c_str(), "%f", &y);
+ sscanf (prop->value().c_str(), "%.12g", &y);
outputs.push_back (Output (x, y));
}
@@ -1490,14 +1336,6 @@ Panner::touching () const
}
void
-Panner::reset_midi_control (MIDI::Port* port, bool on)
-{
- for (vector<StreamPanner*>::const_iterator i = begin(); i != end(); ++i) {
- (*i)->reset_midi_control (port, on);
- }
-}
-
-void
Panner::set_position (float xpos, StreamPanner& orig)
{
float xnow;
@@ -1639,42 +1477,3 @@ Panner::set_position (float xpos, float ypos, float zpos, StreamPanner& orig)
}
}
}
-
-void
-Panner::send_all_midi_feedback ()
-{
- if (_session.get_midi_feedback()) {
- float xpos;
-
- // do feedback for all panners
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- (*i)->get_effective_position (xpos);
-
- (*i)->midi_control().send_feedback (xpos);
- }
-
- }
-}
-
-MIDI::byte*
-Panner::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize)
-{
- AutoState astate = automation_state ();
-
- if (_session.get_midi_feedback() &&
- (astate == Play || (astate == Touch && !touching()))) {
-
- float xpos;
-
- // do feedback for all panners
- for (vector<StreamPanner*>::iterator i = begin(); i != end(); ++i) {
- (*i)->get_effective_position (xpos);
-
- buf = (*i)->midi_control().write_feedback (buf, bufsize, xpos);
- }
-
- }
-
- return buf;
-}
-
diff --git a/libs/ardour/playlist.cc b/libs/ardour/playlist.cc
index 7dee866767..6d5e8f7847 100644
--- a/libs/ardour/playlist.cc
+++ b/libs/ardour/playlist.cc
@@ -77,7 +77,6 @@ Playlist::Playlist (Session& sess, string nom, bool hide)
{
init (hide);
_name = nom;
- _orig_diskstream_id = 0;
}
@@ -86,7 +85,6 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
{
init (hide);
_name = "unnamed"; /* reset by set_state */
- _orig_diskstream_id = 0;
if (set_state (node)) {
throw failed_constructor();
@@ -601,6 +599,31 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
}
void
+Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
+{
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ if (Config->get_use_overlap_equivalency()) {
+ if ((*i)->overlap_equivalent (other)) {
+ results.push_back ((*i));
+ } else if ((*i)->equivalent (other)) {
+ results.push_back ((*i));
+ }
+ }
+ }
+}
+
+void
+Playlist::get_region_list_equivalent_regions (const Region& other, vector<Region*>& results)
+{
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+
+ if ((*i) && (*i)->region_list_equivalent (other)) {
+ results.push_back (*i);
+ }
+ }
+}
+
+void
Playlist::partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level)
{
RegionList thawlist;
@@ -1343,7 +1366,7 @@ Playlist::set_state (const XMLNode& node)
if (prop->name() == X_("name")) {
_name = prop->value();
} else if (prop->name() == X_("orig_diskstream_id")) {
- sscanf (prop->value().c_str(), "%" PRIu64, &_orig_diskstream_id);
+ _orig_diskstream_id = prop->value ();
} else if (prop->name() == X_("frozen")) {
_frozen = (prop->value() == X_("yes"));
}
@@ -1404,7 +1427,7 @@ Playlist::state (bool full_state)
node->add_property (X_("name"), _name);
- snprintf (buf, sizeof(buf), "%" PRIu64, _orig_diskstream_id);
+ _orig_diskstream_id.print (buf);
node->add_property (X_("orig_diskstream_id"), buf);
node->add_property (X_("frozen"), _frozen ? "yes" : "no");
@@ -1725,7 +1748,7 @@ Playlist::nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwa
}
Region*
-Playlist::find_region (id_t id) const
+Playlist::find_region (const ID& id) const
{
RegionLock rlock (const_cast<Playlist*> (this));
RegionList::const_iterator i;
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 2d1f8ffcbd..8ea95b8903 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -35,12 +35,12 @@
#include <pbd/pathscanner.h>
#include <pbd/xml++.h>
-#include <midi++/manager.h>
-
#include <ardour/ardour.h>
#include <ardour/session.h>
#include <ardour/audioengine.h>
#include <ardour/plugin.h>
+#include <ardour/ladspa_plugin.h>
+#include <ardour/plugin_manager.h>
#include <pbd/stl_delete.h>
@@ -61,64 +61,59 @@ Plugin::Plugin (const Plugin& other)
}
void
-Plugin::setup_midi_controls ()
+Plugin::setup_controls ()
{
- uint32_t port_cnt;
-
- port_cnt = parameter_count();
+ uint32_t port_cnt = parameter_count();
- /* set up a vector of null pointers for the MIDI controls.
+ /* set up a vector of null pointers for the controls.
we'll fill this in on an as-needed basis.
*/
for (uint32_t i = 0; i < port_cnt; ++i) {
- midi_controls.push_back (0);
+ controls.push_back (0);
}
}
Plugin::~Plugin ()
{
- for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i) {
+ for (vector<PortControllable*>::iterator i = controls.begin(); i != controls.end(); ++i) {
if (*i) {
delete *i;
}
}
}
-MIDI::Controllable *
-Plugin::get_nth_midi_control (uint32_t n)
+Controllable *
+Plugin::get_nth_control (uint32_t n)
{
if (n >= parameter_count()) {
return 0;
}
- if (midi_controls[n] == 0) {
+ if (controls[n] == 0) {
Plugin::ParameterDescriptor desc;
get_parameter_descriptor (n, desc);
-
- midi_controls[n] = new MIDIPortControl (*this, n, _session.midi_port(), desc.lower, desc.upper, desc.toggled, desc.logarithmic);
+
+ controls[n] = new PortControllable (*this, n, desc.lower, desc.upper, desc.toggled, desc.logarithmic);
}
- return midi_controls[n];
+ return controls[n];
}
-Plugin::MIDIPortControl::MIDIPortControl (Plugin& p, uint32_t port_id, MIDI::Port *port,
- float low, float up, bool t, bool loga)
- : MIDI::Controllable (port, 0), plugin (p), absolute_port (port_id)
+Plugin::PortControllable::PortControllable (Plugin& p, uint32_t port_id, float low, float up, bool t, bool loga)
+ : plugin (p), absolute_port (port_id)
{
toggled = t;
logarithmic = loga;
lower = low;
upper = up;
range = upper - lower;
- last_written = 0; /* XXX need a good out-of-bound-value */
- setting = false;
}
void
-Plugin::MIDIPortControl::set_value (float value)
+Plugin::PortControllable::set_value (float value)
{
if (toggled) {
if (value > 0.5) {
@@ -127,145 +122,40 @@ Plugin::MIDIPortControl::set_value (float value)
value = 0.0;
}
} else {
- value = lower + (range * value);
-
- if (logarithmic) {
- value = exp(value);
- }
- }
- setting = true;
- plugin.set_parameter (absolute_port, value);
- setting = false;
-}
-
-void
-Plugin::MIDIPortControl::send_feedback (float value)
-{
-
- if (!setting && get_midi_feedback()) {
- MIDI::byte val;
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::EventTwoBytes data;
-
- if (toggled) {
- val = (MIDI::byte) (value * 127.0f);
+ if (!logarithmic) {
+ value = lower + (range * value);
} else {
- if (logarithmic) {
- value = log(value);
- }
-
- val = (MIDI::byte) (((value - lower) / range) * 127.0f);
- }
-
- if (get_control_info (ch, ev, additional)) {
- data.controller_number = additional;
- data.value = val;
- last_written = val;
-
- plugin.session().send_midi_message (get_port(), ev, ch, data);
- }
- }
-
-}
-
-MIDI::byte*
-Plugin::MIDIPortControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, float value, bool force)
-{
- if (get_midi_feedback() && bufsize > 2) {
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
-
- if (get_control_info (ch, ev, additional)) {
-
- MIDI::byte val;
-
- if (toggled) {
-
- val = (MIDI::byte) (value * 127.0f);
-
- } else {
-
- if (logarithmic) {
- value = log(value);
- }
-
- val = (MIDI::byte) (((value - lower) / range) * 127.0f);
+ float _lower = 0.0f;
+ if (lower > 0.0f) {
+ _lower = log(lower);
}
- if (val != last_written || force) {
- *buf++ = MIDI::controller & ch;
- *buf++ = additional; /* controller number */
- *buf++ = val;
- last_written = val;
- bufsize -= 3;
- }
+ value = exp(_lower + log(range) * value);
}
}
- return buf;
+ plugin.set_parameter (absolute_port, value);
}
-
-void
-Plugin::reset_midi_control (MIDI::Port* port, bool on)
+float
+Plugin::PortControllable::get_value (void) const
{
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte extra;
-
- for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i) {
- if (*i == 0)
- continue;
- (*i)->get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
- }
- (*i)->midi_rebind (port, chn);
- }
-}
+ float val = plugin.get_parameter (absolute_port);
-void
-Plugin::send_all_midi_feedback ()
-{
- if (_session.get_midi_feedback()) {
- float val = 0.0;
- uint32_t n = 0;
+ if (toggled) {
- for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i, ++n) {
- if (*i == 0) {
- continue;
- }
-
- val = (*i)->plugin.get_parameter (n);
- (*i)->send_feedback (val);
- }
+ return val;
- }
-}
-
-MIDI::byte*
-Plugin::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize)
-{
- if (_session.get_midi_feedback()) {
- float val = 0.0;
- uint32_t n = 0;
+ } else {
- for (vector<MIDIPortControl*>::iterator i = midi_controls.begin(); i != midi_controls.end(); ++i, ++n) {
- if (*i == 0) {
- continue;
- }
-
- val = (*i)->plugin.get_parameter (n);
- buf = (*i)->write_feedback (buf, bufsize, val);
+ if (logarithmic) {
+ val = log(val);
}
+
+ return ((val - lower) / range);
}
-
- return buf;
-}
+}
vector<string>
Plugin::get_presets()
@@ -352,3 +242,43 @@ Plugin::save_preset (string name, string domain)
return true;
}
+
+PluginPtr
+ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::Type type)
+{
+ PluginManager *mgr = PluginManager::the_manager();
+ PluginInfoList plugs;
+
+ switch (type) {
+ case PluginInfo::LADSPA:
+ plugs = mgr->ladspa_plugin_info();
+ break;
+
+#ifdef VST_SUPPORT
+ case PluginInfo::VST:
+ plugs = mgr->vst_plugin_info();
+ unique_id = 0; // VST plugins don't have a unique id.
+ break;
+#endif
+
+#ifdef HAVE_COREAUDIO
+ case PluginInfo::AudioUnit:
+ plugs = AUPluginInfo::discover ();
+ unique_id = 0; // Neither do AU.
+ break;
+#endif
+
+ default:
+ return PluginPtr ((Plugin *) 0);
+ }
+
+ PluginInfoList::iterator i;
+ for (i = plugs.begin(); i != plugs.end(); ++i) {
+ if ((name == "" || (*i)->name == name) &&
+ (unique_id == 0 || (*i)->unique_id == unique_id)) {
+ return (*i)->load (session);
+ }
+ }
+
+ return PluginPtr ((Plugin*) 0);
+}
diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc
index b096e81785..096696aca5 100644
--- a/libs/ardour/plugin_manager.cc
+++ b/libs/ardour/plugin_manager.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2000-2004 Paul Davis
+ Copyright (C) 2000-2006 Paul Davis
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
@@ -27,7 +27,7 @@
#include <fst.h>
#include <pbd/basename.h>
#include <string.h>
-#endif
+#endif // VST_SUPPORT
#include <pbd/pathscanner.h>
@@ -36,7 +36,10 @@
#include <ardour/plugin_manager.h>
#include <ardour/plugin.h>
#include <ardour/ladspa_plugin.h>
+
+#ifdef VST_SUPPORT
#include <ardour/vst_plugin.h>
+#endif
#include <pbd/error.h>
#include <pbd/stl_delete.h>
@@ -48,8 +51,7 @@ using namespace PBD;
PluginManager* PluginManager::_manager = 0;
-PluginManager::PluginManager (AudioEngine& e)
- : _engine (e)
+PluginManager::PluginManager ()
{
char* s;
string lrdf_path;
@@ -95,16 +97,12 @@ PluginManager::refresh ()
if (Config->get_use_vst()) {
vst_refresh ();
}
-#endif
+#endif // VST_SUPPORT
}
void
PluginManager::ladspa_refresh ()
{
- for (std::list<PluginInfo*>::iterator i = _ladspa_plugin_info.begin(); i != _ladspa_plugin_info.end(); ++i) {
- delete *i;
- }
-
_ladspa_plugin_info.clear ();
if (ladspa_path.length() == 0) {
@@ -225,7 +223,6 @@ PluginManager::add_lrdf_data (const string &path)
int
PluginManager::ladspa_discover (string path)
{
- PluginInfo *info;
void *module;
const LADSPA_Descriptor *descriptor;
LADSPA_Descriptor_Function dfunc;
@@ -250,7 +247,7 @@ PluginManager::ladspa_discover (string path)
break;
}
- info = new PluginInfo;
+ PluginInfoPtr info(new LadspaPluginInfo);
info->name = descriptor->Name;
info->category = get_ladspa_category(descriptor->UniqueID);
info->path = path;
@@ -280,82 +277,6 @@ PluginManager::ladspa_discover (string path)
return 0;
}
-Plugin *
-PluginManager::load (Session& session, PluginInfo *info)
-{
- void *module;
- Plugin *plugin = 0;
-
- try {
- if (info->type == PluginInfo::VST) {
-
-#ifdef VST_SUPPORT
- if (Config->get_use_vst()) {
- FSTHandle* handle;
-
- if ((handle = fst_load (info->path.c_str())) == 0) {
- error << string_compose(_("VST: cannot load module from \"%1\""), info->path) << endmsg;
- } else {
- plugin = new VSTPlugin (_engine, session, handle);
- }
- } else {
- error << _("You asked ardour to not use any VST plugins") << endmsg;
- }
-#else
- error << _("This version of ardour has no support for VST plugins") << endmsg;
- return 0;
-#endif
-
- } else {
-
- if ((module = dlopen (info->path.c_str(), RTLD_NOW)) == 0) {
- error << string_compose(_("LADSPA: cannot load module from \"%1\""), info->path) << endmsg;
- error << dlerror() << endmsg;
- } else {
- plugin = new LadspaPlugin (module, _engine, session, info->index, session.frame_rate());
- }
- }
-
- plugin->set_info(*info);
- }
-
- catch (failed_constructor &err) {
- plugin = 0;
- }
-
- return plugin;
-}
-
-Plugin *
-ARDOUR::find_plugin(Session& session, string name, long unique_id, PluginInfo::Type type)
-{
- PluginManager *mgr = PluginManager::the_manager();
- list<PluginInfo *>::iterator i;
- list<PluginInfo *>* plugs = 0;
-
- switch (type) {
- case PluginInfo::LADSPA:
- plugs = &mgr->ladspa_plugin_info();
- break;
- case PluginInfo::VST:
- plugs = &mgr->vst_plugin_info();
- unique_id = 0; // VST plugins don't have a unique id.
- break;
- case PluginInfo::AudioUnit:
- default:
- return 0;
- }
-
- for (i = plugs->begin(); i != plugs->end(); ++i) {
- if ((name == "" || (*i)->name == name) &&
- (unique_id == 0 || (*i)->unique_id == unique_id)) {
- return mgr->load (session, *i);
- }
- }
-
- return 0;
-}
-
string
PluginManager::get_ladspa_category (uint32_t plugin_id)
{
@@ -397,10 +318,6 @@ PluginManager::get_ladspa_category (uint32_t plugin_id)
void
PluginManager::vst_refresh ()
{
- for (std::list<PluginInfo*>::iterator i = _vst_plugin_info.begin(); i != _vst_plugin_info.end(); ++i) {
- delete *i;
- }
-
_vst_plugin_info.clear ();
if (vst_path.length() == 0) {
@@ -454,7 +371,6 @@ int
PluginManager::vst_discover (string path)
{
FSTInfo* finfo;
- PluginInfo* info;
if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
return -1;
@@ -466,7 +382,7 @@ PluginManager::vst_discover (string path)
<< endl;
}
- info = new PluginInfo;
+ PluginInfoPtr info(new PluginInfo);
/* what a goddam joke freeware VST is */
@@ -489,4 +405,4 @@ PluginManager::vst_discover (string path)
return 0;
}
-#endif
+#endif // VST_SUPPORT
diff --git a/libs/ardour/po/el_GR.po b/libs/ardour/po/el_GR.po
index 33c1bb6e85..5d8adef7d0 100644
--- a/libs/ardour/po/el_GR.po
+++ b/libs/ardour/po/el_GR.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 0.664.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-06-27 13:00-0400\n"
+"POT-Creation-Date: 2006-06-29 21:03-0400\n"
"PO-Revision-Date: 2003-05-21 12:50+0500\n"
"Last-Translator: Muadibas\n"
"Language-Team: Hellenic(Greek)\n"
@@ -56,47 +56,47 @@ msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
"DiskStream \"%1\": δεν γίνεται να αποÏÏιφθοÏν δειγματοληψίες στο δίσκο!"
-#: libs/ardour/audio_diskstream.cc:1795
+#: libs/ardour/audio_diskstream.cc:1796
msgid "%1: could not create region for complete audio file"
msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για ολόκληÏο audio file"
-#: libs/ardour/audio_diskstream.cc:1818
+#: libs/ardour/audio_diskstream.cc:1819
#, fuzzy
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr "DiskStream: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για δειγματοληψίες!"
-#: libs/ardour/audio_diskstream.cc:1873
+#: libs/ardour/audio_diskstream.cc:1874
#, fuzzy
msgid "programmer error: %1"
msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1"
-#: libs/ardour/audio_diskstream.cc:2145
+#: libs/ardour/audio_diskstream.cc:2146
#, fuzzy
msgid "AudioDiskstream: channel %1 out of range"
msgstr "DiskStream: κανάλι εκτός διαστήματος"
-#: libs/ardour/audio_diskstream.cc:2170
+#: libs/ardour/audio_diskstream.cc:2171
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 νέα δειγματοληψία δεν εκκινήθη σωστά"
-#: libs/ardour/audio_diskstream.cc:2403
+#: libs/ardour/audio_diskstream.cc:2404
msgid "Location \"%1\" not valid for track loop (start >= end)"
msgstr "Η Τοποθεσία \"%1\" δεν είναι ικανή για track loop (αÏχή >= τέλος)"
-#: libs/ardour/audio_diskstream.cc:2484
+#: libs/ardour/audio_diskstream.cc:2485
#, fuzzy
msgid "%1: cannot restore pending capture source file %2"
msgstr "Εισαγωγή: δεν μποÏÏŽ να ανοίξω το εισαγμένο αÏχείο ήχου \"%1\""
-#: libs/ardour/audio_diskstream.cc:2506
+#: libs/ardour/audio_diskstream.cc:2507
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2522
+#: libs/ardour/audio_diskstream.cc:2523
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2534
+#: libs/ardour/audio_diskstream.cc:2535
#, fuzzy
msgid "%1: cannot create region from pending capture sources"
msgstr "%1: δεν μπόÏεσα να δημιουÏγήσω πεÏιοχή για ολόκληÏο audio file"
@@ -155,36 +155,36 @@ msgstr "αλλαγή xfade"
msgid "region modified"
msgstr "η πεÏιοχή μετεβλήθη"
-#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716
+#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716
#: libs/ardour/io.cc:1826
msgid "Unknown connection \"%1\" listed for input of %2"
msgstr "Άγνωστη σÏνδεση \"%1\" στη λίστα εισόδου του %2"
-#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718
+#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718
#: libs/ardour/io.cc:1828
#, fuzzy
msgid "in 1"
msgstr "in %lu"
-#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719
+#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719
#: libs/ardour/io.cc:1829
msgid "No input connections available as a replacement"
msgstr ""
-#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723
+#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723
#: libs/ardour/io.cc:1833
msgid "Connection %1 was not available - \"in 1\" used instead"
msgstr ""
-#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842
+#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842
msgid "improper input channel list in XML node (%1)"
msgstr "ακατάλληλη λίστα καναλιών εισόδου στον κόμβο XML (%1)"
-#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207
+#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199
msgid "AudioTrack: diskstream \"%1\" not known by session"
msgstr "AudioTrack: το diskstream \"%1\" είναι μή αναγνωÏίσιμο από τη συνεδÏία"
-#: libs/ardour/audio_track.cc:305
+#: libs/ardour/audio_track.cc:297
#, fuzzy
msgid ""
"MIDI rec_enable control specification for %1 is incomplete, so it has been "
@@ -193,7 +193,7 @@ msgstr ""
"Η Ï€ÏοδιαγÏαφή ελέγχου του MIDI gain για το %1 είναι ημιτελής, με αποτέλεσμα "
"να αγνοηθεί"
-#: libs/ardour/audio_track.cc:317
+#: libs/ardour/audio_track.cc:309
msgid "programming error: AudioTrack given state without diskstream!"
msgstr ""
"σφάλμα Ï€ÏογÏαμματισμοÏ: εδόθη κατάσταση στην AudioTrack δίχως diskstream!"
@@ -272,24 +272,24 @@ msgstr "Σφάλμα: δεν μπόÏεσα να γÏάψω %1"
msgid "could not reconnect %1 and %2 (err = %3)"
msgstr ""
-#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095
+#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095
msgid ""
"there are already 1000 files with names like %1; versioning discontinued"
msgstr "ΥπάÏχουν ήδη 1000 αÏχεία με ονόματα όπως %1; μη-συνεχές versioning"
-#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109
+#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109
msgid "cannot rename audio file source from %1 to %2 (%3)"
msgstr "δεν μποÏÏŽ να μετονομάσω την πηγή του audio file από %1 σε %2 (%3)"
-#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124
+#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124
msgid "cannot remove peakfile %1 for %2 (%3)"
msgstr "δεν μποÏÏŽ να απαλοίψω το peakfile %1 για %2 (%3)"
-#: libs/ardour/audiofilesource.cc:510
+#: libs/ardour/audiofilesource.cc:509
msgid "FileSource: search path not set"
msgstr "FileSource: μονοπάτι αναζητήσεως δεν ετέθη"
-#: libs/ardour/audiofilesource.cc:534
+#: libs/ardour/audiofilesource.cc:533
msgid ""
"FileSource: \"%1\" is ambigous when searching %2\n"
"\t"
@@ -297,25 +297,25 @@ msgstr ""
"FileSource: \"%1\" είναι αμφίβολο κατά την αναζήτηση του %2\n"
"\t"
-#: libs/ardour/audiofilesource.cc:540
+#: libs/ardour/audiofilesource.cc:539
#, fuzzy
msgid "Filesource: cannot find required file (%1): while searching %2"
msgstr "Filesource: δεν ευÏέθη το απαιτοÏμενο αÏχείο (%1): %2"
-#: libs/ardour/audiofilesource.cc:563
+#: libs/ardour/audiofilesource.cc:562
msgid "Filesource: cannot find required file (%1): %2"
msgstr "Filesource: δεν ευÏέθη το απαιτοÏμενο αÏχείο (%1): %2"
-#: libs/ardour/audiofilesource.cc:568
+#: libs/ardour/audiofilesource.cc:567
msgid "Filesource: cannot check for existing file (%1): %2"
msgstr "Filesource: δεν μποÏÏŽ να ελέγξω για το υπάÏχον αÏχείο (%1): %2"
-#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525
-#: libs/ardour/sndfilesource.cc:112
+#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525
+#: libs/ardour/sndfilesource.cc:113
msgid "programming error: %1"
msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1"
-#: libs/ardour/audiofilesource.cc:645
+#: libs/ardour/audiofilesource.cc:641
#, fuzzy
msgid "cannot rename audio file for %1 to %2"
msgstr "δεν μποÏÏŽ να μετονομάσω την πηγή του audio file από %1 σε %2 (%3)"
@@ -1837,7 +1837,7 @@ msgstr ""
msgid "cannot remove dead sound file %1 (%2)"
msgstr "δεν μποÏÏŽ να απαλοίψω το 'νεκÏο' ηχο-αÏχείο %1 (%2)"
-#: libs/ardour/session_time.cc:375
+#: libs/ardour/session_time.cc:374
msgid "Unknown JACK transport state %1 in sync callback"
msgstr "Άγνωστη κατάσταση του JACK transport %1 στην ανάκληση sync"
@@ -1979,24 +1979,24 @@ msgstr "Little-endian (Intel)"
msgid "Big-endian (Mac)"
msgstr "Big-endian (Mac)"
-#: libs/ardour/sndfilesource.cc:146
+#: libs/ardour/sndfilesource.cc:147
msgid "FileSource: cannot get host information for BWF header (%1)"
msgstr ""
"FileSource: δεν μποÏÏŽ να βÏÏŽ πληÏοφοÏίες οικοδεσπότη(host) για επικεφαλίδα "
"BWF (%1)"
-#: libs/ardour/sndfilesource.cc:168
+#: libs/ardour/sndfilesource.cc:169
msgid ""
"cannot set broadcast info for audio file %1 (%2); dropping broadcast info "
"for this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:224
+#: libs/ardour/sndfilesource.cc:220
#, fuzzy
msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)"
msgstr "SndFileSource: δεν μποÏÏŽ να ανοίξω το αÏχείο \"%1\" (%2)"
-#: libs/ardour/sndfilesource.cc:230
+#: libs/ardour/sndfilesource.cc:226
msgid ""
"SndFileSource: file only contains %1 channels; %2 is invalid as a channel "
"number"
@@ -2004,22 +2004,22 @@ msgstr ""
"SndFileSource: το αÏχείο πεÏιέχει μόνο %1 κανάλια; %2 δεν έχει αξία σαν "
"κανάλι number"
-#: libs/ardour/sndfilesource.cc:307
+#: libs/ardour/sndfilesource.cc:327
msgid "SndFileSource: could not seek to frame %1 within %2 (%3)"
msgstr "SndFileSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μέσα στο %2 (%3)"
-#: libs/ardour/sndfilesource.cc:358
+#: libs/ardour/sndfilesource.cc:378
#, fuzzy
msgid "programming error: %1 %2"
msgstr "σφάλμα Ï€ÏογÏαμματισμοÏ: %1"
-#: libs/ardour/sndfilesource.cc:458
+#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533
msgid ""
"cannot set broadcast info for audio file %1; Dropping broadcast info for "
"this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:500
+#: libs/ardour/sndfilesource.cc:544
#, fuzzy
msgid "%1: cannot seek to %2"
msgstr "%1: δεν μποÏÏŽ να αναζητήσω στο %2 για εξαγωγή"
@@ -2166,7 +2166,7 @@ msgid "no support for presets using chunks at this time"
msgstr ""
"καμμία υποστήÏιξη αυτή τη στιγμή για Ïυθμίσεις που χÏησιμοποιοÏν κομμάτια"
-#: libs/ardour/coreaudio_source.cc:99
+#: libs/ardour/coreaudiosource.cc:97
#, fuzzy
msgid ""
"CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel "
@@ -2175,7 +2175,7 @@ msgstr ""
"SndFileSource: το αÏχείο πεÏιέχει μόνο %1 κανάλια; %2 δεν έχει αξία σαν "
"κανάλι number"
-#: libs/ardour/coreaudio_source.cc:164
+#: libs/ardour/coreaudiosource.cc:162
#, fuzzy
msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)"
msgstr "SndFileSource: δεν μποÏοÏσα να αναζητήσω στο frame %1 μέσα στο %2 (%3)"
diff --git a/libs/ardour/po/it_IT.po b/libs/ardour/po/it_IT.po
index 63089ea77f..2ce02827bd 100644
--- a/libs/ardour/po/it_IT.po
+++ b/libs/ardour/po/it_IT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 0.664.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-06-27 13:00-0400\n"
+"POT-Creation-Date: 2006-06-29 21:03-0400\n"
"PO-Revision-Date: 2003-05-21 12:50+0500\n"
"Last-Translator: Filippo Pappalardo <filippo@email.it>\n"
"Language-Team: Italian\n"
@@ -50,48 +50,48 @@ msgstr "DiskStream %1: impossibile scrivere sul disco"
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr "DiskStream \"%1\": impossibile scaricare i dati acquisiti sul disco!"
-#: libs/ardour/audio_diskstream.cc:1795
+#: libs/ardour/audio_diskstream.cc:1796
msgid "%1: could not create region for complete audio file"
msgstr "%1: impossibile creare una regione per il file audio completo"
-#: libs/ardour/audio_diskstream.cc:1818
+#: libs/ardour/audio_diskstream.cc:1819
#, fuzzy
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr "DiskStream: impossibile creare una regione per l'audio registrato!"
-#: libs/ardour/audio_diskstream.cc:1873
+#: libs/ardour/audio_diskstream.cc:1874
#, fuzzy
msgid "programmer error: %1"
msgstr "errore di programmazione: %1"
-#: libs/ardour/audio_diskstream.cc:2145
+#: libs/ardour/audio_diskstream.cc:2146
#, fuzzy
msgid "AudioDiskstream: channel %1 out of range"
msgstr "DiskStream: canale fuori margine"
-#: libs/ardour/audio_diskstream.cc:2170
+#: libs/ardour/audio_diskstream.cc:2171
msgid "%1:%2 new capture file not initialized correctly"
msgstr "%1:%2 nuovo file di registrazione non è stato avviato correttamente"
-#: libs/ardour/audio_diskstream.cc:2403
+#: libs/ardour/audio_diskstream.cc:2404
msgid "Location \"%1\" not valid for track loop (start >= end)"
msgstr "La Location \"%1\" non valida per il loop (inizio >= fine)"
-#: libs/ardour/audio_diskstream.cc:2484
+#: libs/ardour/audio_diskstream.cc:2485
#, fuzzy
msgid "%1: cannot restore pending capture source file %2"
msgstr "Import: impossibile aprire il file audio di input \"%1\""
-#: libs/ardour/audio_diskstream.cc:2506
+#: libs/ardour/audio_diskstream.cc:2507
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2522
+#: libs/ardour/audio_diskstream.cc:2523
#, fuzzy
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr "Playlist: impossibile creare la Regione dal file di stato"
-#: libs/ardour/audio_diskstream.cc:2534
+#: libs/ardour/audio_diskstream.cc:2535
#, fuzzy
msgid "%1: cannot create region from pending capture sources"
msgstr "Playlist: impossibile creare la Regione dal file di stato"
@@ -145,41 +145,41 @@ msgstr "cambio dello smorzamento incrociato"
msgid "region modified"
msgstr "regione modificata"
-#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716
+#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716
#: libs/ardour/io.cc:1826
msgid "Unknown connection \"%1\" listed for input of %2"
msgstr "Connessione sconosciuta \"%1\" come input di %2"
-#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718
+#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718
#: libs/ardour/io.cc:1828
msgid "in 1"
msgstr ""
-#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719
+#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719
#: libs/ardour/io.cc:1829
msgid "No input connections available as a replacement"
msgstr ""
-#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723
+#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723
#: libs/ardour/io.cc:1833
msgid "Connection %1 was not available - \"in 1\" used instead"
msgstr ""
-#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842
+#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842
msgid "improper input channel list in XML node (%1)"
msgstr ""
-#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207
+#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199
msgid "AudioTrack: diskstream \"%1\" not known by session"
msgstr "AudioTrack: diskstream \"%1\" non riconosciuto dalla sessione"
-#: libs/ardour/audio_track.cc:305
+#: libs/ardour/audio_track.cc:297
msgid ""
"MIDI rec_enable control specification for %1 is incomplete, so it has been "
"ignored"
msgstr ""
-#: libs/ardour/audio_track.cc:317
+#: libs/ardour/audio_track.cc:309
msgid "programming error: AudioTrack given state without diskstream!"
msgstr ""
@@ -268,25 +268,25 @@ msgstr "Esportazione: impossibile scrivere dati sul file di output (%1)"
msgid "could not reconnect %1 and %2 (err = %3)"
msgstr ""
-#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095
+#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095
msgid ""
"there are already 1000 files with names like %1; versioning discontinued"
msgstr ""
"ci sono gia' 1000 file con nomi come %1; tracciamento di versione interrotto"
-#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109
+#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109
msgid "cannot rename audio file source from %1 to %2 (%3)"
msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)"
-#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124
+#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124
msgid "cannot remove peakfile %1 for %2 (%3)"
msgstr "impossibile eliminare il peakfile %1 per %2 (%3)"
-#: libs/ardour/audiofilesource.cc:510
+#: libs/ardour/audiofilesource.cc:509
msgid "FileSource: search path not set"
msgstr "FileSource: percorso di ricerca non specificato"
-#: libs/ardour/audiofilesource.cc:534
+#: libs/ardour/audiofilesource.cc:533
msgid ""
"FileSource: \"%1\" is ambigous when searching %2\n"
"\t"
@@ -294,25 +294,25 @@ msgstr ""
"FileSource: \"%1\" è risultato ambiguo nel cercare %2\n"
"\t"
-#: libs/ardour/audiofilesource.cc:540
+#: libs/ardour/audiofilesource.cc:539
#, fuzzy
msgid "Filesource: cannot find required file (%1): while searching %2"
msgstr "FileSource: impossibile trovare il file richiesto (%1): %2"
-#: libs/ardour/audiofilesource.cc:563
+#: libs/ardour/audiofilesource.cc:562
msgid "Filesource: cannot find required file (%1): %2"
msgstr "FileSource: impossibile trovare il file richiesto (%1): %2"
-#: libs/ardour/audiofilesource.cc:568
+#: libs/ardour/audiofilesource.cc:567
msgid "Filesource: cannot check for existing file (%1): %2"
msgstr "FileSource: impossibile controllare il file esistente (%1): %2"
-#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525
-#: libs/ardour/sndfilesource.cc:112
+#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525
+#: libs/ardour/sndfilesource.cc:113
msgid "programming error: %1"
msgstr "errore di programmazione: %1"
-#: libs/ardour/audiofilesource.cc:645
+#: libs/ardour/audiofilesource.cc:641
#, fuzzy
msgid "cannot rename audio file for %1 to %2"
msgstr "impossibile rinominare file audio sorgente da %1 a %2 (%3)"
@@ -1782,7 +1782,7 @@ msgstr "Nodo sconosciuto \"%1\" trovato in Connections list dal file di stato"
msgid "cannot remove dead sound file %1 (%2)"
msgstr "impossibile accedere al file audio per il click %1 (%2)"
-#: libs/ardour/session_time.cc:375
+#: libs/ardour/session_time.cc:374
msgid "Unknown JACK transport state %1 in sync callback"
msgstr ""
@@ -1915,22 +1915,22 @@ msgstr ""
msgid "Big-endian (Mac)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:146
+#: libs/ardour/sndfilesource.cc:147
msgid "FileSource: cannot get host information for BWF header (%1)"
msgstr "FileSource: impossibile ottenere info sull'host dall'header BWF (%1)"
-#: libs/ardour/sndfilesource.cc:168
+#: libs/ardour/sndfilesource.cc:169
msgid ""
"cannot set broadcast info for audio file %1 (%2); dropping broadcast info "
"for this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:224
+#: libs/ardour/sndfilesource.cc:220
#, fuzzy
msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)"
msgstr "SndFileSource: impossibile accedere al file \"%1\" (%2)"
-#: libs/ardour/sndfilesource.cc:230
+#: libs/ardour/sndfilesource.cc:226
msgid ""
"SndFileSource: file only contains %1 channels; %2 is invalid as a channel "
"number"
@@ -1938,22 +1938,22 @@ msgstr ""
"SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero "
"di canale"
-#: libs/ardour/sndfilesource.cc:307
+#: libs/ardour/sndfilesource.cc:327
msgid "SndFileSource: could not seek to frame %1 within %2 (%3)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:358
+#: libs/ardour/sndfilesource.cc:378
#, fuzzy
msgid "programming error: %1 %2"
msgstr "errore di programmazione: %1"
-#: libs/ardour/sndfilesource.cc:458
+#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533
msgid ""
"cannot set broadcast info for audio file %1; Dropping broadcast info for "
"this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:500
+#: libs/ardour/sndfilesource.cc:544
msgid "%1: cannot seek to %2"
msgstr ""
@@ -2100,7 +2100,7 @@ msgstr ""
msgid "no support for presets using chunks at this time"
msgstr ""
-#: libs/ardour/coreaudio_source.cc:99
+#: libs/ardour/coreaudiosource.cc:97
#, fuzzy
msgid ""
"CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel "
@@ -2109,7 +2109,7 @@ msgstr ""
"SndFileSource: il file contiene solo %1 canali; %2 non è valido come numero "
"di canale"
-#: libs/ardour/coreaudio_source.cc:164
+#: libs/ardour/coreaudiosource.cc:162
msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)"
msgstr ""
diff --git a/libs/ardour/po/ru_RU.po b/libs/ardour/po/ru_RU.po
index 2ca30cba55..aeeb1bf547 100644
--- a/libs/ardour/po/ru_RU.po
+++ b/libs/ardour/po/ru_RU.po
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libardour 0.716.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2006-06-27 13:00-0400\n"
+"POT-Creation-Date: 2006-06-29 21:03-0400\n"
"PO-Revision-Date: 2004-03-31 00:55+0300\n"
"Last-Translator: Igor Blinov pitstop@nm.ru\n"
"Language-Team: Russian\n"
@@ -43,44 +43,44 @@ msgstr ""
msgid "AudioDiskstream \"%1\": cannot flush captured data to disk!"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:1795
+#: libs/ardour/audio_diskstream.cc:1796
msgid "%1: could not create region for complete audio file"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:1818
+#: libs/ardour/audio_diskstream.cc:1819
msgid "AudioDiskstream: could not create region for captured audio!"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:1873
+#: libs/ardour/audio_diskstream.cc:1874
#, fuzzy
msgid "programmer error: %1"
msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: "
-#: libs/ardour/audio_diskstream.cc:2145
+#: libs/ardour/audio_diskstream.cc:2146
msgid "AudioDiskstream: channel %1 out of range"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2170
+#: libs/ardour/audio_diskstream.cc:2171
msgid "%1:%2 new capture file not initialized correctly"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2403
+#: libs/ardour/audio_diskstream.cc:2404
msgid "Location \"%1\" not valid for track loop (start >= end)"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2484
+#: libs/ardour/audio_diskstream.cc:2485
msgid "%1: cannot restore pending capture source file %2"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2506
+#: libs/ardour/audio_diskstream.cc:2507
msgid "%1: incorrect number of pending sources listed - ignoring them all"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2522
+#: libs/ardour/audio_diskstream.cc:2523
msgid "%1: cannot create whole-file region from pending capture sources"
msgstr ""
-#: libs/ardour/audio_diskstream.cc:2534
+#: libs/ardour/audio_diskstream.cc:2535
msgid "%1: cannot create region from pending capture sources"
msgstr ""
@@ -133,41 +133,41 @@ msgstr ""
msgid "region modified"
msgstr ""
-#: libs/ardour/audio_track.cc:133 libs/ardour/io.cc:1716
+#: libs/ardour/audio_track.cc:125 libs/ardour/io.cc:1716
#: libs/ardour/io.cc:1826
msgid "Unknown connection \"%1\" listed for input of %2"
msgstr ""
-#: libs/ardour/audio_track.cc:135 libs/ardour/io.cc:1718
+#: libs/ardour/audio_track.cc:127 libs/ardour/io.cc:1718
#: libs/ardour/io.cc:1828
msgid "in 1"
msgstr ""
-#: libs/ardour/audio_track.cc:136 libs/ardour/io.cc:1719
+#: libs/ardour/audio_track.cc:128 libs/ardour/io.cc:1719
#: libs/ardour/io.cc:1829
msgid "No input connections available as a replacement"
msgstr ""
-#: libs/ardour/audio_track.cc:140 libs/ardour/io.cc:1723
+#: libs/ardour/audio_track.cc:132 libs/ardour/io.cc:1723
#: libs/ardour/io.cc:1833
msgid "Connection %1 was not available - \"in 1\" used instead"
msgstr ""
-#: libs/ardour/audio_track.cc:149 libs/ardour/io.cc:1842
+#: libs/ardour/audio_track.cc:141 libs/ardour/io.cc:1842
msgid "improper input channel list in XML node (%1)"
msgstr ""
-#: libs/ardour/audio_track.cc:194 libs/ardour/audio_track.cc:207
+#: libs/ardour/audio_track.cc:186 libs/ardour/audio_track.cc:199
msgid "AudioTrack: diskstream \"%1\" not known by session"
msgstr ""
-#: libs/ardour/audio_track.cc:305
+#: libs/ardour/audio_track.cc:297
msgid ""
"MIDI rec_enable control specification for %1 is incomplete, so it has been "
"ignored"
msgstr ""
-#: libs/ardour/audio_track.cc:317
+#: libs/ardour/audio_track.cc:309
msgid "programming error: AudioTrack given state without diskstream!"
msgstr ""
@@ -243,48 +243,48 @@ msgstr ""
msgid "could not reconnect %1 and %2 (err = %3)"
msgstr ""
-#: libs/ardour/audiofilesource.cc:445 libs/ardour/session_state.cc:3095
+#: libs/ardour/audiofilesource.cc:444 libs/ardour/session_state.cc:3095
msgid ""
"there are already 1000 files with names like %1; versioning discontinued"
msgstr ""
-#: libs/ardour/audiofilesource.cc:459 libs/ardour/session_state.cc:3109
+#: libs/ardour/audiofilesource.cc:458 libs/ardour/session_state.cc:3109
msgid "cannot rename audio file source from %1 to %2 (%3)"
msgstr ""
-#: libs/ardour/audiofilesource.cc:466 libs/ardour/session_state.cc:3124
+#: libs/ardour/audiofilesource.cc:465 libs/ardour/session_state.cc:3124
msgid "cannot remove peakfile %1 for %2 (%3)"
msgstr ""
-#: libs/ardour/audiofilesource.cc:510
+#: libs/ardour/audiofilesource.cc:509
msgid "FileSource: search path not set"
msgstr ""
-#: libs/ardour/audiofilesource.cc:534
+#: libs/ardour/audiofilesource.cc:533
msgid ""
"FileSource: \"%1\" is ambigous when searching %2\n"
"\t"
msgstr ""
-#: libs/ardour/audiofilesource.cc:540
+#: libs/ardour/audiofilesource.cc:539
msgid "Filesource: cannot find required file (%1): while searching %2"
msgstr ""
-#: libs/ardour/audiofilesource.cc:563
+#: libs/ardour/audiofilesource.cc:562
msgid "Filesource: cannot find required file (%1): %2"
msgstr ""
-#: libs/ardour/audiofilesource.cc:568
+#: libs/ardour/audiofilesource.cc:567
msgid "Filesource: cannot check for existing file (%1): %2"
msgstr ""
-#: libs/ardour/audiofilesource.cc:640 libs/ardour/insert.cc:525
-#: libs/ardour/sndfilesource.cc:112
+#: libs/ardour/audiofilesource.cc:636 libs/ardour/insert.cc:525
+#: libs/ardour/sndfilesource.cc:113
#, fuzzy
msgid "programming error: %1"
msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: "
-#: libs/ardour/audiofilesource.cc:645
+#: libs/ardour/audiofilesource.cc:641
msgid "cannot rename audio file for %1 to %2"
msgstr ""
@@ -1684,7 +1684,7 @@ msgstr ""
msgid "cannot remove dead sound file %1 (%2)"
msgstr ""
-#: libs/ardour/session_time.cc:375
+#: libs/ardour/session_time.cc:374
msgid "Unknown JACK transport state %1 in sync callback"
msgstr ""
@@ -1816,42 +1816,42 @@ msgstr ""
msgid "Big-endian (Mac)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:146
+#: libs/ardour/sndfilesource.cc:147
msgid "FileSource: cannot get host information for BWF header (%1)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:168
+#: libs/ardour/sndfilesource.cc:169
msgid ""
"cannot set broadcast info for audio file %1 (%2); dropping broadcast info "
"for this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:224
+#: libs/ardour/sndfilesource.cc:220
msgid "SndFileSource: cannot open file \"%1\" for %2 (%3)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:230
+#: libs/ardour/sndfilesource.cc:226
msgid ""
"SndFileSource: file only contains %1 channels; %2 is invalid as a channel "
"number"
msgstr ""
-#: libs/ardour/sndfilesource.cc:307
+#: libs/ardour/sndfilesource.cc:327
msgid "SndFileSource: could not seek to frame %1 within %2 (%3)"
msgstr ""
-#: libs/ardour/sndfilesource.cc:358
+#: libs/ardour/sndfilesource.cc:378
#, fuzzy
msgid "programming error: %1 %2"
msgstr "ÏÛÉÂËÁ ÐÒÏÇÒÁÍÍÙ: "
-#: libs/ardour/sndfilesource.cc:458
+#: libs/ardour/sndfilesource.cc:487 libs/ardour/sndfilesource.cc:533
msgid ""
"cannot set broadcast info for audio file %1; Dropping broadcast info for "
"this file"
msgstr ""
-#: libs/ardour/sndfilesource.cc:500
+#: libs/ardour/sndfilesource.cc:544
msgid "%1: cannot seek to %2"
msgstr ""
@@ -1989,12 +1989,12 @@ msgstr ""
msgid "no support for presets using chunks at this time"
msgstr ""
-#: libs/ardour/coreaudio_source.cc:99
+#: libs/ardour/coreaudiosource.cc:97
msgid ""
"CoreAudioSource: file only contains %1 channels; %2 is invalid as a channel "
"number"
msgstr ""
-#: libs/ardour/coreaudio_source.cc:164
+#: libs/ardour/coreaudiosource.cc:162
msgid "CoreAudioSource: could not seek to frame %1 within %2 (%3)"
msgstr ""
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index c5c03d0a05..7ec0d5a05a 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -24,15 +24,15 @@ using namespace ARDOUR;
using namespace std;
Port::Port (jack_port_t *p)
- : port (p)
+ : _port (p)
{
- if (port == 0) {
+ if (_port == 0) {
throw failed_constructor();
}
- _flags = JackPortFlags (jack_port_flags (port));
- _type = jack_port_type (port);
- _name = jack_port_name (port);
+ _flags = JackPortFlags (jack_port_flags (_port));
+ _type = jack_port_type (_port);
+ _name = jack_port_name (_port);
reset ();
}
@@ -42,9 +42,9 @@ Port::reset ()
{
reset_buffer ();
- last_monitor = false;
- silent = false;
- metering = 0;
+ _last_monitor = false;
+ _silent = false;
+ _metering = 0;
reset_meters ();
}
@@ -54,7 +54,7 @@ Port::set_name (string str)
{
int ret;
- if ((ret = jack_port_set_name (port, str.c_str())) == 0) {
+ if ((ret = jack_port_set_name (_port, str.c_str())) == 0) {
_name = str;
}
diff --git a/libs/ardour/redirect.cc b/libs/ardour/redirect.cc
index 33fec5088f..1ab2f91cf0 100644
--- a/libs/ardour/redirect.cc
+++ b/libs/ardour/redirect.cc
@@ -60,25 +60,25 @@ Redirect::~Redirect ()
{
}
-Redirect*
-Redirect::clone (const Redirect& other)
+boost::shared_ptr<Redirect>
+Redirect::clone (boost::shared_ptr<const Redirect> other)
{
- const Send *send;
- const PortInsert *port_insert;
- const PluginInsert *plugin_insert;
-
- if ((send = dynamic_cast<const Send*>(&other)) != 0) {
- return new Send (*send);
- } else if ((port_insert = dynamic_cast<const PortInsert*>(&other)) != 0) {
- return new PortInsert (*port_insert);
- } else if ((plugin_insert = dynamic_cast<const PluginInsert*>(&other)) != 0) {
- return new PluginInsert (*plugin_insert);
+ boost::shared_ptr<const Send> send;
+ boost::shared_ptr<const PortInsert> port_insert;
+ boost::shared_ptr<const PluginInsert> plugin_insert;
+
+ if ((send = boost::dynamic_pointer_cast<const Send>(other)) != 0) {
+ return boost::shared_ptr<Redirect> (new Send (*send));
+ } else if ((port_insert = boost::dynamic_pointer_cast<const PortInsert>(other)) != 0) {
+ return boost::shared_ptr<Redirect> (new PortInsert (*port_insert));
+ } else if ((plugin_insert = boost::dynamic_pointer_cast<const PluginInsert>(other)) != 0) {
+ return boost::shared_ptr<Redirect> (new PluginInsert (*plugin_insert));
} else {
fatal << _("programming error: unknown Redirect type in Redirect::Clone!\n")
<< endmsg;
/*NOTREACHED*/
}
- return 0;
+ return boost::shared_ptr<Redirect>();
}
void
@@ -231,9 +231,9 @@ Redirect::state (bool full_state)
string path;
string legal_name;
- snprintf (buf, sizeof(buf), "%" PRIu64, id());
path = _session.snap_name();
path += "-redirect-";
+ id().print (buf);
path += buf;
path += ".automation";
diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc
index 8c27a3bebc..037c844324 100644
--- a/libs/ardour/region.cc
+++ b/libs/ardour/region.cc
@@ -39,13 +39,13 @@ using namespace std;
using namespace ARDOUR;
using namespace PBD;
-Change Region::FadeChanged = ARDOUR::new_change ();
+Change Region::FadeChanged = ARDOUR::new_change ();
Change Region::SyncOffsetChanged = ARDOUR::new_change ();
-Change Region::MuteChanged = ARDOUR::new_change ();
-Change Region::OpacityChanged = ARDOUR::new_change ();
-Change Region::LockChanged = ARDOUR::new_change ();
-Change Region::LayerChanged = ARDOUR::new_change ();
-Change Region::HiddenChanged = ARDOUR::new_change ();
+Change Region::MuteChanged = ARDOUR::new_change ();
+Change Region::OpacityChanged = ARDOUR::new_change ();
+Change Region::LockChanged = ARDOUR::new_change ();
+Change Region::LayerChanged = ARDOUR::new_change ();
+Change Region::HiddenChanged = ARDOUR::new_change ();
sigc::signal<void,Region *> Region::CheckNewRegion;
@@ -53,7 +53,6 @@ Region::Region (jack_nframes_t start, jack_nframes_t length, const string& name,
{
/* basic Region constructor */
- _id = ARDOUR::new_id();
_flags = flags;
_playlist = 0;
_read_data_count = 0;
@@ -76,7 +75,6 @@ Region::Region (const Region& other, jack_nframes_t offset, jack_nframes_t lengt
{
/* create a new Region from part of an existing one */
- _id = ARDOUR::new_id();
_frozen = 0;
pending_changed = Change (0);
_playlist = 0;
@@ -102,7 +100,6 @@ Region::Region (const Region &other)
{
/* Pure copy constructor */
- _id = ARDOUR::new_id();
_frozen = 0;
pending_changed = Change (0);
_playlist = 0;
@@ -130,7 +127,6 @@ Region::Region (const Region &other)
Region::Region (const XMLNode& node)
{
- _id = 0;
_frozen = 0;
pending_changed = Change (0);
_playlist = 0;
@@ -844,7 +840,7 @@ Region::state (bool full_state)
XMLNode *node = new XMLNode ("Region");
char buf[64];
- snprintf (buf, sizeof (buf), "%" PRIu64, _id);
+ _id.print (buf);
node->add_property ("id", buf);
node->add_property ("name", _name);
snprintf (buf, sizeof (buf), "%u", _start);
@@ -886,7 +882,7 @@ Region::set_state (const XMLNode& node)
return -1;
}
- sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+ _id = prop->value();
if ((prop = node.property ("name")) == 0) {
error << _("Session: XMLNode describing a Region is incomplete (no name)") << endmsg;
@@ -994,3 +990,30 @@ Region::set_last_layer_op (uint64_t when)
{
_last_layer_op = when;
}
+
+bool
+Region::overlap_equivalent (const Region& other) const
+{
+ return coverage (other.first_frame(), other.last_frame()) != OverlapNone;
+}
+
+bool
+Region::equivalent (const Region& other) const
+{
+ return _start == other._start &&
+ _position == other._position &&
+ _length == other._length;
+}
+
+bool
+Region::size_equivalent (const Region& other) const
+{
+ return _start == other._start &&
+ _length == other._length;
+}
+
+bool
+Region::region_list_equivalent (const Region& other) const
+{
+ return size_equivalent (other) && source_equivalent (other) && _name == other._name;
+}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 3f51b2f140..b47981a47e 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -20,11 +20,13 @@
#include <cmath>
#include <fstream>
+#include <cassert>
#include <sigc++/bind.h>
#include <pbd/xml++.h>
#include <ardour/timestamps.h>
+#include <ardour/buffer.h>
#include <ardour/audioengine.h>
#include <ardour/route.h>
#include <ardour/insert.h>
@@ -50,19 +52,19 @@ using namespace PBD;
uint32_t Route::order_key_cnt = 0;
-Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg)
- : IO (sess, name, input_min, input_max, output_min, output_max),
+Route::Route (Session& sess, string name, int input_min, int input_max, int output_min, int output_max, Flag flg, DataType default_type)
+ : IO (sess, name, input_min, input_max, output_min, output_max, default_type),
_flags (flg),
- _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()),
- _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port())
+ _solo_control (*this, ToggleControllable::SoloControl),
+ _mute_control (*this, ToggleControllable::MuteControl)
{
init ();
}
Route::Route (Session& sess, const XMLNode& node)
: IO (sess, "route"),
- _midi_solo_control (*this, MIDIToggleControl::SoloControl, _session.midi_port()),
- _midi_mute_control (*this, MIDIToggleControl::MuteControl, _session.midi_port())
+ _solo_control (*this, ToggleControllable::SoloControl),
+ _mute_control (*this, ToggleControllable::MuteControl)
{
init ();
set_state (node);
@@ -105,8 +107,6 @@ Route::init ()
input_changed.connect (mem_fun (this, &Route::input_change_handler));
output_changed.connect (mem_fun (this, &Route::output_change_handler));
-
- reset_midi_control (_session.midi_port(), _session.get_midi_control());
}
Route::~Route ()
@@ -712,11 +712,8 @@ Route::set_solo (bool yn, void *src)
if (_soloed != yn) {
_soloed = yn;
- solo_changed (src); /* EMIT SIGNAL */
-
- if (_session.get_midi_feedback()) {
- _midi_solo_control.send_feedback (_soloed);
- }
+ solo_changed (src); /* EMIT SIGNAL */
+ _solo_control.Changed (); /* EMIT SIGNAL */
}
}
@@ -753,9 +750,7 @@ Route::set_mute (bool yn, void *src)
_muted = yn;
mute_changed (src); /* EMIT SIGNAL */
- if (_session.get_midi_feedback()) {
- _midi_mute_control.send_feedback (_muted);
- }
+ _mute_control.Changed (); /* EMIT SIGNAL */
Glib::Mutex::Lock lm (declick_lock);
desired_mute_gain = (yn?0.0f:1.0f);
@@ -763,7 +758,7 @@ Route::set_mute (bool yn, void *src)
}
int
-Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
+Route::add_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
{
uint32_t old_rmo = redirect_max_outs;
@@ -774,12 +769,12 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
{
Glib::RWLock::WriterLock lm (redirect_lock);
- PluginInsert* pi;
- PortInsert* porti;
+ boost::shared_ptr<PluginInsert> pi;
+ boost::shared_ptr<PortInsert> porti;
uint32_t potential_max_streams = 0;
- if ((pi = dynamic_cast<PluginInsert*>(redirect)) != 0) {
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(redirect)) != 0) {
pi->set_count (1);
if (pi->input_streams() == 0) {
@@ -788,8 +783,8 @@ Route::add_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
}
potential_max_streams = max(pi->input_streams(), pi->output_streams());
-
- } else if ((porti = dynamic_cast<PortInsert*>(redirect)) != 0) {
+
+ } else if ((porti = boost::dynamic_pointer_cast<PortInsert>(redirect)) != 0) {
/* force new port inserts to start out with an i/o configuration
that matches this route's i/o configuration.
@@ -854,9 +849,9 @@ Route::add_redirects (const RedirectList& others, void *src, uint32_t* err_strea
for (RedirectList::const_iterator i = others.begin(); i != others.end(); ++i) {
- PluginInsert* pi;
+ boost::shared_ptr<PluginInsert> pi;
- if ((pi = dynamic_cast<PluginInsert*>(*i)) != 0) {
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
pi->set_count (1);
uint32_t m = max(pi->input_streams(), pi->output_streams());
@@ -905,11 +900,6 @@ Route::clear_redirects (void *src)
{
Glib::RWLock::WriterLock lm (redirect_lock);
-
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- delete *i;
- }
-
_redirects.clear ();
}
@@ -923,7 +913,7 @@ Route::clear_redirects (void *src)
}
int
-Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
+Route::remove_redirect (boost::shared_ptr<Redirect> redirect, void *src, uint32_t* err_streams)
{
uint32_t old_rmo = redirect_max_outs;
@@ -955,13 +945,13 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
run.
*/
- Send* send;
- PortInsert* port_insert;
+ boost::shared_ptr<Send> send;
+ boost::shared_ptr<PortInsert> port_insert;
- if ((send = dynamic_cast<Send*> (*i)) != 0) {
+ if ((send = boost::dynamic_pointer_cast<Send> (*i)) != 0) {
send->disconnect_inputs (this);
send->disconnect_outputs (this);
- } else if ((port_insert = dynamic_cast<PortInsert*> (*i)) != 0) {
+ } else if ((port_insert = boost::dynamic_pointer_cast<PortInsert> (*i)) != 0) {
port_insert->disconnect_inputs (this);
port_insert->disconnect_outputs (this);
}
@@ -990,9 +980,9 @@ Route::remove_redirect (Redirect *redirect, void *src, uint32_t* err_streams)
bool foo = false;
for (i = _redirects.begin(); i != _redirects.end(); ++i) {
- PluginInsert* pi;
-
- if ((pi = dynamic_cast<PluginInsert*>(*i)) != 0) {
+ boost::shared_ptr<PluginInsert> pi;
+
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(*i)) != 0) {
if (pi->is_generator()) {
foo = true;
}
@@ -1039,7 +1029,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
for (r = _redirects.begin(); r != _redirects.end(); ++r) {
- Insert *insert;
+ boost::shared_ptr<Insert> insert;
/* do this here in case we bomb out before we get to the end of
this function.
@@ -1047,22 +1037,22 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
redirect_max_outs = max ((*r)->output_streams (), redirect_max_outs);
- if ((insert = dynamic_cast<Insert*>(*r)) != 0) {
+ if ((insert = boost::dynamic_pointer_cast<Insert>(*r)) != 0) {
++i_cnt;
- insert_map[insert->placement()].push_back (InsertCount (*insert));
+ insert_map[insert->placement()].push_back (InsertCount (insert));
/* reset plugin counts back to one for now so
that we have a predictable, controlled
state to try to configure.
*/
- PluginInsert* pi;
+ boost::shared_ptr<PluginInsert> pi;
- if ((pi = dynamic_cast<PluginInsert*>(insert)) != 0) {
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert>(insert)) != 0) {
pi->set_count (1);
}
- } else if (dynamic_cast<Send*> (*r) != 0) {
+ } else if (boost::dynamic_pointer_cast<Send> (*r) != 0) {
++s_cnt;
}
}
@@ -1089,7 +1079,7 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
if (!insert_map[PreFader].empty()) {
InsertCount& ic (insert_map[PreFader].back());
- initial_streams = ic.insert.compute_output_streams (ic.cnt);
+ initial_streams = ic.insert->compute_output_streams (ic.cnt);
} else {
initial_streams = n_inputs ();
}
@@ -1113,9 +1103,9 @@ Route::_reset_plugin_counts (uint32_t* err_streams)
RedirectList::iterator prev = _redirects.end();
for (r = _redirects.begin(); r != _redirects.end(); prev = r, ++r) {
- Send* s;
+ boost::shared_ptr<Send> s;
- if ((s = dynamic_cast<Send*> (*r)) != 0) {
+ if ((s = boost::dynamic_pointer_cast<Send> (*r)) != 0) {
if (r == _redirects.begin()) {
s->expect_inputs (n_inputs());
} else {
@@ -1138,11 +1128,11 @@ Route::apply_some_plugin_counts (list<InsertCount>& iclist)
for (i = iclist.begin(); i != iclist.end(); ++i) {
- if ((*i).insert.configure_io ((*i).cnt, (*i).in, (*i).out)) {
+ if ((*i).insert->configure_io ((*i).cnt, (*i).in, (*i).out)) {
return -1;
}
/* make sure that however many we have, they are all active */
- (*i).insert.activate ();
+ (*i).insert->activate ();
}
return 0;
@@ -1155,7 +1145,7 @@ Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inp
for (i = iclist.begin(); i != iclist.end(); ++i) {
- if (((*i).cnt = (*i).insert.can_support_input_configuration (required_inputs)) < 0) {
+ if (((*i).cnt = (*i).insert->can_support_input_configuration (required_inputs)) < 0) {
if (err_streams) {
*err_streams = required_inputs;
}
@@ -1163,7 +1153,7 @@ Route::check_some_plugin_counts (list<InsertCount>& iclist, int32_t required_inp
}
(*i).in = required_inputs;
- (*i).out = (*i).insert.compute_output_streams ((*i).cnt);
+ (*i).out = (*i).insert->compute_output_streams ((*i).cnt);
required_inputs = (*i).out;
}
@@ -1207,7 +1197,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
for (RedirectList::const_iterator i = other._redirects.begin(); i != other._redirects.end(); ++i) {
if ((*i)->placement() == placement) {
- _redirects.push_back (Redirect::clone (**i));
+ _redirects.push_back (Redirect::clone (*i));
}
}
@@ -1225,7 +1215,6 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
++tmp;
if ((*i)->placement() == placement) {
- delete *i;
_redirects.erase (i);
}
@@ -1244,10 +1233,7 @@ Route::copy_redirects (const Route& other, Placement placement, uint32_t* err_st
} else {
/* SUCCESSFUL COPY ATTEMPT: delete the redirects we removed pre-copy */
-
- for (RedirectList::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) {
- delete *i;
- }
+ to_be_deleted.clear ();
}
}
@@ -1290,7 +1276,7 @@ Route::all_redirects_active (bool state)
}
struct RedirectSorter {
- bool operator() (const Redirect *a, const Redirect *b) {
+ bool operator() (boost::shared_ptr<const Redirect> a, boost::shared_ptr<const Redirect> b) {
return a->sort_key() < b->sort_key();
}
};
@@ -1346,6 +1332,9 @@ Route::state(bool full_state)
snprintf (buf, sizeof (buf), "0x%x", _flags);
node->add_property("flags", buf);
}
+
+ node->add_property("default-type", _default_type.to_string());
+
node->add_property("active", _active?"yes":"no");
node->add_property("muted", _muted?"yes":"no");
node->add_property("soloed", _soloed?"yes":"no");
@@ -1362,26 +1351,6 @@ Route::state(bool full_state)
node->add_property("mix-group", _mix_group->name());
}
- /* MIDI control */
-
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte additional;
- XMLNode* midi_node = 0;
- XMLNode* child;
-
- midi_node = node->add_child ("MIDI");
-
- if (_midi_mute_control.get_control_info (chn, ev, additional)) {
- child = midi_node->add_child ("mute");
- set_midi_node_info (child, ev, chn, additional);
- }
- if (_midi_solo_control.get_control_info (chn, ev, additional)) {
- child = midi_node->add_child ("solo");
- set_midi_node_info (child, ev, chn, additional);
- }
-
-
string order_string;
OrderKeys::iterator x = order_keys.begin();
@@ -1469,13 +1438,13 @@ void
Route::add_redirect_from_xml (const XMLNode& node)
{
const XMLProperty *prop;
- Insert *insert = 0;
- Send *send = 0;
if (node.name() == "Send") {
+
try {
- send = new Send (_session, node);
+ boost::shared_ptr<Send> send (new Send (_session, node));
+ add_redirect (send, this);
}
catch (failed_constructor &err) {
@@ -1483,21 +1452,21 @@ Route::add_redirect_from_xml (const XMLNode& node)
return;
}
- add_redirect (send, this);
-
} else if (node.name() == "Insert") {
try {
if ((prop = node.property ("type")) != 0) {
+ boost::shared_ptr<Insert> insert;
+
if (prop->value() == "ladspa" || prop->value() == "Ladspa" || prop->value() == "vst") {
- insert = new PluginInsert(_session, node);
+ insert.reset (new PluginInsert(_session, node));
} else if (prop->value() == "port") {
- insert = new PortInsert (_session, node);
+ insert.reset (new PortInsert (_session, node));
} else {
@@ -1526,8 +1495,6 @@ Route::set_state (const XMLNode& node)
XMLNode *child;
XMLPropertyList plist;
const XMLProperty *prop;
- XMLNodeList midi_kids;
-
if (node.name() != "Route"){
error << string_compose(_("Bad node sent to Route::set_state() [%1]"), node.name()) << endmsg;
@@ -1541,6 +1508,11 @@ Route::set_state (const XMLNode& node)
} else {
_flags = Flag (0);
}
+
+ if ((prop = node.property ("default-type")) != 0) {
+ _default_type = DataType(prop->value());
+ assert(_default_type != DataType::NIL);
+ }
if ((prop = node.property ("phase-invert")) != 0) {
set_phase_invert(prop->value()=="yes"?true:false, this);
@@ -1716,45 +1688,6 @@ Route::set_state (const XMLNode& node)
}
}
- midi_kids = node.children ("MIDI");
-
- for (niter = midi_kids.begin(); niter != midi_kids.end(); ++niter) {
-
- XMLNodeList kids;
- XMLNodeConstIterator miter;
- XMLNode* child;
-
- kids = (*niter)->children ();
-
- for (miter = kids.begin(); miter != kids.end(); ++miter) {
-
- child =* miter;
-
- MIDI::eventType ev = MIDI::on; /* initialize to keep gcc happy */
- MIDI::byte additional = 0; /* ditto */
- MIDI::channel_t chn = 0; /* ditto */
-
- if (child->name() == "mute") {
-
- if (get_midi_node_info (child, ev, chn, additional)) {
- _midi_mute_control.set_control_type (chn, ev, additional);
- } else {
- error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
- }
- }
- else if (child->name() == "solo") {
-
- if (get_midi_node_info (child, ev, chn, additional)) {
- _midi_solo_control.set_control_type (chn, ev, additional);
- } else {
- error << string_compose(_("MIDI mute control specification for %1 is incomplete, so it has been ignored"), _name) << endmsg;
- }
- }
-
- }
- }
-
-
return 0;
}
@@ -1783,8 +1716,8 @@ Route::silence (jack_nframes_t nframes, jack_nframes_t offset)
if (lm.locked()) {
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- PluginInsert* pi;
- if (!_active && (pi = dynamic_cast<PluginInsert*> (*i)) != 0) {
+ boost::shared_ptr<PluginInsert> pi;
+ if (!_active && (pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
// skip plugins, they don't need anything when we're not active
continue;
}
@@ -1895,18 +1828,17 @@ Route::set_comment (string cmt, void *src)
}
bool
-Route::feeds (Route *o)
+Route::feeds (boost::shared_ptr<Route> other)
{
uint32_t i, j;
- IO& other = *o;
IO& self = *this;
uint32_t no = self.n_outputs();
- uint32_t ni = other.n_inputs ();
+ uint32_t ni = other->n_inputs ();
for (i = 0; i < no; ++i) {
for (j = 0; j < ni; ++j) {
- if (self.output(i)->connected_to (other.input(j)->name())) {
+ if (self.output(i)->connected_to (other->input(j)->name())) {
return true;
}
}
@@ -1920,7 +1852,7 @@ Route::feeds (Route *o)
for (i = 0; i < no; ++i) {
for (j = 0; j < ni; ++j) {
- if ((*r)->output(i)->connected_to (other.input (j)->name())) {
+ if ((*r)->output(i)->connected_to (other->input (j)->name())) {
return true;
}
}
@@ -1935,7 +1867,7 @@ Route::feeds (Route *o)
for (i = 0; i < no; ++i) {
for (j = 0; j < ni; ++j) {
- if (_control_outs->output(i)->connected_to (other.input (j)->name())) {
+ if (_control_outs->output(i)->connected_to (other->input (j)->name())) {
return true;
}
}
@@ -2186,10 +2118,10 @@ Route::toggle_monitor_input ()
bool
Route::has_external_redirects () const
{
- const PortInsert* pi;
+ boost::shared_ptr<const PortInsert> pi;
for (RedirectList::const_iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- if ((pi = dynamic_cast<const PortInsert*>(*i)) != 0) {
+ if ((pi = boost::dynamic_pointer_cast<const PortInsert>(*i)) != 0) {
uint32_t no = pi->n_outputs();
@@ -2211,67 +2143,6 @@ Route::has_external_redirects () const
}
void
-Route::reset_midi_control (MIDI::Port* port, bool on)
-{
- MIDI::channel_t chn;
- MIDI::eventType ev;
- MIDI::byte extra;
-
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- (*i)->reset_midi_control (port, on);
- }
-
- IO::reset_midi_control (port, on);
-
- _midi_solo_control.get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
- }
- _midi_solo_control.midi_rebind (port, chn);
-
- _midi_mute_control.get_control_info (chn, ev, extra);
- if (!on) {
- chn = -1;
- }
- _midi_mute_control.midi_rebind (port, chn);
-}
-
-void
-Route::send_all_midi_feedback ()
-{
- if (_session.get_midi_feedback()) {
-
- {
- Glib::RWLock::ReaderLock lm (redirect_lock);
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- (*i)->send_all_midi_feedback ();
- }
- }
-
- IO::send_all_midi_feedback();
-
- _midi_solo_control.send_feedback (_soloed);
- _midi_mute_control.send_feedback (_muted);
- }
-}
-
-MIDI::byte*
-Route::write_midi_feedback (MIDI::byte* buf, int32_t& bufsize)
-{
- buf = _midi_solo_control.write_feedback (buf, bufsize, _soloed);
- buf = _midi_mute_control.write_feedback (buf, bufsize, _muted);
-
- {
- Glib::RWLock::ReaderLock lm (redirect_lock);
- for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- buf = (*i)->write_midi_feedback (buf, bufsize);
- }
- }
-
- return IO::write_midi_feedback (buf, bufsize);
-}
-
-void
Route::flush_redirects ()
{
/* XXX shouldn't really try to take this lock, since
@@ -2341,106 +2212,46 @@ Route::automation_snapshot (jack_nframes_t now)
}
}
-Route::MIDIToggleControl::MIDIToggleControl (Route& s, ToggleType tp, MIDI::Port* port)
- : MIDI::Controllable (port, true), route (s), type(tp), setting(false)
+Route::ToggleControllable::ToggleControllable (Route& s, ToggleType tp)
+ : route (s), type(tp)
{
- last_written = false; /* XXX need a good out-of-bound-value */
+
}
void
-Route::MIDIToggleControl::set_value (float val)
+Route::ToggleControllable::set_value (float val)
{
- MIDI::eventType et;
- MIDI::channel_t chn;
- MIDI::byte additional;
-
- get_control_info (chn, et, additional);
-
- setting = true;
-
-#ifdef HOLD_TOGGLE_VALUES
- if (et == MIDI::off || et == MIDI::on) {
-
- /* literal toggle */
-
- switch (type) {
- case MuteControl:
- route.set_mute (!route.muted(), this);
- break;
- case SoloControl:
- route.set_solo (!route.soloed(), this);
- break;
- default:
- break;
- }
-
- } else {
-#endif
-
- /* map full control range to a boolean */
-
- bool bval = ((val >= 0.5f) ? true: false);
-
- switch (type) {
- case MuteControl:
- route.set_mute (bval, this);
- break;
- case SoloControl:
- route.set_solo (bval, this);
- break;
- default:
- break;
- }
-
-#ifdef HOLD_TOGGLE_VALUES
+ bool bval = ((val >= 0.5f) ? true: false);
+
+ switch (type) {
+ case MuteControl:
+ route.set_mute (bval, this);
+ break;
+ case SoloControl:
+ route.set_solo (bval, this);
+ break;
+ default:
+ break;
}
-#endif
-
- setting = false;
}
-void
-Route::MIDIToggleControl::send_feedback (bool value)
+float
+Route::ToggleControllable::get_value (void) const
{
-
- if (!setting && get_midi_feedback()) {
- MIDI::byte val = (MIDI::byte) (value ? 127: 0);
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
- MIDI::EventTwoBytes data;
-
- if (get_control_info (ch, ev, additional)) {
- data.controller_number = additional;
- data.value = val;
- last_written = value;
-
- route._session.send_midi_message (get_port(), ev, ch, data);
- }
- }
+ float val = 0.0f;
-}
-
-MIDI::byte*
-Route::MIDIToggleControl::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool val, bool force)
-{
- if (get_midi_feedback() && bufsize > 2) {
- MIDI::channel_t ch = 0;
- MIDI::eventType ev = MIDI::none;
- MIDI::byte additional = 0;
-
- if (get_control_info (ch, ev, additional)) {
- if (val != last_written || force) {
- *buf++ = (0xF0 & ev) | (0xF & ch);
- *buf++ = additional; /* controller number */
- *buf++ = (MIDI::byte) (val ? 127 : 0);
- bufsize -= 3;
- last_written = val;
- }
- }
+ switch (type) {
+ case MuteControl:
+ val = route.muted() ? 1.0f : 0.0f;
+ break;
+ case SoloControl:
+ val = route.soloed() ? 1.0f : 0.0f;
+ break;
+ default:
+ break;
}
- return buf;
+ return val;
}
void
@@ -2479,8 +2290,8 @@ Route::protect_automation ()
}
for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
- PluginInsert* pi;
- if ((pi = dynamic_cast<PluginInsert*> (*i)) != 0) {
+ boost::shared_ptr<PluginInsert> pi;
+ if ((pi = boost::dynamic_pointer_cast<PluginInsert> (*i)) != 0) {
pi->protect_automation ();
}
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 864e6178d2..806ec3b17f 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -64,6 +64,7 @@
#include <ardour/crossfade.h>
#include <ardour/playlist.h>
#include <ardour/click.h>
+#include <ardour/data_type.h>
#ifdef HAVE_LIBLO
#include <ardour/osc.h>
@@ -74,6 +75,7 @@
using namespace std;
using namespace ARDOUR;
using namespace PBD;
+using boost::shared_ptr;
const char* Session::_template_suffix = X_(".template");
const char* Session::_statefile_suffix = X_(".ardour");
@@ -90,6 +92,8 @@ Session::mix_buffers_no_gain_t Session::mix_buffers_no_gain = 0;
sigc::signal<int> Session::AskAboutPendingState;
sigc::signal<void> Session::SMPTEOffsetChanged;
+sigc::signal<void> Session::SendFeedback;
+
int
Session::find_session (string str, string& path, string& snapshot, bool& isnew)
@@ -252,6 +256,9 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port),
pending_events (2048),
midi_requests (128), // the size of this should match the midi request pool size
+ routes (new RouteList),
+ auditioner ((Auditioner*) 0),
+ _click_io ((IO*) 0),
main_outs (0)
{
bool new_session;
@@ -299,6 +306,7 @@ Session::Session (AudioEngine &eng,
_midi_port (default_midi_port),
pending_events (2048),
midi_requests (16),
+ routes (new RouteList),
main_outs (0)
{
@@ -316,15 +324,13 @@ Session::Session (AudioEngine &eng,
}
if (control_out_channels) {
- Route* r;
- r = new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut);
+ shared_ptr<Route> r (new Route (*this, _("monitor"), -1, control_out_channels, -1, control_out_channels, Route::ControlOut));
add_route (r);
_control_out = r;
}
if (master_out_channels) {
- Route* r;
- r = new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut);
+ shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
add_route (r);
_master_out = r;
} else {
@@ -376,15 +382,6 @@ Session::~Session ()
clear_clicks ();
- if (_click_io) {
- delete _click_io;
- }
-
-
- if (auditioner) {
- delete auditioner;
- }
-
for (vector<Sample*>::iterator i = _passthru_buffers.begin(); i != _passthru_buffers.end(); ++i) {
free(*i);
}
@@ -401,6 +398,8 @@ Session::~Session ()
delete [] (i->second);
}
+ AudioDiskstream::free_working_buffers();
+
#undef TRACK_DESTRUCTION
#ifdef TRACK_DESTRUCTION
cerr << "delete named selections\n";
@@ -438,27 +437,16 @@ Session::~Session ()
tmp =i;
++tmp;
- delete (*i).second;
+ delete i->second;
i = tmp;
}
#ifdef TRACK_DESTRUCTION
- cerr << "delete routes\n";
-#endif /* TRACK_DESTRUCTION */
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ) {
- RouteList::iterator tmp;
- tmp = i;
- ++tmp;
- delete *i;
- i = tmp;
- }
-
-#ifdef TRACK_DESTRUCTION
- cerr << "delete audio_diskstreams\n";
+ cerr << "delete diskstreams\n";
#endif /* TRACK_DESTRUCTION */
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ) {
- AudioDiskstreamList::iterator tmp;
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ) {
+ DiskstreamList::iterator tmp;
tmp = i;
++tmp;
@@ -477,7 +465,7 @@ Session::~Session ()
tmp = i;
++tmp;
- delete (*i).second;
+ delete i->second;
i = tmp;
}
@@ -544,7 +532,7 @@ Session::~Session ()
}
void
-Session::set_worst_io_latencies (bool take_lock)
+Session::set_worst_io_latencies ()
{
_worst_output_latency = 0;
_worst_input_latency = 0;
@@ -553,18 +541,12 @@ Session::set_worst_io_latencies (bool take_lock)
return;
}
- if (take_lock) {
- route_lock.reader_lock ();
- }
+ boost::shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
_worst_output_latency = max (_worst_output_latency, (*i)->output_latency());
_worst_input_latency = max (_worst_input_latency, (*i)->input_latency());
}
-
- if (take_lock) {
- route_lock.reader_unlock ();
- }
}
void
@@ -581,7 +563,7 @@ Session::when_engine_running ()
/* every time we reconnect, recompute worst case output latencies */
- _engine.Running.connect (sigc::bind (mem_fun (*this, &Session::set_worst_io_latencies), true));
+ _engine.Running.connect (mem_fun (*this, &Session::set_worst_io_latencies));
if (synced_to_jack()) {
_engine.transport_stop ();
@@ -596,7 +578,7 @@ Session::when_engine_running ()
try {
XMLNode* child = 0;
- _click_io = new ClickIO (*this, "click", 0, 0, -1, -1);
+ _click_io.reset (new ClickIO (*this, "click", 0, 0, -1, -1));
if (state_tree && (child = find_named_node (*state_tree->root(), "Click")) != 0) {
@@ -632,7 +614,7 @@ Session::when_engine_running ()
error << _("cannot setup Click I/O") << endmsg;
}
- set_worst_io_latencies (true);
+ set_worst_io_latencies ();
if (_clicking) {
ControlChanged (Clicking); /* EMIT SIGNAL */
@@ -647,7 +629,7 @@ Session::when_engine_running ()
*/
try {
- auditioner = new Auditioner (*this);
+ auditioner.reset (new Auditioner (*this));
}
catch (failed_constructor& err) {
@@ -881,7 +863,7 @@ Session::playlist_length_changed (Playlist* pl)
}
void
-Session::diskstream_playlist_changed (AudioDiskstream* dstream)
+Session::diskstream_playlist_changed (Diskstream* dstream)
{
Playlist *playlist;
@@ -961,7 +943,7 @@ Session::set_auto_input (bool yn)
The rarity and short potential lock duration makes this "OK"
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input);
@@ -979,7 +961,7 @@ Session::reset_input_monitor_state ()
{
if (transport_rolling()) {
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring() && !auto_input);
@@ -987,7 +969,7 @@ Session::reset_input_monitor_state ()
}
} else {
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input = " << !auto_input << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (Config->get_use_hardware_monitoring());
@@ -1068,7 +1050,7 @@ Session::auto_loop_changed (Location* location)
}
else if (seamless_loop && !loop_changing) {
- // schedule a locate-roll to refill the audio_diskstreams at the
+ // schedule a locate-roll to refill the diskstreams at the
// previous loop end
loop_changing = true;
@@ -1265,7 +1247,7 @@ Session::enable_record ()
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
(*i)->monitor_input (true);
}
@@ -1300,7 +1282,7 @@ Session::disable_record (bool rt_context, bool force)
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
(*i)->monitor_input (false);
}
@@ -1327,7 +1309,7 @@ Session::step_back_from_record ()
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false);
@@ -1450,7 +1432,6 @@ Session::set_block_size (jack_nframes_t nframes)
*/
{
- Glib::RWLock::ReaderLock lm (route_lock);
Glib::RWLock::ReaderLock dsm (diskstream_lock);
vector<Sample*>::iterator i;
uint32_t np;
@@ -1492,15 +1473,17 @@ Session::set_block_size (jack_nframes_t nframes)
allocate_pan_automation_buffers (nframes, _npan_buffers, true);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_block_size (nframes);
}
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->set_block_size (nframes);
}
- set_worst_io_latencies (false);
+ set_worst_io_latencies ();
}
}
@@ -1542,7 +1525,7 @@ Session::set_default_fade (float steepness, float fade_msecs)
}
struct RouteSorter {
- bool operator() (Route* r1, Route* r2) {
+ bool operator() (boost::shared_ptr<Route> r1, boost::shared_ptr<Route> r2) {
if (r1->fed_by.find (r2) != r1->fed_by.end()) {
return false;
} else if (r2->fed_by.find (r1) != r2->fed_by.end()) {
@@ -1564,9 +1547,9 @@ struct RouteSorter {
};
static void
-trace_terminal (Route* r1, Route* rbase)
+trace_terminal (shared_ptr<Route> r1, shared_ptr<Route> rbase)
{
- Route* r2;
+ shared_ptr<Route> r2;
if ((r1->fed_by.find (rbase) != r1->fed_by.end()) && (rbase->fed_by.find (r1) != rbase->fed_by.end())) {
info << string_compose(_("feedback loop setup between %1 and %2"), r1->name(), rbase->name()) << endmsg;
@@ -1575,13 +1558,13 @@ trace_terminal (Route* r1, Route* rbase)
/* make a copy of the existing list of routes that feed r1 */
- set<Route *> existing = r1->fed_by;
+ set<shared_ptr<Route> > existing = r1->fed_by;
/* for each route that feeds r1, recurse, marking it as feeding
rbase as well.
*/
- for (set<Route *>::iterator i = existing.begin(); i != existing.end(); ++i) {
+ for (set<shared_ptr<Route> >::iterator i = existing.begin(); i != existing.end(); ++i) {
r2 =* i;
/* r2 is a route that feeds r1 which somehow feeds base. mark
@@ -1611,7 +1594,7 @@ trace_terminal (Route* r1, Route* rbase)
}
void
-Session::resort_routes (void* src)
+Session::resort_routes ()
{
/* don't do anything here with signals emitted
by Routes while we are being destroyed.
@@ -1621,54 +1604,64 @@ Session::resort_routes (void* src)
return;
}
- /* Caller MUST hold the route_lock */
- RouteList::iterator i, j;
+ {
- for (i = routes.begin(); i != routes.end(); ++i) {
+ RCUWriter<RouteList> writer (routes);
+ shared_ptr<RouteList> r = writer.get_copy ();
+ resort_routes_using (r);
+ /* writer goes out of scope and forces update */
+ }
+}
+void
+Session::resort_routes_using (shared_ptr<RouteList> r)
+{
+ RouteList::iterator i, j;
+
+ for (i = r->begin(); i != r->end(); ++i) {
+
(*i)->fed_by.clear ();
- for (j = routes.begin(); j != routes.end(); ++j) {
-
+ for (j = r->begin(); j != r->end(); ++j) {
+
/* although routes can feed themselves, it will
cause an endless recursive descent if we
detect it. so don't bother checking for
self-feeding.
*/
-
+
if (*j == *i) {
continue;
}
-
+
if ((*j)->feeds (*i)) {
(*i)->fed_by.insert (*j);
}
}
}
- for (i = routes.begin(); i != routes.end(); ++i) {
+ for (i = r->begin(); i != r->end(); ++i) {
trace_terminal (*i, *i);
}
-
+
RouteSorter cmp;
- routes.sort (cmp);
-
+ r->sort (cmp);
+
#if 0
cerr << "finished route resort\n";
- for (i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
cerr << " " << (*i)->name() << " signal order = " << (*i)->order_key ("signal") << endl;
}
cerr << endl;
#endif
-
+
}
-AudioTrack*
+shared_ptr<AudioTrack>
Session::new_audio_track (int input_channels, int output_channels, TrackMode mode)
{
- AudioTrack *track;
char track_name[32];
uint32_t n = 0;
uint32_t channels_used = 0;
@@ -1679,9 +1672,10 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
/* count existing audio tracks */
{
- Glib::RWLock::ReaderLock lm (route_lock);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- if (dynamic_cast<AudioTrack*>(*i) != 0) {
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
if (!(*i)->hidden()) {
n++;
channels_used += (*i)->n_inputs();
@@ -1718,7 +1712,7 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
}
try {
- track = new AudioTrack (*this, track_name, Route::Flag (0), mode);
+ shared_ptr<AudioTrack> track (new AudioTrack (*this, track_name, Route::Flag (0), mode));
if (track->ensure_io (input_channels, output_channels, false, this)) {
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
@@ -1769,25 +1763,23 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
track->set_control_outs (cports);
}
- track->diskstream_changed.connect (mem_fun (this, &Session::resort_routes));
+ track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
add_route (track);
track->set_remote_control_id (ntracks());
+ return track;
}
catch (failed_constructor &err) {
error << _("Session: could not create new audio track.") << endmsg;
- return 0;
+ return shared_ptr<AudioTrack> ((AudioTrack*) 0);
}
-
- return track;
}
-Route*
+shared_ptr<Route>
Session::new_audio_route (int input_channels, int output_channels)
{
- Route *bus;
char bus_name[32];
uint32_t n = 0;
string port;
@@ -1795,9 +1787,10 @@ Session::new_audio_route (int input_channels, int output_channels)
/* count existing audio busses */
{
- Glib::RWLock::ReaderLock lm (route_lock);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- if (dynamic_cast<AudioTrack*>(*i) == 0) {
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
if (!(*i)->hidden()) {
n++;
}
@@ -1815,7 +1808,7 @@ Session::new_audio_route (int input_channels, int output_channels)
} while (n < (UINT_MAX-1));
try {
- bus = new Route (*this, bus_name, -1, -1, -1, -1);
+ shared_ptr<Route> bus (new Route (*this, bus_name, -1, -1, -1, -1, Route::Flag(0), DataType::AUDIO));
if (bus->ensure_io (input_channels, output_channels, false, this)) {
error << string_compose (_("cannot configure %1 in/%2 out configuration for new audio track"),
@@ -1864,23 +1857,23 @@ Session::new_audio_route (int input_channels, int output_channels)
}
add_route (bus);
+ return bus;
}
catch (failed_constructor &err) {
- error << _("Session: could not create new route.") << endmsg;
- return 0;
+ error << _("Session: could not create new audio route.") << endmsg;
+ return shared_ptr<Route> ((Route*) 0);
}
-
- return bus;
}
void
-Session::add_route (Route* route)
+Session::add_route (shared_ptr<Route> route)
{
{
- Glib::RWLock::WriterLock lm (route_lock);
- routes.push_front (route);
- resort_routes(0);
+ RCUWriter<RouteList> writer (routes);
+ shared_ptr<RouteList> r = writer.get_copy ();
+ r->push_front (route);
+ resort_routes_using (r);
}
route->solo_changed.connect (sigc::bind (mem_fun (*this, &Session::route_solo_changed), route));
@@ -1903,14 +1896,14 @@ Session::add_route (Route* route)
}
void
-Session::add_diskstream (AudioDiskstream* dstream)
+Session::add_diskstream (Diskstream* dstream)
{
/* need to do this in case we're rolling at the time, to prevent false underruns */
- dstream->do_refill(0, 0, 0);
+ dstream->do_refill_with_alloc();
{
Glib::RWLock::WriterLock lm (diskstream_lock);
- audio_diskstreams.push_back (dstream);
+ diskstreams.push_back (dstream);
}
/* take a reference to the diskstream, preventing it from
@@ -1930,52 +1923,56 @@ Session::add_diskstream (AudioDiskstream* dstream)
set_dirty();
save_state (_current_snapshot_name);
- AudioDiskstreamAdded (dstream); /* EMIT SIGNAL */
+ DiskstreamAdded (dstream); /* EMIT SIGNAL */
}
void
-Session::remove_route (Route& route)
+Session::remove_route (shared_ptr<Route> route)
{
{
- Glib::RWLock::WriterLock lm (route_lock);
- routes.remove (&route);
+ RCUWriter<RouteList> writer (routes);
+ shared_ptr<RouteList> rs = writer.get_copy ();
+ rs->remove (route);
/* deleting the master out seems like a dumb
idea, but its more of a UI policy issue
than our concern.
*/
- if (&route == _master_out) {
- _master_out = 0;
+ if (route == _master_out) {
+ _master_out = shared_ptr<Route> ((Route*) 0);
}
- if (&route == _control_out) {
- _control_out = 0;
+ if (route == _control_out) {
+ _control_out = shared_ptr<Route> ((Route*) 0);
/* cancel control outs for all routes */
vector<string> empty;
- for (RouteList::iterator r = routes.begin(); r != routes.end(); ++r) {
+ for (RouteList::iterator r = rs->begin(); r != rs->end(); ++r) {
(*r)->set_control_outs (empty);
}
}
update_route_solo_state ();
+
+ /* writer goes out of scope, forces route list update */
}
+ // FIXME: audio specific
AudioTrack* at;
AudioDiskstream* ds = 0;
- if ((at = dynamic_cast<AudioTrack*>(&route)) != 0) {
- ds = &at->disk_stream();
+ if ((at = dynamic_cast<AudioTrack*>(route.get())) != 0) {
+ ds = &at->audio_diskstream();
}
if (ds) {
{
Glib::RWLock::WriterLock lm (diskstream_lock);
- audio_diskstreams.remove (ds);
+ diskstreams.remove (ds);
}
ds->unref ();
@@ -1990,7 +1987,7 @@ Session::remove_route (Route& route)
save_state (_current_snapshot_name);
- delete &route;
+ /* all shared ptrs to route should go out of scope here */
}
void
@@ -2000,19 +1997,20 @@ Session::route_mute_changed (void* src)
}
void
-Session::route_solo_changed (void* src, Route* route)
+Session::route_solo_changed (void* src, shared_ptr<Route> route)
{
if (solo_update_disabled) {
// We know already
return;
}
- Glib::RWLock::ReaderLock lm (route_lock);
bool is_track;
- is_track = (dynamic_cast<AudioTrack*>(route) != 0);
+ is_track = (dynamic_cast<AudioTrack*>(route.get()) != 0);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
/* soloing a track mutes all other tracks, soloing a bus mutes all other busses */
@@ -2020,7 +2018,7 @@ Session::route_solo_changed (void* src, Route* route)
/* don't mess with busses */
- if (dynamic_cast<AudioTrack*>(*i) == 0) {
+ if (dynamic_cast<AudioTrack*>((*i).get()) == 0) {
continue;
}
@@ -2028,7 +2026,7 @@ Session::route_solo_changed (void* src, Route* route)
/* don't mess with tracks */
- if (dynamic_cast<AudioTrack*>(*i) != 0) {
+ if (dynamic_cast<AudioTrack*>((*i).get()) != 0) {
continue;
}
}
@@ -2061,10 +2059,10 @@ Session::route_solo_changed (void* src, Route* route)
bool same_thing_soloed = false;
bool signal = false;
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
something_soloed = true;
- if (dynamic_cast<AudioTrack*>(*i)) {
+ if (dynamic_cast<AudioTrack*>((*i).get())) {
if (is_track) {
same_thing_soloed = true;
break;
@@ -2115,11 +2113,13 @@ Session::update_route_solo_state ()
/* this is where we actually implement solo by changing
the solo mute setting of each track.
*/
-
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->soloed()) {
mute = true;
- if (dynamic_cast<AudioTrack*>(*i)) {
+ if (dynamic_cast<AudioTrack*>((*i).get())) {
is_track = true;
}
break;
@@ -2135,7 +2135,7 @@ Session::update_route_solo_state ()
/* nothing is soloed */
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_solo_mute (false);
}
@@ -2156,13 +2156,15 @@ Session::update_route_solo_state ()
void
Session::modify_solo_mute (bool is_track, bool mute)
{
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (is_track) {
/* only alter track solo mute */
- if (dynamic_cast<AudioTrack*>(*i)) {
+ if (dynamic_cast<AudioTrack*>((*i).get())) {
if ((*i)->soloed()) {
(*i)->set_solo_mute (!mute);
} else {
@@ -2174,7 +2176,7 @@ Session::modify_solo_mute (bool is_track, bool mute)
/* only alter bus solo mute */
- if (!dynamic_cast<AudioTrack*>(*i)) {
+ if (!dynamic_cast<AudioTrack*>((*i).get())) {
if ((*i)->soloed()) {
@@ -2206,36 +2208,35 @@ Session::catch_up_on_solo ()
basis, but needs the global overview that only the session
has.
*/
- Glib::RWLock::ReaderLock lm (route_lock);
update_route_solo_state();
}
-Route *
+shared_ptr<Route>
Session::route_by_name (string name)
{
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->name() == name) {
- return* i;
+ return *i;
}
}
- return 0;
+ return shared_ptr<Route> ((Route*) 0);
}
-Route *
+shared_ptr<Route>
Session::route_by_remote_id (uint32_t id)
{
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->remote_control_id() == id) {
- return* i;
+ return *i;
}
}
- return 0;
+ return shared_ptr<Route> ((Route*) 0);
}
void
@@ -2264,7 +2265,7 @@ Session::get_maximum_extent () const
ensure atomicity.
*/
- for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
Playlist* pl = (*i)->playlist();
if ((me = pl->get_maximum_extent()) > max) {
max = me;
@@ -2274,12 +2275,12 @@ Session::get_maximum_extent () const
return max;
}
-AudioDiskstream *
+Diskstream *
Session::diskstream_by_name (string name)
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->name() == name) {
return* i;
}
@@ -2288,12 +2289,12 @@ Session::diskstream_by_name (string name)
return 0;
}
-AudioDiskstream *
-Session::diskstream_by_id (id_t id)
+Diskstream *
+Session::diskstream_by_id (const PBD::ID& id)
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->id() == id) {
return *i;
}
@@ -2337,7 +2338,7 @@ Session::new_region_name (string old)
sbuf = buf;
for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- if ((*i).second->name() == sbuf) {
+ if (i->second->name() == sbuf) {
break;
}
}
@@ -2402,7 +2403,7 @@ Session::region_name (string& result, string base, bool newlevel) const
name_taken = false;
for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- if ((*i).second->name() == result) {
+ if (i->second->name() == result) {
name_taken = true;
break;
}
@@ -2447,8 +2448,8 @@ Session::add_region (Region* region)
if (x == audio_regions.end()) {
- pair<AudioRegionList::key_type, AudioRegionList::mapped_type> entry;
-
+ pair<AudioRegionList::key_type,AudioRegionList::mapped_type> entry;
+
entry.first = region->id();
entry.second = ar;
@@ -2505,16 +2506,18 @@ Session::remove_region (Region* region)
AudioRegionList::iterator i;
AudioRegion* ar = 0;
bool removed = false;
-
+
{
Glib::Mutex::Lock lm (region_lock);
- if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
+ if ((ar = dynamic_cast<AudioRegion*> (region)) != 0) {
if ((i = audio_regions.find (region->id())) != audio_regions.end()) {
audio_regions.erase (i);
removed = true;
- }
+ }
+
} else {
+
fatal << _("programming error: ")
<< X_("unknown region type passed to Session::remove_region()")
<< endmsg;
@@ -2542,7 +2545,7 @@ Session::find_whole_file_parent (AudioRegion& child)
for (i = audio_regions.begin(); i != audio_regions.end(); ++i) {
- region = (*i).second;
+ region = i->second;
if (region->whole_file()) {
@@ -2556,18 +2559,10 @@ Session::find_whole_file_parent (AudioRegion& child)
}
void
-Session::find_equivalent_playlist_regions (AudioRegion& region, vector<AudioRegion*>& result)
+Session::find_equivalent_playlist_regions (Region& region, vector<Region*>& result)
{
- for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-
- AudioPlaylist* pl;
-
- if ((pl = dynamic_cast<AudioPlaylist*>(*i)) == 0) {
- continue;
- }
-
- pl->get_region_list_equivalent_regions (region, result);
- }
+ for (PlaylistList::iterator i = playlists.begin(); i != playlists.end(); ++i)
+ (*i)->get_region_list_equivalent_regions (region, result);
}
int
@@ -2619,7 +2614,7 @@ Session::remove_last_capture ()
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
list<Region*>& l = (*i)->last_capture_regions();
if (!l.empty()) {
@@ -2646,12 +2641,12 @@ Session::add_audio_source (AudioSource* source)
{
pair<AudioSourceList::key_type, AudioSourceList::mapped_type> entry;
- {
- Glib::Mutex::Lock lm (audio_source_lock);
+ {
+ Glib::Mutex::Lock lm (audio_source_lock);
entry.first = source->id();
entry.second = source;
audio_sources.insert (entry);
- }
+ }
source->GoingAway.connect (mem_fun (this, &Session::remove_source));
set_dirty();
@@ -2669,7 +2664,7 @@ Session::remove_source (Source* source)
if ((i = audio_sources.find (source->id())) != audio_sources.end()) {
audio_sources.erase (i);
- }
+ }
}
if (!_state_of_the_state & InCleanup) {
@@ -2685,23 +2680,19 @@ Session::remove_source (Source* source)
}
Source *
-Session::get_source (ARDOUR::id_t id)
+Session::source_by_id (const PBD::ID& id)
{
Glib::Mutex::Lock lm (audio_source_lock);
AudioSourceList::iterator i;
Source* source = 0;
if ((i = audio_sources.find (id)) != audio_sources.end()) {
- source = (*i).second;
- }
-
- if (source) {
- return source;
+ source = i->second;
}
/* XXX search MIDI or other searches here */
- return 0;
+ return source;
}
string
@@ -2776,12 +2767,13 @@ Session::change_audio_path_by_name (string path, string oldname, string newname,
the task here is to replace NAME with the new name.
*/
- /* find last slash */
-
string dir;
string suffix;
string::size_type slash;
string::size_type dash;
+ string::size_type postfix;
+
+ /* find last slash */
if ((slash = path.find_last_of ('/')) == string::npos) {
return "";
@@ -2795,11 +2787,41 @@ Session::change_audio_path_by_name (string path, string oldname, string newname,
return "";
}
- suffix = path.substr (dash);
+ suffix = path.substr (dash+1);
+
+ // Suffix is now everything after the dash. Now we need to eliminate
+ // the nnnnn part, which is done by either finding a '%' or a '.'
+
+ postfix = suffix.find_last_of ("%");
+ if (postfix == string::npos) {
+ postfix = suffix.find_last_of ('.');
+ }
+
+ if (postfix != string::npos) {
+ suffix = suffix.substr (postfix);
+ } else {
+ error << "Logic error in Session::change_audio_path_by_name(), please report to the developers" << endl;
+ return "";
+ }
+
+ const uint32_t limit = 10000;
+ char buf[PATH_MAX+1];
+
+ for (uint32_t cnt = 1; cnt <= limit; ++cnt) {
+
+ snprintf (buf, sizeof(buf), "%s%s-%u%s", dir.c_str(), newname.c_str(), cnt, suffix.c_str());
+
+ if (access (buf, F_OK) != 0) {
+ path = buf;
+ break;
+ }
+ path = "";
+ }
+
+ if (path == "") {
+ error << "FATAL ERROR! Could not find a " << endl;
+ }
- path = dir;
- path += new_legalized;
- path += suffix;
}
return path;
@@ -2822,20 +2844,20 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
*/
for (cnt = (destructive ? ++destructive_index : 1); cnt <= limit; ++cnt) {
-
+
vector<space_and_path>::iterator i;
uint32_t existing = 0;
-
+
for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
-
+
spath = (*i).path;
-
+
if (destructive) {
spath += tape_dir_name;
} else {
spath += sound_dir_name;
}
-
+
if (destructive) {
if (nchan < 2) {
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
@@ -2851,10 +2873,10 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
snprintf (buf, sizeof(buf), "%s/T%04d-%s.wav", spath.c_str(), cnt, legalized.c_str());
}
} else {
-
+
spath += '/';
spath += legalized;
-
+
if (nchan < 2) {
snprintf (buf, sizeof(buf), "%s-%u.wav", spath.c_str(), cnt);
} else if (nchan == 2) {
@@ -2874,7 +2896,7 @@ Session::audio_path_from_name (string name, uint32_t nchan, uint32_t chan, bool
existing++;
}
}
-
+
if (existing == 0) {
break;
}
@@ -2931,18 +2953,6 @@ Session::create_audio_source_for_session (AudioDiskstream& ds, uint32_t chan, bo
/* Playlist management */
Playlist *
-Session::get_playlist (string name)
-{
- Playlist* ret = 0;
-
- if ((ret = playlist_by_name (name)) == 0) {
- ret = new AudioPlaylist (*this, name);
- }
-
- return ret;
-}
-
-Playlist *
Session::playlist_by_name (string name)
{
Glib::Mutex::Lock lm (playlist_lock);
@@ -3071,11 +3081,14 @@ Session::audition_playlist ()
}
void
-Session::audition_region (AudioRegion& r)
+Session::audition_region (Region& r)
{
- Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
- ev->set_ptr (&r);
- queue_event (ev);
+ AudioRegion* ar = dynamic_cast<AudioRegion*>(&r);
+ if (ar) {
+ Event* ev = new Event (Event::Audition, Event::Add, Event::Immediate, 0, 0.0);
+ ev->set_ptr (ar);
+ queue_event (ev);
+ }
}
void
@@ -3088,7 +3101,7 @@ Session::cancel_audition ()
}
bool
-Session::RoutePublicOrderSorter::operator() (Route* a, Route* b)
+Session::RoutePublicOrderSorter::operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b)
{
return a->order_key(N_("signal")) < b->order_key(N_("signal"));
}
@@ -3134,13 +3147,11 @@ Session::is_auditioning () const
void
Session::set_all_solo (bool yn)
{
- {
- Glib::RWLock::ReaderLock lm (route_lock);
-
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->set_solo (yn, this);
- }
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (!(*i)->hidden()) {
+ (*i)->set_solo (yn, this);
}
}
@@ -3150,13 +3161,11 @@ Session::set_all_solo (bool yn)
void
Session::set_all_mute (bool yn)
{
- {
- Glib::RWLock::ReaderLock lm (route_lock);
-
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->set_mute (yn, this);
- }
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (!(*i)->hidden()) {
+ (*i)->set_mute (yn, this);
}
}
@@ -3164,12 +3173,12 @@ Session::set_all_mute (bool yn)
}
uint32_t
-Session::n_audio_diskstreams () const
+Session::n_diskstreams () const
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
uint32_t n = 0;
- for (AudioDiskstreamList::const_iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
n++;
}
@@ -3177,17 +3186,6 @@ Session::n_audio_diskstreams () const
return n;
}
-void
-Session::foreach_audio_diskstream (void (AudioDiskstream::*func)(void))
-{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
- if (!(*i)->hidden()) {
- ((*i)->*func)();
- }
- }
-}
-
void
Session::graph_reordered ()
{
@@ -3199,16 +3197,15 @@ Session::graph_reordered ()
return;
}
- Glib::RWLock::WriterLock lm1 (route_lock);
Glib::RWLock::ReaderLock lm2 (diskstream_lock);
- resort_routes (0);
+ resort_routes ();
/* force all diskstreams to update their capture offset values to
reflect any changes in latencies within the graph.
*/
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->set_capture_offset ();
}
}
@@ -3228,12 +3225,12 @@ Session::record_enable_all ()
void
Session::record_enable_change_all (bool yn)
{
- Glib::RWLock::ReaderLock lm1 (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
AudioTrack* at;
- if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
+ if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
at->set_record_enable (yn, this);
}
}
@@ -3491,7 +3488,7 @@ Session::reset_native_file_format ()
//RWLockMonitor lm1 (route_lock, true, __LINE__, __FILE__);
Glib::RWLock::ReaderLock lm2 (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->reset_write_sources (false);
}
}
@@ -3499,9 +3496,9 @@ Session::reset_native_file_format ()
bool
Session::route_name_unique (string n) const
{
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->name() == n) {
return false;
}
@@ -3558,23 +3555,16 @@ Session::allocate_pan_automation_buffers (jack_nframes_t nframes, uint32_t howma
_npan_buffers = howmany;
}
-void
-Session::add_instant_xml (XMLNode& node, const std::string& dir)
-{
- Stateful::add_instant_xml (node, dir);
- Config->add_instant_xml (node, get_user_ardour_path());
-}
-
int
Session::freeze (InterThreadInfo& itt)
{
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
AudioTrack *at;
- if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
+ if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
/* XXX this is wrong because itt.progress will keep returning to zero at the start
of every track.
*/
@@ -3609,7 +3599,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
/* call tree *MUST* hold route_lock */
- if ((playlist = track.disk_stream().playlist()) == 0) {
+ if ((playlist = track.diskstream().playlist()) == 0) {
goto out;
}
@@ -3619,7 +3609,7 @@ Session::write_one_audio_track (AudioTrack& track, jack_nframes_t start, jack_nf
goto out;
}
- nchans = track.disk_stream().n_channels();
+ nchans = track.audio_diskstream().n_channels();
dir = discover_best_sound_dir ();
@@ -3763,10 +3753,10 @@ uint32_t
Session::ntracks () const
{
uint32_t n = 0;
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
- if (dynamic_cast<AudioTrack*> (*i)) {
+ for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
+ if (dynamic_cast<AudioTrack*> ((*i).get())) {
++n;
}
}
@@ -3778,10 +3768,10 @@ uint32_t
Session::nbusses () const
{
uint32_t n = 0;
- Glib::RWLock::ReaderLock lm (route_lock);
+ shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::const_iterator i = routes.begin(); i != routes.end(); ++i) {
- if (dynamic_cast<AudioTrack*> (*i) == 0) {
+ for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
+ if (dynamic_cast<AudioTrack*> ((*i).get()) == 0) {
++n;
}
}
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 4613bfccf9..6509a783bb 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -168,15 +168,9 @@ Session::butler_thread_work ()
struct timeval begin, end;
struct pollfd pfd[1];
bool disk_work_outstanding = false;
- AudioDiskstreamList::iterator i;
-
- butler_mixdown_buffer = new Sample[AudioDiskstream::disk_io_frames()];
- butler_gain_buffer = new gain_t[AudioDiskstream::disk_io_frames()];
- // this buffer is used for temp conversion purposes in filesources
- char * conv_buffer = conversion_buffer(ButlerContext);
+ DiskstreamList::iterator i;
while (true) {
-
pfd[0].fd = butler_request_pipe[0];
pfd[0].events = POLLIN|POLLERR|POLLHUP;
@@ -198,14 +192,13 @@ Session::butler_thread_work ()
}
if (pfd[0].revents & POLLIN) {
-
+
char req;
/* empty the pipe of all current requests */
while (1) {
size_t nread = ::read (butler_request_pipe[0], &req, sizeof (req));
-
if (nread == 1) {
switch ((ButlerRequest::Type) req) {
@@ -240,10 +233,10 @@ Session::butler_thread_work ()
}
}
}
-
- for (i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+
+ //for (i = diskstreams.begin(); i != diskstreams.end(); ++i) {
// cerr << "BEFORE " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
- }
+ //}
if (transport_work_requested()) {
butler_transport_work ();
@@ -257,16 +250,16 @@ Session::butler_thread_work ()
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
-
- // cerr << "rah fondr " << (*i)->io()->name () << endl;
+ for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
+
+ Diskstream* const ds = *i;
- switch ((*i)->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) {
+ switch (ds->do_refill ()) {
case 0:
- bytes += (*i)->read_data_count();
+ bytes += ds->read_data_count();
break;
case 1:
- bytes += (*i)->read_data_count();
+ bytes += ds->read_data_count();
disk_work_outstanding = true;
break;
@@ -278,7 +271,7 @@ Session::butler_thread_work ()
}
- if (i != audio_diskstreams.end()) {
+ if (i != diskstreams.end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
@@ -299,12 +292,11 @@ Session::butler_thread_work ()
bytes = 0;
compute_io = true;
gettimeofday (&begin, 0);
-
- for (i = audio_diskstreams.begin(); !transport_work_requested() && butler_should_run && i != audio_diskstreams.end(); ++i) {
-
+
+ for (i = diskstreams.begin(); !transport_work_requested() && butler_should_run && i != diskstreams.end(); ++i) {
// cerr << "write behind for " << (*i)->name () << endl;
- switch ((*i)->do_flush (conv_buffer)) {
+ switch ((*i)->do_flush (Session::ButlerContext)) {
case 0:
bytes += (*i)->write_data_count();
break;
@@ -330,7 +322,7 @@ Session::butler_thread_work ()
request_stop ();
}
- if (i != audio_diskstreams.end()) {
+ if (i != diskstreams.end()) {
/* we didn't get to all the streams */
disk_work_outstanding = true;
}
@@ -357,7 +349,7 @@ Session::butler_thread_work ()
Glib::Mutex::Lock lm (butler_request_lock);
if (butler_should_run && (disk_work_outstanding || transport_work_requested())) {
-// for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+// for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
// cerr << "AFTER " << (*i)->name() << ": pb = " << (*i)->playback_buffer_load() << " cp = " << (*i)->capture_buffer_load() << endl;
// }
@@ -375,18 +367,17 @@ Session::butler_thread_work ()
void
-Session::request_overwrite_buffer (AudioDiskstream* stream)
+Session::request_overwrite_buffer (Diskstream* stream)
{
Event *ev = new Event (Event::Overwrite, Event::Add, Event::Immediate, 0, 0, 0.0);
ev->set_ptr (stream);
queue_event (ev);
}
+/** Process thread. */
void
-Session::overwrite_some_buffers (AudioDiskstream* ds)
+Session::overwrite_some_buffers (Diskstream* ds)
{
- /* executed by the audio thread */
-
if (actively_recording()) {
return;
}
@@ -398,7 +389,7 @@ Session::overwrite_some_buffers (AudioDiskstream* ds)
} else {
Glib::RWLock::ReaderLock dm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->set_pending_overwrite (true);
}
}
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index ddced9cc5f..b39c4f2218 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -485,8 +485,9 @@ Session::prepare_to_export (AudioExportSpecification& spec)
/* take everyone out of awrite to avoid disasters */
{
- Glib::RWLock::ReaderLock lm (route_lock);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->protect_automation ();
}
}
@@ -495,7 +496,7 @@ Session::prepare_to_export (AudioExportSpecification& spec)
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)-> seek (spec.start_frame, true)) {
error << string_compose (_("%1: cannot seek to %2 for export"),
(*i)->name(), spec.start_frame)
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index 60bd95464f..821f894eeb 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -109,13 +109,6 @@ Session::set_midi_control (bool yn)
set_dirty();
poke_midi_thread ();
- if (_midi_port) {
- Glib::RWLock::ReaderLock guard (route_lock);
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- (*i)->reset_midi_control (_midi_port, midi_control);
- }
- }
-
ControlChanged (MidiControl); /* EMIT SIGNAL */
}
@@ -783,12 +776,12 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
if (mmc_control) {
RouteList::iterator i;
- Glib::RWLock::ReaderLock guard (route_lock);
+ boost::shared_ptr<RouteList> r = routes.reader();
- for (i = routes.begin(); i != routes.end(); ++i) {
+ for (i = r->begin(); i != r->end(); ++i) {
AudioTrack *at;
- if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
+ if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
if (trk == at->remote_control_id()) {
at->set_record_enable (enabled, &mmc);
break;
diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc
index ad4e9a64bb..88b111a1fb 100644
--- a/libs/ardour/session_process.cc
+++ b/libs/ardour/session_process.cc
@@ -59,12 +59,14 @@ Session::process (jack_nframes_t nframes)
}
(this->*process_function) (nframes);
+
+ SendFeedback (); /* EMIT SIGNAL */
}
void
Session::prepare_diskstreams ()
{
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->prepare ();
}
}
@@ -75,23 +77,20 @@ Session::no_roll (jack_nframes_t nframes, jack_nframes_t offset)
jack_nframes_t end_frame = _transport_frame + nframes;
int ret = 0;
bool declick = get_transport_declick_required();
+ boost::shared_ptr<RouteList> r = routes.reader ();
if (_click_io) {
_click_io->silence (nframes, offset);
}
- /* XXX we're supposed to have the route_lock while doing this.
- this is really bad ...
- */
-
if (g_atomic_int_get (&processing_prohibited)) {
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->silence (nframes, offset);
}
return 0;
}
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if ((*i)->hidden()) {
continue;
@@ -116,6 +115,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
bool record_active;
int declick = get_transport_declick_required();
bool rec_monitors = get_rec_monitors_input();
+ boost::shared_ptr<RouteList> r = routes.reader ();
if (transport_sub_state & StopPendingCapture) {
/* force a declick out */
@@ -124,7 +124,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
record_active = actively_recording(); // || (get_record_enabled() && get_punch_in());
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
int ret;
@@ -141,7 +141,7 @@ Session::process_routes (jack_nframes_t nframes, jack_nframes_t offset)
call path, so make sure we release any outstanding locks here before we return failure.
*/
- for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
+ for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
(*ids)->recover ();
}
@@ -159,13 +159,14 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
bool record_active = actively_recording();
int declick = get_transport_declick_required();
bool rec_monitors = get_rec_monitors_input();
+ boost::shared_ptr<RouteList> r = routes.reader ();
if (transport_sub_state & StopPendingCapture) {
/* force a declick out */
declick = -1;
}
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
int ret;
@@ -180,7 +181,7 @@ Session::silent_process_routes (jack_nframes_t nframes, jack_nframes_t offset)
call path, so make sure we release any outstanding locks here before we return failure.
*/
- for (AudioDiskstreamList::iterator ids = audio_diskstreams.begin(); ids != audio_diskstreams.end(); ++ids) {
+ for (DiskstreamList::iterator ids = diskstreams.begin(); ids != diskstreams.end(); ++ids) {
(*ids)->recover ();
}
@@ -199,7 +200,7 @@ Session::commit_diskstreams (jack_nframes_t nframes, bool &needs_butler)
float pworst = 1.0f;
float cworst = 1.0f;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->hidden()) {
continue;
@@ -247,10 +248,14 @@ Session::process_with_events (jack_nframes_t nframes)
jack_nframes_t stop_limit;
long frames_moved;
+ /* make sure the auditioner is silent */
+
if (auditioner) {
auditioner->silence (nframes, 0);
}
+ /* handle any pending events */
+
while (pending_events.read (&ev, 1) == 1) {
merge_event (ev);
}
@@ -279,13 +284,12 @@ Session::process_with_events (jack_nframes_t nframes)
end_frame = _transport_frame + nframes;
{
- Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK);
Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
Event* this_event;
Events::iterator the_next_one;
-
- if (!rm.locked() || !dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
+
+ if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
no_roll (nframes, 0);
return;
}
@@ -566,7 +570,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
bool ok = true;
jack_nframes_t frame_delta = slave_transport_frame - _transport_frame;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->can_internal_playback_seek (frame_delta)) {
ok = false;
break;
@@ -574,7 +578,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
}
if (ok) {
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->internal_playback_seek (frame_delta);
}
_transport_frame += frame_delta;
@@ -692,7 +696,7 @@ Session::follow_slave (jack_nframes_t nframes, jack_nframes_t offset)
summon_butler ();
}
- jack_nframes_t frames_moved = (long) floor (_transport_speed * nframes);
+ int32_t frames_moved = (int32_t) floor (_transport_speed * nframes);
if (frames_moved < 0) {
decrement_transport_position (-frames_moved);
@@ -729,10 +733,9 @@ Session::process_without_events (jack_nframes_t nframes)
long frames_moved;
{
- Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK);
Glib::RWLock::ReaderLock dsm (diskstream_lock, Glib::TRY_LOCK);
- if (!rm.locked() || !dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
+ if (!dsm.locked() || (post_transport_work & (PostTransportLocate|PostTransportStop))) {
no_roll (nframes, 0);
return;
}
@@ -801,21 +804,23 @@ Session::process_without_events (jack_nframes_t nframes)
void
Session::process_audition (jack_nframes_t nframes)
{
- Glib::RWLock::ReaderLock rm (route_lock, Glib::TRY_LOCK);
Event* ev;
+ boost::shared_ptr<RouteList> r = routes.reader ();
- if (rm.locked()) {
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
- if (!(*i)->hidden()) {
- (*i)->silence (nframes, 0);
- }
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if (!(*i)->hidden()) {
+ (*i)->silence (nframes, 0);
}
}
+
+ /* run the auditioner, and if it says we need butler service, ask for it */
if (auditioner->play_audition (nframes) > 0) {
summon_butler ();
}
+ /* handle pending events */
+
while (pending_events.read (&ev, 1) == 1) {
merge_event (ev);
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 0ae73291e0..9619e77ad1 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -165,7 +165,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_slave_type = None;
butler_mixdown_buffer = 0;
butler_gain_buffer = 0;
- auditioner = 0;
mmc_control = false;
midi_control = true;
mmc = 0;
@@ -180,8 +179,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_edit_mode = Slide;
pending_edit_mode = _edit_mode;
_play_range = false;
- _control_out = 0;
- _master_out = 0;
input_auto_connect = AutoConnectOption (0);
output_auto_connect = AutoConnectOption (0);
waiting_to_start = false;
@@ -197,6 +194,7 @@ Session::first_stage_init (string fullpath, string snapshot_name)
/* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[AudioDiskstream::disk_io_frames() * 4];
_conversion_buffers[TransportContext] = new char[AudioDiskstream::disk_io_frames() * 4];
+ AudioDiskstream::allocate_working_buffers();
/* default short fade = 15ms */
@@ -216,7 +214,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
waveforms for clicks.
*/
- _click_io = 0;
_clicking = false;
click_requested = false;
click_data = 0;
@@ -270,9 +267,12 @@ Session::first_stage_init (string fullpath, string snapshot_name)
AudioSource::AudioSourceCreated.connect (mem_fun (*this, &Session::add_audio_source));
Playlist::PlaylistCreated.connect (mem_fun (*this, &Session::add_playlist));
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
- AudioDiskstream::AudioDiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
+ AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
+ Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
+ Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
+
IO::MoreOutputs.connect (mem_fun (*this, &Session::ensure_passthru_buffers));
/* stop IO objects from doing stuff until we're ready for them */
@@ -1330,6 +1330,13 @@ Session::state(bool full_state)
}
}
+ /* save the ID counter */
+
+ snprintf (buf, sizeof (buf), "%" PRIu64, ID::counter());
+ node->add_property ("id-counter", buf);
+
+ /* various options */
+
node->add_child_nocopy (get_options());
child = node->add_child ("Sources");
@@ -1343,7 +1350,7 @@ Session::state(bool full_state)
AudioFileSource* fs;
- if ((fs = dynamic_cast<AudioFileSource*> ((*siter).second)) != 0) {
+ if ((fs = dynamic_cast<AudioFileSource*> (siter->second)) != 0) {
DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
/* destructive file sources are OK if they are empty, because
@@ -1357,7 +1364,7 @@ Session::state(bool full_state)
}
}
- child->add_child_nocopy ((*siter).second->get_state());
+ child->add_child_nocopy (siter->second->get_state());
}
}
@@ -1370,7 +1377,7 @@ Session::state(bool full_state)
/* only store regions not attached to playlists */
- if ((*i).second->playlist() == 0) {
+ if (i->second->playlist() == 0) {
child->add_child_nocopy (i->second->state (true));
}
}
@@ -1380,7 +1387,7 @@ Session::state(bool full_state)
{
Glib::RWLock::ReaderLock dl (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
child->add_child_nocopy ((*i)->get_state());
}
@@ -1401,10 +1408,10 @@ Session::state(bool full_state)
child = node->add_child ("Routes");
{
- Glib::RWLock::ReaderLock lm (route_lock);
+ boost::shared_ptr<RouteList> r = routes.reader ();
RoutePublicOrderSorter cmp;
- RouteList public_order(routes);
+ RouteList public_order (*r);
public_order.sort (cmp);
for (RouteList::iterator i = public_order.begin(); i != public_order.end(); ++i) {
@@ -1489,7 +1496,7 @@ Session::set_state (const XMLNode& node)
_state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave);
- if (node.name() != "Session"){
+ if (node.name() != X_("Session")){
fatal << _("programming error: Session: incorrect XML node sent to set_state()") << endmsg;
return -1;
}
@@ -1499,6 +1506,21 @@ Session::set_state (const XMLNode& node)
if ((prop = node.property ("name")) != 0) {
_name = prop->value ();
}
+
+ if ((prop = node.property (X_("id-counter"))) != 0) {
+ uint64_t x;
+ sscanf (prop->value().c_str(), "%" PRIu64, &x);
+ ID::init_counter (x);
+ } else {
+ /* old sessions used a timebased counter, so fake
+ the startup ID counter based on a standard
+ timestamp.
+ */
+ time_t now;
+ time (&now);
+ ID::init_counter (now);
+ }
+
IO::disable_ports ();
IO::disable_connecting ();
@@ -1685,7 +1707,6 @@ Session::load_routes (const XMLNode& node)
{
XMLNodeList nlist;
XMLNodeConstIterator niter;
- Route *route;
nlist = node.children();
@@ -1693,7 +1714,9 @@ Session::load_routes (const XMLNode& node)
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
- if ((route = XMLRouteFactory (**niter)) == 0) {
+ boost::shared_ptr<Route> route (XMLRouteFactory (**niter));
+
+ if (route == 0) {
error << _("Session: cannot create Route from XML description.") << endmsg;
return -1;
}
@@ -1704,17 +1727,19 @@ Session::load_routes (const XMLNode& node)
return 0;
}
-Route *
+boost::shared_ptr<Route>
Session::XMLRouteFactory (const XMLNode& node)
{
if (node.name() != "Route") {
- return 0;
+ return boost::shared_ptr<Route> ((Route*) 0);
}
if (node.property ("diskstream") != 0 || node.property ("diskstream-id") != 0) {
- return new AudioTrack (*this, node);
+ boost::shared_ptr<Route> x (new AudioTrack (*this, node));
+ return x;
} else {
- return new Route (*this, node);
+ boost::shared_ptr<Route> x (new Route (*this, node));
+ return x;
}
}
@@ -1730,12 +1755,10 @@ Session::load_regions (const XMLNode& node)
set_dirty();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
-
if ((region = XMLRegionFactory (**niter, false)) == 0) {
error << _("Session: cannot create Region from XML description.") << endmsg;
}
}
-
return 0;
}
@@ -1743,7 +1766,6 @@ AudioRegion *
Session::XMLRegionFactory (const XMLNode& node, bool full)
{
const XMLProperty* prop;
- id_t s_id;
Source* source;
AudioSource* as;
AudioRegion::SourceList sources;
@@ -1766,9 +1788,9 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
}
}
- sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
+ PBD::ID s_id (prop->value());
- if ((source = get_source (s_id)) == 0) {
+ if ((source = source_by_id (s_id)) == 0) {
error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
return 0;
}
@@ -1786,23 +1808,23 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
for (uint32_t n=1; n < nchans; ++n) {
snprintf (buf, sizeof(buf), X_("source-%d"), n);
if ((prop = node.property (buf)) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu64, &s_id);
- if ((source = get_source (s_id)) == 0) {
- error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), s_id) << endmsg;
+ PBD::ID id2 (prop->value());
+
+ if ((source = source_by_id (id2)) == 0) {
+ error << string_compose(_("Session: XMLNode describing a AudioRegion references an unknown source id =%1"), id2) << endmsg;
return 0;
}
as = dynamic_cast<AudioSource*>(source);
if (!as) {
- error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), s_id) << endmsg;
+ error << string_compose(_("Session: XMLNode describing a AudioRegion references a non-audio source id =%1"), id2) << endmsg;
return 0;
}
sources.push_back (as);
}
}
-
try {
return new AudioRegion (sources, node);
}
@@ -1820,7 +1842,7 @@ Session::get_sources_as_xml ()
Glib::Mutex::Lock lm (audio_source_lock);
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
- node->add_child_nocopy ((*i).second->get_state());
+ node->add_child_nocopy (i->second->get_state());
}
/* XXX get MIDI and other sources here */
@@ -2401,23 +2423,6 @@ Session::load_route_groups (const XMLNode& node, bool edit)
return 0;
}
-void
-Session::swap_configuration(Configuration** new_config)
-{
- Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
- Configuration* tmp = *new_config;
- *new_config = Config;
- Config = tmp;
- set_dirty();
-}
-
-void
-Session::copy_configuration(Configuration* new_config)
-{
- Glib::RWLock::WriterLock lm (route_lock);
- new_config = new Configuration(*Config);
-}
-
static bool
state_file_filter (const string &str, void *arg)
{
@@ -2441,7 +2446,7 @@ remove_end(string* state)
statename = statename.substr (start+1);
}
- if ((end = statename.rfind(".ardour")) < 0) {
+ if ((end = statename.rfind(".ardour")) == string::npos) {
end = statename.length();
}
@@ -2589,14 +2594,15 @@ Session::GlobalRouteBooleanState
Session::get_global_route_boolean (bool (Route::*method)(void) const)
{
GlobalRouteBooleanState s;
- Glib::RWLock::ReaderLock lm (route_lock);
+ boost::shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->hidden()) {
RouteBooleanState v;
v.first =* i;
- v.second = ((*i)->*method)();
+ Route* r = (*i).get();
+ v.second = (r->*method)();
s.push_back (v);
}
@@ -2609,9 +2615,9 @@ Session::GlobalRouteMeterState
Session::get_global_route_metering ()
{
GlobalRouteMeterState s;
- Glib::RWLock::ReaderLock lm (route_lock);
+ boost::shared_ptr<RouteList> r = routes.reader ();
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->hidden()) {
RouteMeterState v;
@@ -2637,7 +2643,8 @@ void
Session::set_global_route_boolean (GlobalRouteBooleanState s, void (Route::*method)(bool, void*), void* arg)
{
for (GlobalRouteBooleanState::iterator i = s.begin(); i != s.end(); ++i) {
- (i->first->*method) (i->second, arg);
+ Route* r = i->first.get();
+ (r->*method) (i->second, arg);
}
}
@@ -2944,7 +2951,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
capture files.
*/
- if ((*i).second->use_cnt() == 0 && (*i).second->length() > 0) {
+ if (i->second->use_cnt() == 0 && i->second->length() > 0) {
dead_sources.push_back (i->second);
/* remove this source from our own list to avoid us
@@ -2971,7 +2978,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
tmp = r;
++tmp;
- ar = (*r).second;
+ ar = r->second;
for (uint32_t n = 0; n < ar->n_channels(); ++n) {
if (&ar->source (n) == (*i)) {
@@ -3024,7 +3031,7 @@ Session::cleanup_sources (Session::cleanup_report& rep)
for (AudioSourceList::iterator i = audio_sources.begin(); i != audio_sources.end(); ++i) {
AudioFileSource* fs;
- if ((fs = dynamic_cast<AudioFileSource*> ((*i).second)) != 0) {
+ if ((fs = dynamic_cast<AudioFileSource*> (i->second)) != 0) {
all_sources.insert (fs->path());
}
}
@@ -3233,3 +3240,41 @@ Session::set_clean ()
}
}
+void
+Session::add_controllable (Controllable* c)
+{
+ Glib::Mutex::Lock lm (controllables_lock);
+ controllables.push_back (c);
+}
+
+void
+Session::remove_controllable (Controllable* c)
+{
+ if (_state_of_the_state | Deletion) {
+ return;
+ }
+
+ Glib::Mutex::Lock lm (controllables_lock);
+ controllables.remove (c);
+}
+
+Controllable*
+Session::controllable_by_id (const PBD::ID& id)
+{
+ Glib::Mutex::Lock lm (controllables_lock);
+
+ for (Controllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
+ }
+
+ return 0;
+}
+
+void
+Session::add_instant_xml (XMLNode& node, const std::string& dir)
+{
+ Stateful::add_instant_xml (node, dir);
+ Config->add_instant_xml (node, get_user_ardour_path());
+}
diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc
index 0e52c926fe..bd2c992ff5 100644
--- a/libs/ardour/session_time.cc
+++ b/libs/ardour/session_time.cc
@@ -32,7 +32,6 @@
#include <ardour/audioengine.h>
#include <ardour/session.h>
#include <ardour/tempo.h>
-#include <ardour/audiofilesource.h>
#include "i18n.h"
@@ -93,8 +92,6 @@ Session::set_smpte_offset (jack_nframes_t off)
_smpte_offset = off;
last_smpte_valid = false;
- AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
-
SMPTEOffsetChanged (); /* EMIT SIGNAL */
}
@@ -104,8 +101,6 @@ Session::set_smpte_offset_negative (bool neg)
_smpte_offset_negative = neg;
last_smpte_valid = false;
- AudioFileSource::set_header_position_offset (_smpte_offset, _smpte_offset_negative);
-
SMPTEOffsetChanged (); /* EMIT SIGNAL */
}
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 55bdac064b..3bd54aa69c 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -80,7 +80,7 @@ Session::request_transport_speed (float speed)
}
void
-Session::request_diskstream_speed (AudioDiskstream& ds, float speed)
+Session::request_diskstream_speed (Diskstream& ds, float speed)
{
Event* ev = new Event (Event::SetDiskstreamSpeed, Event::Add, Event::Immediate, 0, speed);
ev->set_ptr (&ds);
@@ -192,17 +192,17 @@ Session::realtime_stop (bool abort)
void
Session::butler_transport_work ()
{
- Glib::RWLock::ReaderLock rm (route_lock);
Glib::RWLock::ReaderLock dsm (diskstream_lock);
-
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
if (post_transport_work & PostTransportCurveRealloc) {
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->curve_reallocate();
}
}
if (post_transport_work & PostTransportInputChange) {
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->non_realtime_input_change ();
}
}
@@ -218,7 +218,7 @@ Session::butler_transport_work ()
cumulative_rf_motion = 0;
reset_rf_scale (0);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -250,7 +250,7 @@ Session::non_realtime_set_speed ()
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->non_realtime_set_speed ();
}
}
@@ -260,7 +260,7 @@ Session::non_realtime_overwrite ()
{
Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->pending_overwrite) {
(*i)->overwrite_existing_buffers ();
}
@@ -276,7 +276,7 @@ Session::non_realtime_stop (bool abort)
did_record = false;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->get_captured_frames () != 0) {
did_record = true;
break;
@@ -331,11 +331,13 @@ Session::non_realtime_stop (bool abort)
_have_captured = true;
}
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->transport_stopped (*now, xnow, abort);
}
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_pending_declick (0);
}
@@ -368,7 +370,7 @@ Session::non_realtime_stop (bool abort)
}
#endif
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->speed() != 1.0f || (*i)->speed() != -1.0f) {
(*i)->seek ((jack_nframes_t) (_transport_frame * (double) (*i)->speed()));
@@ -495,7 +497,7 @@ Session::set_auto_loop (bool yn)
if (seamless_loop) {
// set all diskstreams to use internal looping
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (loc);
}
@@ -503,7 +505,7 @@ Session::set_auto_loop (bool yn)
}
else {
// set all diskstreams to NOT use internal looping
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (0);
}
@@ -533,7 +535,7 @@ Session::set_auto_loop (bool yn)
clear_events (Event::AutoLoop);
// set all diskstreams to NOT use internal looping
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
(*i)->set_loop (0);
}
@@ -547,7 +549,9 @@ Session::set_auto_loop (bool yn)
void
Session::flush_all_redirects ()
{
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->flush_redirects ();
}
}
@@ -649,7 +653,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
The rarity and short potential lock duration makes this "OK"
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (!auto_input);
@@ -664,7 +668,7 @@ Session::locate (jack_nframes_t target_frame, bool with_roll, bool with_flush, b
The rarity and short potential lock duration makes this "OK"
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true);
@@ -708,7 +712,7 @@ Session::set_transport_speed (float speed, bool abort)
The rarity and short potential lock duration makes this "OK"
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->record_enabled ()) {
//cerr << "switching to input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (true);
@@ -734,7 +738,7 @@ Session::set_transport_speed (float speed, bool abort)
The rarity and short potential lock duration makes this "OK"
*/
Glib::RWLock::ReaderLock dsm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (auto_input && (*i)->record_enabled ()) {
//cerr << "switching from input" << __FILE__ << __LINE__ << endl << endl;
(*i)->monitor_input (false);
@@ -785,7 +789,7 @@ Session::set_transport_speed (float speed, bool abort)
_last_transport_speed = _transport_speed;
_transport_speed = speed;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
}
@@ -875,7 +879,7 @@ Session::actually_start_transport ()
transport_sub_state |= PendingDeclickIn;
_transport_speed = 1.0;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->realtime_set_speed ((*i)->speed(), true);
}
@@ -1005,7 +1009,7 @@ Session::set_slave_source (SlaveSource src, jack_nframes_t frame)
_slave_type = src;
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
if ((*i)->realtime_set_speed ((*i)->speed(), true)) {
non_rt_required = true;
@@ -1037,7 +1041,7 @@ Session::reverse_diskstream_buffers ()
}
void
-Session::set_diskstream_speed (AudioDiskstream* stream, float speed)
+Session::set_diskstream_speed (Diskstream* stream, float speed)
{
if (stream->realtime_set_speed (speed, false)) {
post_transport_work = PostTransportWork (post_transport_work | PostTransportSpeed);
@@ -1196,11 +1200,12 @@ Session::update_latency_compensation (bool with_stop, bool abort)
return;
}
- Glib::RWLock::ReaderLock lm (route_lock);
Glib::RWLock::ReaderLock lm2 (diskstream_lock);
_worst_track_latency = 0;
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ boost::shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
if (with_stop) {
(*i)->handle_transport_stopped (abort, (post_transport_work & PostTransportLocate),
(!(post_transport_work & PostTransportLocate) || pending_locate_flush));
@@ -1218,7 +1223,7 @@ Session::update_latency_compensation (bool with_stop, bool abort)
}
}
- for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
(*i)->set_latency_delay (_worst_track_latency);
}
@@ -1228,12 +1233,12 @@ Session::update_latency_compensation (bool with_stop, bool abort)
_engine.update_total_latencies ();
}
- set_worst_io_latencies (false);
+ set_worst_io_latencies ();
/* reflect any changes in latencies into capture offsets
*/
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); ++i) {
+ for (DiskstreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
(*i)->set_capture_offset ();
}
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 443a24e3c2..5936f62570 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -156,6 +156,8 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
utsinfo.version);
_broadcast_info->version = 1;
+ _broadcast_info->time_reference_low = 0;
+ _broadcast_info->time_reference_high = 0;
/* XXX do something about this field */
@@ -183,6 +185,7 @@ SndFileSource::SndFileSource (string idstr, SampleFormat sfmt, HeaderFormat hf,
}
AudioSourceCreated (this); /* EMIT SIGNAL */
+
}
void
@@ -246,21 +249,19 @@ SndFileSource::open ()
_flags = Flag (_flags & ~Broadcast);
}
+ set_timeline_position (header_position_offset);
+
} else {
/* XXX 64 bit alert: when JACK switches to a 64 bit frame count, this needs to use the high bits
of the time reference.
*/
-
- set_timeline_position (_broadcast_info->time_reference_low);
+
+ set_timeline_position ( _broadcast_info->time_reference_low );
}
if (writable()) {
sf_command (sf, SFC_SET_UPDATE_HEADER_AUTO, 0, SF_FALSE);
-
- /* update header if header offset info changes */
-
- AudioFileSource::HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioFileSource::handle_header_position_change));
}
return 0;
@@ -280,7 +281,7 @@ SndFileSource::~SndFileSource ()
}
if (_broadcast_info) {
- free (_broadcast_info);
+ delete _broadcast_info;
}
}
@@ -472,7 +473,7 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t
now.tm_mon,
now.tm_mday);
- snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d-%02d-%02d",
+ snprintf (_broadcast_info->origination_time, sizeof (_broadcast_info->origination_time), "%02d:%02d:%02d",
now.tm_hour,
now.tm_min,
now.tm_sec);
@@ -495,33 +496,12 @@ SndFileSource::setup_broadcast_info (jack_nframes_t when, struct tm& now, time_t
void
SndFileSource::set_header_timeline_position ()
{
- uint64_t pos;
-
if (!(_flags & Broadcast)) {
return;
}
- _broadcast_info->time_reference_high = 0;
-
- if (header_position_negative) {
-
- if (ULONG_LONG_MAX - header_position_offset < timeline_position) {
- pos = ULONG_LONG_MAX; // impossible
- } else {
- pos = timeline_position + header_position_offset;
- }
-
- } else {
-
- if (timeline_position < header_position_offset) {
- pos = 0;
- } else {
- pos = timeline_position - header_position_offset;
- }
- }
-
- _broadcast_info->time_reference_high = (pos >> 32);
- _broadcast_info->time_reference_low = (pos & 0xffffffff);
+ _broadcast_info->time_reference_high = (timeline_position >> 32);
+ _broadcast_info->time_reference_low = (timeline_position & 0xffffffff);
if (sf_command (sf, SFC_SET_BROADCAST_INFO, _broadcast_info, sizeof (*_broadcast_info)) != SF_TRUE) {
error << string_compose (_("cannot set broadcast info for audio file %1; Dropping broadcast info for this file"), _path) << endmsg;
@@ -545,3 +525,9 @@ SndFileSource::write_float (Sample* data, jack_nframes_t frame_pos, jack_nframes
return cnt;
}
+
+jack_nframes_t
+SndFileSource::natural_position() const
+{
+ return timeline_position;
+}
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 0d32ea4a21..eebc64d463 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -45,7 +45,6 @@ using namespace ARDOUR;
Source::Source (string name)
{
_name = name;
- _id = ARDOUR::new_id();
_use_cnt = 0;
_timestamp = 0;
}
@@ -71,7 +70,7 @@ Source::get_state ()
char buf[64];
node->add_property ("name", _name);
- snprintf (buf, sizeof(buf)-1, "%" PRIu64, _id);
+ _id.print (buf);
node->add_property ("id", buf);
if (_timestamp != 0) {
@@ -94,7 +93,7 @@ Source::set_state (const XMLNode& node)
}
if ((prop = node.property ("id")) != 0) {
- sscanf (prop->value().c_str(), "%" PRIu64, &_id);
+ _id = prop->value ();
} else {
return -1;
}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
new file mode 100644
index 0000000000..3b3b705a87
--- /dev/null
+++ b/libs/ardour/track.cc
@@ -0,0 +1,219 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#include <pbd/error.h>
+#include <sigc++/retype.h>
+#include <sigc++/retype_return.h>
+#include <sigc++/bind.h>
+
+#include <ardour/track.h>
+#include <ardour/diskstream.h>
+#include <ardour/session.h>
+#include <ardour/redirect.h>
+#include <ardour/audioregion.h>
+#include <ardour/audiosource.h>
+#include <ardour/route_group_specialized.h>
+#include <ardour/insert.h>
+#include <ardour/audioplaylist.h>
+#include <ardour/panner.h>
+#include <ardour/utils.h>
+
+#include "i18n.h"
+
+using namespace std;
+using namespace ARDOUR;
+using namespace PBD;
+
+Track::Track (Session& sess, string name, Route::Flag flag, TrackMode mode, DataType default_type)
+ : Route (sess, name, 1, -1, -1, -1, flag, default_type)
+ , _diskstream (0)
+ , _rec_enable_control (*this)
+{
+ _declickable = true;
+ _freeze_record.state = NoFreeze;
+ _saved_meter_point = _meter_point;
+ _mode = mode;
+}
+
+Track::Track (Session& sess, const XMLNode& node, DataType default_type)
+ : Route (sess, "to be renamed", 0, 0, -1, -1, Route::Flag(0), default_type)
+ , _diskstream (0)
+ , _rec_enable_control (*this)
+{
+ _freeze_record.state = NoFreeze;
+ _declickable = true;
+ _saved_meter_point = _meter_point;
+}
+
+Track::~Track ()
+{
+ if (_diskstream) {
+ _diskstream->unref();
+ }
+}
+
+void
+Track::set_meter_point (MeterPoint p, void *src)
+{
+ Route::set_meter_point (p, src);
+}
+
+XMLNode&
+Track::get_state ()
+{
+ return state (true);
+}
+
+XMLNode&
+Track::get_template ()
+{
+ return state (false);
+}
+
+void
+Track::toggle_monitor_input ()
+{
+ for (vector<Port*>::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
+ (*i)->request_monitor_input(!(*i)->monitoring_input());
+ }
+}
+
+jack_nframes_t
+Track::update_total_latency ()
+{
+ _own_latency = 0;
+
+ for (RedirectList::iterator i = _redirects.begin(); i != _redirects.end(); ++i) {
+ if ((*i)->active ()) {
+ _own_latency += (*i)->latency ();
+ }
+ }
+
+ set_port_latency (_own_latency);
+
+ return _own_latency;
+}
+
+
+Track::FreezeRecord::~FreezeRecord ()
+{
+ for (vector<FreezeRecordInsertInfo*>::iterator i = insert_info.begin(); i != insert_info.end(); ++i) {
+ delete *i;
+ }
+}
+
+Track::FreezeState
+Track::freeze_state() const
+{
+ return _freeze_record.state;
+}
+
+Track::RecEnableControllable::RecEnableControllable (Track& s)
+ : track (s)
+{
+}
+
+void
+Track::RecEnableControllable::set_value (float val)
+{
+ bool bval = ((val >= 0.5f) ? true: false);
+ track.set_record_enable (bval, this);
+}
+
+float
+Track::RecEnableControllable::get_value (void) const
+{
+ if (track.record_enabled()) { return 1.0f; }
+ return 0.0f;
+}
+
+bool
+Track::record_enabled () const
+{
+ return _diskstream->record_enabled ();
+}
+
+void
+Track::set_record_enable (bool yn, void *src)
+{
+ if (_freeze_record.state == Frozen) {
+ return;
+ }
+
+ if (_mix_group && src != _mix_group && _mix_group->is_active()) {
+ _mix_group->apply (&Track::set_record_enable, yn, _mix_group);
+ return;
+ }
+
+ /* keep track of the meter point as it was before we rec-enabled */
+
+ if (!_diskstream->record_enabled()) {
+ _saved_meter_point = _meter_point;
+ }
+
+ _diskstream->set_record_enabled (yn);
+
+ if (_diskstream->record_enabled()) {
+ set_meter_point (MeterInput, this);
+ } else {
+ set_meter_point (_saved_meter_point, this);
+ }
+
+ _rec_enable_control.Changed ();
+}
+
+void
+Track::set_mode (TrackMode m)
+{
+ if (_diskstream) {
+ if (_mode != m) {
+ _mode = m;
+ _diskstream->set_destructive (m == Destructive);
+ ModeChanged();
+ }
+ }
+}
+
+int
+Track::set_name (string str, void *src)
+{
+ int ret;
+
+ if (record_enabled() && _session.actively_recording()) {
+ /* this messes things up if done while recording */
+ return -1;
+ }
+
+ if (_diskstream->set_name (str)) {
+ return -1;
+ }
+
+ /* save state so that the statefile fully reflects any filename changes */
+
+ if ((ret = IO::set_name (str, src)) == 0) {
+ _session.save_state ("");
+ }
+ return ret;
+}
+
+void
+Track::set_latency_delay (jack_nframes_t longest_session_latency)
+{
+ Route::set_latency_delay (longest_session_latency);
+ _diskstream->set_roll_delay (_roll_delay);
+}
+
diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc
index 9adc7c72cd..78e5572a3d 100644
--- a/libs/ardour/utils.cc
+++ b/libs/ardour/utils.cc
@@ -186,15 +186,6 @@ touch_file (string path)
return 1;
}
-uint32_t long
-get_uid()
-{
- struct timeval tv;
- gettimeofday(&tv, 0);
-
- return (uint32_t long) tv.tv_sec * 1000000 + tv.tv_usec;
-}
-
string
placement_as_string (Placement p)
{
@@ -262,3 +253,21 @@ path_expand (string path)
#endif
}
+#ifdef HAVE_COREAUDIO
+string
+CFStringRefToStdString(CFStringRef stringRef)
+{
+ CFIndex size =
+ CFStringGetMaximumSizeForEncoding(CFStringGetLength(stringRef) ,
+ kCFStringEncodingUTF8);
+ char *buf = new char[size];
+
+ std::string result;
+
+ if(CFStringGetCString(stringRef, buf, size, kCFStringEncodingUTF8)) {
+ result = buf;
+ }
+ delete [] buf;
+ return result;
+}
+#endif // HAVE_COREAUDIO
diff --git a/libs/ardour/vst_plugin.cc b/libs/ardour/vst_plugin.cc
index 80c36dab95..a551a15d28 100644
--- a/libs/ardour/vst_plugin.cc
+++ b/libs/ardour/vst_plugin.cc
@@ -41,8 +41,6 @@
#include <vst/aeffectx.h>
-#include <midi++/manager.h>
-
#include <ardour/ardour.h>
#include <ardour/session.h>
#include <ardour/audioengine.h>
@@ -81,7 +79,7 @@ VSTPlugin::VSTPlugin (AudioEngine& e, Session& session, FSTHandle* h)
_plugin->dispatcher (_plugin, effSetProgram, 0, 0, NULL, 0.0f);
- Plugin::setup_midi_controls ();
+ Plugin::setup_controls ();
}
VSTPlugin::VSTPlugin (const VSTPlugin &other)
@@ -94,7 +92,7 @@ VSTPlugin::VSTPlugin (const VSTPlugin &other)
}
_plugin = _fst->plugin;
- Plugin::setup_midi_controls ();
+ Plugin::setup_controls ();
}
VSTPlugin::~VSTPlugin ()
@@ -133,13 +131,6 @@ VSTPlugin::set_parameter (uint32_t which, float val)
{
_plugin->setParameter (_plugin, which, val);
ParameterChanged (which, val); /* EMIT SIGNAL */
-
- if (session().get_midi_feedback()) {
-
- if (which < parameter_count() && midi_controls[which]) {
- midi_controls[which]->send_feedback (val);
- }
- }
}
float
@@ -488,3 +479,31 @@ VSTPlugin::print_parameter (uint32_t param, char *buf, uint32_t len) const
memmove (buf, first_nonws, strlen (buf) - (first_nonws - buf) + 1);
}
+
+PluginPtr
+VSTPluginInfo::load (Session& session)
+{
+ try {
+ PluginPtr plugin;
+
+ if (Config->get_use_vst()) {
+ FSTHandle* handle;
+
+ if ((handle = fst_load (info->path.c_str())) == 0) {
+ error << string_compose(_("VST: cannot load module from \"%1\""), info->path) << endmsg;
+ } else {
+ plugin.reset (new VSTPlugin (session.engine(), session, handle));
+ }
+ } else {
+ error << _("You asked ardour to not use any VST plugins") << endmsg;
+ return PluginPtr ((Plugin*) 0);
+ }
+
+ plugin->set_info(PluginInfoPtr(new VSTPluginInfo(*this)));
+ return plugin;
+ }
+
+ catch (failed_constructor &err) {
+ return PluginPtr ((Plugin*) 0);
+ }
+}
diff --git a/libs/gtkmm2ext/SConscript b/libs/gtkmm2ext/SConscript
index b70aea3d40..cf513eb5a1 100644
--- a/libs/gtkmm2ext/SConscript
+++ b/libs/gtkmm2ext/SConscript
@@ -9,8 +9,7 @@ Import('env final_prefix install_prefix libraries i18n')
gtkmm2ext = env.Copy()
gtkmm2ext.Merge ([
libraries['sigc2'],
- libraries['pbd3'],
- libraries['midi++2'],
+ libraries['pbd'],
libraries['gtk2'],
libraries['glibmm2'],
libraries['pangomm'],
@@ -25,24 +24,25 @@ gtkmm2ext.Merge ([
domain = 'libgtkmm2ext'
-gtkmm2ext.Append(DOMAIN=domain,MAJOR=0,MINOR=8,MICRO=2)
+gtkmm2ext.Append(DOMAIN=domain,MAJOR=0,MINOR=8,MICRO=3)
gtkmm2ext.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"")
gtkmm2ext.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
+#gtkmm2ext.Append(CPPPATH='#libs/surfaces/control_protocol')
gtkmm2ext.Append(PACKAGE=domain)
gtkmm2ext.Append(POTFILE=domain + '.pot')
gtkmm2ext_files = Split("""
auto_spin.cc
barcontroller.cc
-bindable_button.cc
+binding_proxy.cc
choice.cc
click_box.cc
-controller.cc
dndtreeview.cc
fastmeter.cc
gtk_ui.cc
hexentry.cc
idle_adjustment.cc
+pathlist.cc
pixscroller.cc
popup.cc
prompter.cc
diff --git a/libs/gtkmm2ext/barcontroller.cc b/libs/gtkmm2ext/barcontroller.cc
index c977f3e5f7..eefe6ca843 100644
--- a/libs/gtkmm2ext/barcontroller.cc
+++ b/libs/gtkmm2ext/barcontroller.cc
@@ -23,7 +23,7 @@
#include <cmath>
#include <algorithm>
-#include <midi++/controllable.h>
+#include <pbd/controllable.h>
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/utils.h>
@@ -36,16 +36,13 @@ using namespace Gtk;
using namespace Gtkmm2ext;
BarController::BarController (Gtk::Adjustment& adj,
- MIDI::Controllable *mc,
+ PBD::Controllable& mc,
sigc::slot<void,char*,unsigned int> lc)
: adjustment (adj),
- prompter (Gtk::WIN_POS_MOUSE, 30000, false),
- midi_control (mc),
+ binding_proxy (mc),
label_callback (lc),
- spinner (adjustment),
- bind_button (2),
- bind_statemask (Gdk::CONTROL_MASK)
+ spinner (adjustment)
{
_style = LeftToRight;
@@ -77,16 +74,6 @@ BarController::BarController (Gtk::Adjustment& adj,
darea.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release));
darea.signal_scroll_event().connect (mem_fun (*this, &BarController::scroll));
- prompter.signal_unmap_event().connect (mem_fun (*this, &BarController::prompter_hiding));
-
- prompting = false;
- unprompting = false;
-
- if (mc) {
- mc->learning_started.connect (mem_fun (*this, &BarController::midicontrol_prompt));
- mc->learning_stopped.connect (mem_fun (*this, &BarController::midicontrol_unprompt));
- }
-
spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
spinner.set_digits (3);
@@ -95,24 +82,13 @@ BarController::BarController (Gtk::Adjustment& adj,
show_all ();
}
-void
-BarController::set_bind_button_state (guint button, guint statemask)
-{
- bind_button = button;
- bind_statemask = statemask;
-}
-
-void
-BarController::get_bind_button_state (guint &button, guint &statemask)
-{
- button = bind_button;
- statemask = bind_statemask;
-}
-
-
bool
BarController::button_press (GdkEventButton* ev)
{
+ if (binding_proxy.button_press_handler (ev)) {
+ return true;
+ }
+
switch (ev->button) {
case 1:
if (ev->type == GDK_2BUTTON_PRESS) {
@@ -174,8 +150,8 @@ BarController::button_release (GdkEventButton* ev)
break;
case 2:
- if ((ev->state & bind_statemask) && bind_button == 2) {
- midi_learn ();
+ if (true) { // XXX FIX ME
+ /* relax */
} else {
double fract;
fract = ev->x / (darea.get_width() - 2.0);
@@ -185,10 +161,6 @@ BarController::button_release (GdkEventButton* ev)
return true;
case 3:
- if ((ev->state & bind_statemask) && bind_button == 3) {
- midi_learn ();
- return TRUE;
- }
return false;
default:
@@ -408,61 +380,6 @@ BarController::set_with_text (bool yn)
}
void
-BarController::midicontrol_set_tip ()
-{
- if (midi_control) {
- // Gtkmm2ext::UI::instance()->set_tip (&darea, midi_control->control_description());
- }
-}
-
-void
-BarController::midi_learn()
-{
- if (midi_control) {
- prompting = true;
- midi_control->learn_about_external_control ();
- }
-}
-
-
-void
-BarController::midicontrol_prompt ()
-{
- if (prompting) {
- string prompt = _("operate MIDI controller now");
- prompter.set_text (prompt);
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
-
- unprompting = true;
- prompting = false;
- }
-}
-
-void
-BarController::midicontrol_unprompt ()
-{
- if (unprompting) {
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
-
- unprompting = false;
- }
-}
-
-gint
-BarController::prompter_hiding (GdkEventAny *ev)
-{
- if (unprompting) {
- if (midi_control) {
- midi_control->stop_learning();
- }
- unprompting = false;
- }
-
- return FALSE;
-}
-
-
-void
BarController::set_style (Style s)
{
_style = s;
diff --git a/libs/gtkmm2ext/binding_proxy.cc b/libs/gtkmm2ext/binding_proxy.cc
new file mode 100644
index 0000000000..3a2f5bbbc8
--- /dev/null
+++ b/libs/gtkmm2ext/binding_proxy.cc
@@ -0,0 +1,89 @@
+/*
+ Copyright (C) 2006 Paul Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#include <string>
+#include <climits>
+#include <iostream>
+
+#include <pbd/controllable.h>
+
+#include <gtkmm2ext/binding_proxy.h>
+
+#include "i18n.h"
+
+using namespace Gtkmm2ext;
+using namespace std;
+using namespace PBD;
+
+BindingProxy::BindingProxy (Controllable& c)
+ : prompter (Gtk::WIN_POS_MOUSE, 30000, false),
+ controllable (c),
+ bind_button (2),
+ bind_statemask (Gdk::CONTROL_MASK)
+
+{
+ prompter.signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding));
+}
+
+void
+BindingProxy::set_bind_button_state (guint button, guint statemask)
+{
+ bind_button = button;
+ bind_statemask = statemask;
+}
+
+void
+BindingProxy::get_bind_button_state (guint &button, guint &statemask)
+{
+ button = bind_button;
+ statemask = bind_statemask;
+}
+
+bool
+BindingProxy::button_press_handler (GdkEventButton *ev)
+{
+ if ((ev->state & bind_statemask) && ev->button == bind_button) {
+ if (Controllable::StartLearning (&controllable)) {
+ string prompt = _("operate controller now");
+ prompter.set_text (prompt);
+ prompter.touch (); // shows popup
+ learning_connection = controllable.LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished));
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void
+BindingProxy::learning_finished ()
+{
+ learning_connection.disconnect ();
+ prompter.touch (); // hides popup
+}
+
+
+bool
+BindingProxy::prompter_hiding (GdkEventAny *ev)
+{
+ learning_connection.disconnect ();
+ Controllable::StopLearning (&controllable);
+ return false;
+}
+
diff --git a/libs/gtkmm2ext/controller.cc b/libs/gtkmm2ext/controller.cc
deleted file mode 100644
index 98d5566c69..0000000000
--- a/libs/gtkmm2ext/controller.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Davis
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
-*/
-
-#include <string>
-#include <climits>
-
-#include <midi++/channel.h>
-#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/controller.h>
-
-#include "i18n.h"
-
-using namespace Gtkmm2ext;
-
-Controller::Controller (Gtk::Adjustment *adj, MIDI::Port *p)
- : MIDI::Controllable (p),
- adjustment (adj),
- prompter (Gtk::WIN_POS_MOUSE, 30000, false)
-{
- new_value_pending = false;
-
- /* hear about MIDI control learning */
-
- learning_started.connect
- (mem_fun (*this, &Controller::midicontrol_prompt));
- learning_stopped.connect
- (mem_fun (*this, &Controller::midicontrol_unprompt));
-}
-
-void
-Controller::midicontrol_prompt ()
-
-{
- string prompt = _("operate MIDI controller now");
-
- prompter.set_text (prompt);
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
-}
-
-void
-Controller::midicontrol_unprompt ()
-
-{
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
-}
-
-int
-Controller::update_controller_value (void *arg)
-
-{
- Controller *c = (Controller *) arg;
-
- c->adjustment->set_value (c->new_value);
- c->new_value_pending = false;
-
- return FALSE;
-}
-
-void
-Controller::set_value (float v)
-
-{
- /* This is called from a MIDI callback. It could happen
- a thousand times a second, or more. Therefore, instead
- of going straight to the X server, which may not work for
- thread-related reasons, simply request an update whenever
- the GTK main loop is idle.
- */
-
- new_value = v;
-
- if (!new_value_pending) {
- new_value_pending = true;
- Gtkmm2ext::UI::instance()->idle_add (update_controller_value, this);
- }
-}
diff --git a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
index 67c8221a55..ebce4e2de9 100644
--- a/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/barcontroller.h
@@ -21,9 +21,9 @@
#define __gtkmm2ext_bar_controller_h__
#include <gtkmm.h>
-#include <gtkmm2ext/popup.h>
+#include <gtkmm2ext/binding_proxy.h>
-namespace MIDI {
+namespace ARDOUR {
class Controllable;
}
@@ -32,14 +32,9 @@ namespace Gtkmm2ext {
class BarController : public Gtk::Frame
{
public:
- BarController (Gtk::Adjustment& adj, MIDI::Controllable*, sigc::slot<void,char*,unsigned int>);
+ BarController (Gtk::Adjustment& adj, PBD::Controllable&, sigc::slot<void,char*,unsigned int>);
virtual ~BarController () {}
- void set_bind_button_state (guint button, guint statemask);
- void get_bind_button_state (guint &button, guint &statemask);
- void midicontrol_set_tip ();
- void midi_learn ();
-
void set_sensitive (bool yn) {
darea.set_sensitive (yn);
}
@@ -69,9 +64,8 @@ class BarController : public Gtk::Frame
protected:
Gtk::Adjustment& adjustment;
+ BindingProxy binding_proxy;
Gtk::DrawingArea darea;
- Gtkmm2ext::PopUp prompter;
- MIDI::Controllable* midi_control;
sigc::slot<void,char*,unsigned int> label_callback;
Glib::RefPtr<Pango::Layout> layout;
Style _style;
@@ -85,10 +79,6 @@ class BarController : public Gtk::Frame
Gtk::SpinButton spinner;
bool use_parent;
- guint bind_button;
- guint bind_statemask;
- bool prompting, unprompting;
-
bool button_press (GdkEventButton *);
bool button_release (GdkEventButton *);
bool motion (GdkEventMotion *);
@@ -98,11 +88,6 @@ class BarController : public Gtk::Frame
gint mouse_control (double x, GdkWindow* w, double scaling);
- gint prompter_hiding (GdkEventAny *);
- void midicontrol_prompt ();
- void midicontrol_unprompt ();
- void update_midi_control ();
-
gint switch_to_bar ();
gint switch_to_spinner ();
diff --git a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
index 7400cf15d0..1936125405 100644
--- a/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
+++ b/libs/gtkmm2ext/gtkmm2ext/bindable_button.h
@@ -18,59 +18,31 @@
$Id$
*/
-#ifndef __pbd_gtkmm_bindable_button_h__
-#define __pbd_gtkmm_bindable_button_h__
+#ifndef __bindable_button_h__
+#define __bindable_button_h__
#include <string>
#include <gtkmm2ext/stateful_button.h>
-#include <gtkmm2ext/popup.h>
+#include "binding_proxy.h"
-namespace MIDI {
+namespace PBD {
class Controllable;
}
-namespace Gtkmm2ext {
-
class BindableToggleButton : public Gtk::ToggleButton
{
public:
- BindableToggleButton(MIDI::Controllable *);
-
- //: Create a check button with a label.
- //- You won't be able
- //- to add a widget in this button since it already has a {\class Gtk_Label}
- //- in it.
- explicit BindableToggleButton(MIDI::Controllable *, const std::string &label);
-
+ BindableToggleButton (PBD::Controllable& c) : binding_proxy (c) {}
+ explicit BindableToggleButton (PBD::Controllable& c, const std::string &label) : Gtk::ToggleButton (label), binding_proxy (c) {}
virtual ~BindableToggleButton() {}
- void set_bind_button_state (guint button, guint statemask);
- void get_bind_button_state (guint &button, guint &statemask);
-
- void midicontrol_set_tip ();
-
- void midi_learn ();
-
- protected:
-
- Gtkmm2ext::PopUp prompter;
-
- MIDI::Controllable* midi_control;
-
- guint bind_button;
- guint bind_statemask;
-
- bool prompting, unprompting;
-
- void init_events ();
- bool prompter_hiding (GdkEventAny *);
- void midicontrol_prompt ();
- void midicontrol_unprompt ();
-
- bool on_button_press_event (GdkEventButton *);
-};
+ bool on_button_press_event (GdkEventButton *ev) {
+ return binding_proxy.button_press_handler (ev);
+ }
+ private:
+ BindingProxy binding_proxy;
};
#endif
diff --git a/libs/ardour/ardour/session_diskstream.h b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
index 33fc5419ba..a26c8ace2a 100644
--- a/libs/ardour/ardour/session_diskstream.h
+++ b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2002 Paul Davis
+ Copyright (C) 2006 Paul Davis
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
@@ -18,25 +18,37 @@
$Id$
*/
-#ifndef __ardour_session_diskstream_h__
-#define __ardour_session_diskstream_h__
+#ifndef __binding_proxy__
+#define __binding_proxy__
-#include <ardour/session.h>
-#include <ardour/audio_diskstream.h>
+#include <string>
-namespace ARDOUR {
+#include <gtkmm2ext/popup.h>
-template<class T> void
-Session::foreach_audio_diskstream (T *obj, void (T::*func)(AudioDiskstream&))
-{
- Glib::RWLock::ReaderLock lm (diskstream_lock);
- for (AudioDiskstreamList::iterator i = audio_diskstreams.begin(); i != audio_diskstreams.end(); i++) {
- if (!(*i)->hidden()) {
- (obj->*func) (**i);
- }
- }
+namespace PBD {
+ class Controllable;
}
-} /* namespace */
-
-#endif /* __ardour_session_diskstream_h__ */
+class BindingProxy : public sigc::trackable
+{
+ public:
+ BindingProxy (PBD::Controllable&);
+ virtual ~BindingProxy() {}
+
+ void set_bind_button_state (guint button, guint statemask);
+ void get_bind_button_state (guint &button, guint &statemask);
+
+ bool button_press_handler (GdkEventButton *);
+
+ protected:
+
+ Gtkmm2ext::PopUp prompter;
+ PBD::Controllable& controllable;
+ guint bind_button;
+ guint bind_statemask;
+ sigc::connection learning_connection;
+ void learning_finished ();
+ bool prompter_hiding (GdkEventAny *);
+};
+
+#endif
diff --git a/libs/gtkmm2ext/gtkmm2ext/controller.h b/libs/gtkmm2ext/gtkmm2ext/pathlist.h
index b72f6c7ed7..f4a5973d5a 100644
--- a/libs/gtkmm2ext/gtkmm2ext/controller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/pathlist.h
@@ -1,5 +1,6 @@
/*
- Copyright (C) 1998-99 Paul Davis
+ Copyright (C) 2006 Paul Davis
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -14,46 +15,49 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
*/
-#ifndef __gtkmm2ext_controller_h__
-#define __gtkmm2ext_controller_h__
+#ifndef __gtkmm2ext_pathlist_h__
+#define __gtkmm2ext_pathlist_h__
+
+#include <vector>
+#include <string>
#include <gtkmm.h>
-#include <gtkmm2ext/popup.h>
-#include <midi++/controllable.h>
namespace Gtkmm2ext {
-class Controller : public MIDI::Controllable
-
+class PathList : public Gtk::VBox
{
public:
- Controller (Gtk::Adjustment *, MIDI::Port *);
- virtual ~Controller () {}
+ PathList ();
+ ~PathList () {};
+
+ std::vector<std::string> get_paths ();
+ void set_paths (std::vector<std::string> paths);
+
+ sigc::signal<void> PathsUpdated;
- void set_value (float);
- float lower () { return adjustment->get_lower(); }
- float upper () { return adjustment->get_upper(); }
- float range () { return upper() - lower() /* XXX +1 ??? */ ; }
-
- void midicontrol_prompt ();
- void midicontrol_unprompt ();
-
protected:
- Gtk::Adjustment *adjustment;
+ Gtk::Button add_btn;
+ Gtk::Button subtract_btn;
- private:
- Gtkmm2ext::PopUp prompter;
- gfloat new_value;
- bool new_value_pending;
+ void add_btn_clicked ();
+ void subtract_btn_clicked ();
- static gint update_controller_value (void *);
+ private:
+ struct PathColumns : public Gtk::TreeModel::ColumnRecord {
+ PathColumns() { add (paths); }
+ Gtk::TreeModelColumn<std::string> paths;
+ };
+ PathColumns path_columns;
+
+ Glib::RefPtr<Gtk::ListStore> _store;
+ Gtk::TreeView _view;
+
+ void selection_changed ();
};
-}; /* namespace */
-
-#endif // __gtkmm2ext_controller_h__
-
+} // namespace Gtkmm2ext
+#endif // __gtkmm2ext_pathlist_h__
diff --git a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
index 7abaf285d1..f0f645eab7 100644
--- a/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
+++ b/libs/gtkmm2ext/gtkmm2ext/slider_controller.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1998-99 Paul Davis
+ Copyright (C) 1998-2006 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
@@ -17,18 +17,19 @@
$Id$
*/
-#ifndef __gtkmm2ext_motion_controller_h__
-#define __gtkmm2ext_motion_controller_h__
+#ifndef __gtkmm2ext_slider_controller_h__
+#define __gtkmm2ext_slider_controller_h__
#include <gtkmm.h>
#include <gtkmm2ext/popup.h>
#include <gtkmm2ext/pixscroller.h>
+#include <gtkmm2ext/binding_proxy.h>
namespace Gtkmm2ext {
class Pix;
}
-namespace MIDI {
+namespace PBD {
class Controllable;
}
@@ -40,41 +41,24 @@ class SliderController : public Gtkmm2ext::PixScroller
SliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment* adj,
- MIDI::Controllable*,
+ PBD::Controllable&,
bool with_numeric = true);
virtual ~SliderController () {}
- void set_bind_button_state (guint button, guint statemask);
- void get_bind_button_state (guint &button, guint &statemask);
- void midicontrol_set_tip ();
- void midi_learn ();
-
void set_value (float);
- // void set_sensitive (bool yn) {
- // spin.set_sensitive (yn);
- // }
- Gtk::SpinButton & get_spin_button () { return spin; }
+ Gtk::SpinButton& get_spin_button () { return spin; }
+ bool on_button_press_event (GdkEventButton *ev);
+
protected:
+ BindingProxy binding_proxy;
Glib::RefPtr<Gdk::Pixbuf> slider;
Glib::RefPtr<Gdk::Pixbuf> rail;
Gtk::SpinButton spin;
Gtk::Frame spin_frame;
Gtk::HBox spin_hbox;
- Gtkmm2ext::PopUp prompter;
- MIDI::Controllable* midi_control;
-
- guint bind_button;
- guint bind_statemask;
- bool prompting, unprompting;
-
- bool button_press (GdkEventButton *);
- bool prompter_hiding (GdkEventAny *);
- void midicontrol_prompt ();
- void midicontrol_unprompt ();
- void update_midi_control ();
};
class VSliderController : public SliderController
@@ -83,7 +67,7 @@ class VSliderController : public SliderController
VSliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment *adj,
- MIDI::Controllable *,
+ PBD::Controllable&,
bool with_numeric = true);
};
@@ -93,11 +77,11 @@ class HSliderController : public SliderController
HSliderController (Glib::RefPtr<Gdk::Pixbuf> slider,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment *adj,
- MIDI::Controllable *,
+ PBD::Controllable&,
bool with_numeric = true);
};
}; /* namespace */
-#endif // __gtkmm2ext_motion_controller_h__
+#endif // __gtkmm2ext_slider_controller_h__
diff --git a/libs/gtkmm2ext/pathlist.cc b/libs/gtkmm2ext/pathlist.cc
new file mode 100644
index 0000000000..7b3448ed5f
--- /dev/null
+++ b/libs/gtkmm2ext/pathlist.cc
@@ -0,0 +1,124 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <gtkmm2ext/pathlist.h>
+
+#include "i18n.h"
+
+using namespace std;
+using namespace Gtkmm2ext;
+
+PathList::PathList ()
+ :
+ add_btn(_("+")),
+ subtract_btn(_("-")),
+ path_columns(),
+ _store(Gtk::ListStore::create(path_columns)),
+ _view(_store)
+{
+ _view.append_column(_("Paths"), path_columns.paths);
+ _view.set_size_request(-1, 100);
+ _view.set_headers_visible (false);
+
+ Gtk::ScrolledWindow* scroll = manage(new Gtk::ScrolledWindow);
+ scroll->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
+ scroll->add(_view);
+
+ add (*scroll);
+
+ Gtk::HBox* btn_box = manage(new Gtk::HBox);
+ btn_box->add(add_btn);
+ btn_box->add(subtract_btn);
+
+ add (*btn_box);
+
+ add_btn.signal_clicked().connect (mem_fun(*this, &PathList::add_btn_clicked));
+ subtract_btn.signal_clicked().connect (mem_fun(*this, &PathList::subtract_btn_clicked));
+ _view.get_selection()->signal_changed().connect (mem_fun(*this, &PathList::selection_changed));
+}
+
+vector<string>
+PathList::get_paths ()
+{
+ vector<string> paths;
+
+ Gtk::TreeModel::Children children(_store->children());
+
+ for (Gtk::TreeIter iter = children.begin(); iter != children.end(); ++iter) {
+ Gtk::ListStore::Row row = *iter;
+
+ paths.push_back(row[path_columns.paths]);
+ }
+
+ return paths;
+}
+
+void
+PathList::set_paths (vector<string> paths)
+{
+ _store->clear();
+
+ for (vector<string>::iterator i = paths.begin(); i != paths.end(); ++i) {
+ Gtk::ListStore::iterator iter = _store->append();
+ Gtk::ListStore::Row row = *iter;
+ row[path_columns.paths] = *i;
+ }
+}
+
+void
+PathList::add_btn_clicked ()
+{
+ Gtk::FileChooserDialog path_chooser (_("Path Chooser"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER);
+
+ path_chooser.add_button (Gtk::Stock::ADD, Gtk::RESPONSE_OK);
+ path_chooser.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+
+ int result = path_chooser.run ();
+
+ if (result == Gtk::RESPONSE_OK) {
+ string pathname = path_chooser.get_filename();
+
+ if (pathname.length ()) {
+ Gtk::ListStore::iterator iter = _store->append ();
+ Gtk::ListStore::Row row = *iter;
+ row[path_columns.paths] = pathname;
+
+ PathsUpdated (); // EMIT_SIGNAL
+ }
+ }
+}
+
+void
+PathList::subtract_btn_clicked ()
+{
+ Gtk::ListStore::iterator iter = _view.get_selection()->get_selected();
+ _store->erase (iter);
+
+ PathsUpdated (); // EMIT_SIGNAL
+}
+
+void
+PathList::selection_changed ()
+{
+ if (_view.get_selection()->count_selected_rows ()) {
+ subtract_btn.set_sensitive (true);
+ } else {
+ subtract_btn.set_sensitive (false);
+ }
+}
diff --git a/libs/gtkmm2ext/popup.cc b/libs/gtkmm2ext/popup.cc
index 0a48ebfc59..a8ffc4af66 100644
--- a/libs/gtkmm2ext/popup.cc
+++ b/libs/gtkmm2ext/popup.cc
@@ -73,11 +73,12 @@ PopUp::remove ()
{
hide ();
+ if (popdown_time != 0 && timeout != -1) {
+ gtk_timeout_remove (timeout);
+ }
+
if (delete_on_hide) {
std::cerr << "deleting prompter\n";
- if (popdown_time != 0 && timeout != -1) {
- gtk_timeout_remove (timeout);
- }
gtk_idle_add (idle_delete, this);
}
}
@@ -125,11 +126,12 @@ PopUp::on_delete_event (GdkEventAny* ev)
{
hide();
+ if (popdown_time != 0 && timeout != -1) {
+ gtk_timeout_remove (timeout);
+ }
+
if (delete_on_hide) {
std::cerr << "deleting prompter\n" << endl;
- if (popdown_time != 0 && timeout != -1) {
- gtk_timeout_remove (timeout);
- }
gtk_idle_add (idle_delete, this);
}
diff --git a/libs/gtkmm2ext/slider_controller.cc b/libs/gtkmm2ext/slider_controller.cc
index 734d5eb62f..e524eba1cb 100644
--- a/libs/gtkmm2ext/slider_controller.cc
+++ b/libs/gtkmm2ext/slider_controller.cc
@@ -18,47 +18,30 @@
*/
#include <string>
-#include <climits>
-
-#include <midi++/controllable.h>
#include <gtkmm2ext/gtk_ui.h>
-#include <gtkmm2ext/slider_controller.h>
#include <gtkmm2ext/pixscroller.h>
+#include <gtkmm2ext/slider_controller.h>
#include "i18n.h"
using namespace Gtkmm2ext;
+using namespace PBD;
SliderController::SliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment *adj,
- MIDI::Controllable *mc,
+ Controllable& c,
bool with_numeric)
: PixScroller (*adj, slide, rail),
- spin (*adj, 0, 2),
- prompter (Gtk::WIN_POS_MOUSE, 30000, false),
- midi_control (mc),
- bind_button (2),
- bind_statemask (Gdk::CONTROL_MASK)
-
+ binding_proxy (c),
+ spin (*adj, 0, 2)
{
- signal_button_press_event().connect (mem_fun (this, &SliderController::button_press));
spin.set_name ("SliderControllerValue");
spin.set_size_request (70,-1); // should be based on font size somehow
spin.set_numeric (true);
spin.set_snap_to_ticks (false);
-
- prompter.signal_unmap_event().connect (mem_fun (*this, &SliderController::prompter_hiding));
-
- prompting = false;
- unprompting = false;
-
- if (mc) {
- mc->learning_started.connect (mem_fun (*this, &SliderController::midicontrol_prompt));
- mc->learning_stopped.connect (mem_fun (*this, &SliderController::midicontrol_unprompt));
- }
}
void
@@ -67,95 +50,22 @@ SliderController::set_value (float v)
adj.set_value (v);
}
-void
-SliderController::set_bind_button_state (guint button, guint statemask)
-{
- bind_button = button;
- bind_statemask = statemask;
-}
-
-void
-SliderController::get_bind_button_state (guint &button, guint &statemask)
-{
- button = bind_button;
- statemask = bind_statemask;
-}
-
-void
-SliderController::midi_learn()
-{
- if (midi_control) {
- prompting = true;
- midi_control->learn_about_external_control ();
- }
-}
-
-bool
-SliderController::button_press (GdkEventButton *ev)
+bool
+SliderController::on_button_press_event (GdkEventButton *ev)
{
- if ((ev->state & bind_statemask) && ev->button == bind_button) {
- midi_learn ();
+ if (binding_proxy.button_press_handler (ev)) {
return true;
}
-
- return false;
-}
-
-void
-SliderController::midicontrol_set_tip ()
-
-{
- if (midi_control) {
- // Gtkmm2ext::UI::instance()->set_tip (this, midi_control->control_description());
- }
-}
-
-bool
-SliderController::prompter_hiding (GdkEventAny *ev)
-{
- if (unprompting) {
- if (midi_control) {
- midi_control->stop_learning();
- }
- unprompting = false;
- }
-
- return false;
-}
-
-void
-SliderController::midicontrol_prompt ()
-
-{
- if (prompting) {
-
- string prompt = _("operate MIDI controller now");
- prompter.set_text (prompt);
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
-
- unprompting = true;
- prompting = false;
- }
-}
-
-void
-SliderController::midicontrol_unprompt ()
-
-{
- if (unprompting) {
- Gtkmm2ext::UI::instance()->touch_display (&prompter);
- unprompting = false;
- }
+ return PixScroller::on_button_press_event (ev);
}
-
VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment *adj,
- MIDI::Controllable *mcontrol,
+ Controllable& control,
bool with_numeric)
- : SliderController (slide, rail, adj, mcontrol, with_numeric)
+ : SliderController (slide, rail, adj, control, with_numeric)
{
if (with_numeric) {
spin_frame.add (spin);
@@ -169,10 +79,10 @@ VSliderController::VSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
HSliderController::HSliderController (Glib::RefPtr<Gdk::Pixbuf> slide,
Glib::RefPtr<Gdk::Pixbuf> rail,
Gtk::Adjustment *adj,
- MIDI::Controllable *mcontrol,
+ Controllable& control,
bool with_numeric)
- : SliderController (slide, rail, adj, mcontrol, with_numeric)
+ : SliderController (slide, rail, adj, control, with_numeric)
{
if (with_numeric) {
spin_frame.add (spin);
diff --git a/libs/libgnomecanvasmm/SConscript b/libs/libgnomecanvasmm/SConscript
index 1d5f3e0050..d9620dc378 100644
--- a/libs/libgnomecanvasmm/SConscript
+++ b/libs/libgnomecanvasmm/SConscript
@@ -8,7 +8,14 @@ gnomecanvasmm_files = glob.glob('libgnomecanvasmm/*.cc')
Import('env libraries install_prefix')
gnomecanvasmm = env.Copy()
-gnomecanvasmm.Merge([libraries['glibmm2'], libraries['gtk2'], libraries['sigc2'], libraries['pangomm'], libraries['atkmm'], libraries['gdkmm2'], libraries['gtkmm2'], libraries['libgnomecanvas2'] ])
+gnomecanvasmm.Merge([libraries['glibmm2'],
+ libraries['gtk2'],
+ libraries['sigc2'],
+ libraries['pangomm'],
+ libraries['atkmm'],
+ libraries['gdkmm2'],
+ libraries['gtkmm2'],
+ libraries['libgnomecanvas2'] ])
libgnomecanvasmm = gnomecanvasmm.SharedLibrary('libgnomecanvasmm', gnomecanvasmm_files)
Default(libgnomecanvasmm)
diff --git a/libs/libsndfile/src/sndfile.c b/libs/libsndfile/src/sndfile.c
index 47b74cfd7f..14586526e4 100644
--- a/libs/libsndfile/src/sndfile.c
+++ b/libs/libsndfile/src/sndfile.c
@@ -1065,20 +1065,19 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize)
memcpy (data, psf->loop_info, sizeof (SF_LOOP_INFO)) ;
return SF_TRUE ;
- case SFC_SET_BROADCAST_INFO :
- { int format = psf->sf.format & SF_FORMAT_TYPEMASK ;
+ case SFC_SET_BROADCAST_INFO : {
+ int format = psf->sf.format & SF_FORMAT_TYPEMASK ;
- /* Only WAV supports the BEXT (Broadcast) chunk. */
- if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
- return SF_FALSE ;
- } ;
+ /* Only WAV supports the BEXT (Broadcast) chunk. */
+ if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
+ return SF_FALSE ;
/* Can only do this is in SFM_RDWR or SFM_WRITE modes. */
if (psf->mode == SFM_READ)
return SF_FALSE ;
/* If data has already been written this must fail. */
- if (psf->broadcast_info == NULL && psf->have_written)
+ if (psf->broadcast_info == NULL && psf->have_written)
return SF_FALSE ;
if (psf->broadcast_info == NULL)
@@ -1089,7 +1088,9 @@ sf_command (SNDFILE *sndfile, int command, void *data, int datasize)
if (psf->auto_header && psf->write_header)
psf->write_header (psf, SF_TRUE) ;
+
return SF_TRUE ;
+ }
case SFC_GET_BROADCAST_INFO :
if (datasize != sizeof (SF_BROADCAST_INFO) || data == NULL)
diff --git a/libs/midi++2/SConscript b/libs/midi++2/SConscript
index 928372909c..696fed6b5b 100644
--- a/libs/midi++2/SConscript
+++ b/libs/midi++2/SConscript
@@ -7,7 +7,7 @@ import glob
Import('env libraries install_prefix')
midi2 = env.Copy()
-midi2.Merge([ libraries['sigc2'], libraries['xml'], libraries['glib2'], libraries['pbd3'] ])
+midi2.Merge([ libraries['sigc2'], libraries['xml'], libraries['glib2'], libraries['pbd'] ])
domain = 'midipp'
@@ -18,7 +18,6 @@ fd_midiport.cc
fifomidi.cc
midi.cc
midichannel.cc
-midicontrollable.cc
midifactory.cc
midimanager.cc
midiparser.cc
diff --git a/libs/midi++2/midi++/channel.h b/libs/midi++2/midi++/channel.h
index 1efde3cb93..f8dbb6e194 100644
--- a/libs/midi++2/midi++/channel.h
+++ b/libs/midi++2/midi++/channel.h
@@ -152,7 +152,7 @@ class Channel : public sigc::trackable {
void process_reset (Parser &);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midichannel_h__
diff --git a/libs/midi++2/midi++/controllable.h b/libs/midi++2/midi++/controllable.h
deleted file mode 100644
index 3fa108bb46..0000000000
--- a/libs/midi++2/midi++/controllable.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- Copyright (C) 1998-99 Paul Barton-Davis
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
-*/
-
-#ifndef __qm_midicontrollable_h__
-#define __qm_midicontrollable_h__
-
-#include <string>
-
-#include <sigc++/sigc++.h>
-
-#include <midi++/types.h>
-
-namespace MIDI {
-
-class Channel;
-class Port;
-class Parser;
-
-class Controllable : public sigc::trackable
-{
- public:
- Controllable (Port *, bool bistate = false);
- virtual ~Controllable ();
-
- void midi_rebind (Port *, channel_t channel=-1);
- void midi_forget ();
- void learn_about_external_control ();
- void stop_learning ();
- void drop_external_control ();
-
- virtual void set_value (float) = 0;
-
- sigc::signal<void> learning_started;
- sigc::signal<void> learning_stopped;
-
- bool get_control_info (channel_t&, eventType&, byte&);
- void set_control_type (channel_t, eventType, byte);
-
- bool get_midi_feedback () { return feedback; }
- void set_midi_feedback (bool val) { feedback = val; }
-
- Port * get_port() { return port; }
-
- std::string control_description() const { return _control_description; }
-
- void send_midi_feedback (float);
-
- private:
- bool bistate;
- int midi_msg_id; /* controller ID or note number */
- sigc::connection midi_sense_connection[2];
- sigc::connection midi_learn_connection;
- size_t connections;
- Port* port;
- eventType control_type;
- byte control_additional;
- channel_t control_channel;
- std::string _control_description;
- bool feedback;
-
- void midi_receiver (Parser &p, byte *, size_t);
- void midi_sense_note (Parser &, EventTwoBytes *, bool is_on);
- void midi_sense_note_on (Parser &p, EventTwoBytes *tb);
- void midi_sense_note_off (Parser &p, EventTwoBytes *tb);
- void midi_sense_controller (Parser &, EventTwoBytes *);
- void midi_sense_program_change (Parser &, byte);
- void midi_sense_pitchbend (Parser &, pitchbend_t);
-
- void bind_midi (channel_t, eventType, byte);
-};
-
-}; /* namespace MIDI */
-
-#endif // __qm_midicontrollable_h__
-
diff --git a/libs/midi++2/midi++/coremidi_midiport.h b/libs/midi++2/midi++/coremidi_midiport.h
index e02a225784..d7df23aa04 100644
--- a/libs/midi++2/midi++/coremidi_midiport.h
+++ b/libs/midi++2/midi++/coremidi_midiport.h
@@ -62,6 +62,6 @@ namespace MIDI {
bool firstrecv;
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __coremidi_midiport_h__
diff --git a/libs/midi++2/midi++/factory.h b/libs/midi++2/midi++/factory.h
index 1543f68cdc..7b4122d791 100644
--- a/libs/midi++2/midi++/factory.h
+++ b/libs/midi++2/midi++/factory.h
@@ -35,6 +35,6 @@ class PortFactory {
const std::string &reqstr);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midi_factory_h__
diff --git a/libs/midi++2/midi++/fd_midiport.h b/libs/midi++2/midi++/fd_midiport.h
index 853af9d7b4..6a9b8f74d1 100644
--- a/libs/midi++2/midi++/fd_midiport.h
+++ b/libs/midi++2/midi++/fd_midiport.h
@@ -89,6 +89,6 @@ class FD_MidiPort : public Port
int do_slow_write (byte *msg, unsigned int msglen);
};
-}; /*namespace MIDI */
+} // namespace MIDI
#endif // __fd_midiport_h__
diff --git a/libs/midi++2/midi++/fifomidi.h b/libs/midi++2/midi++/fifomidi.h
index eb8778d4d5..200d90eda8 100644
--- a/libs/midi++2/midi++/fifomidi.h
+++ b/libs/midi++2/midi++/fifomidi.h
@@ -42,6 +42,6 @@ class FIFO_MidiPort : public MIDI::FD_MidiPort
void open (PortRequest &req);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __fifomidi_h__
diff --git a/libs/midi++2/midi++/manager.h b/libs/midi++2/midi++/manager.h
index 4889aad8c9..1bf8dc7cbd 100644
--- a/libs/midi++2/midi++/manager.h
+++ b/libs/midi++2/midi++/manager.h
@@ -83,6 +83,6 @@ class Manager {
void close_ports ();
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midi_manager_h__
diff --git a/libs/midi++2/midi++/mmc.h b/libs/midi++2/midi++/mmc.h
index 7b51b33a72..2d569f122c 100644
--- a/libs/midi++2/midi++/mmc.h
+++ b/libs/midi++2/midi++/mmc.h
@@ -82,7 +82,7 @@ class MachineControl : public sigc::trackable
cmdRecordStrobeVariable = 0x55,
cmdWait = 0x7C,
- cmdResume = 0x7F,
+ cmdResume = 0x7F
};
MachineControl (Port &port,
@@ -256,6 +256,6 @@ class MachineControl : public sigc::trackable
void write_track_record_ready (byte *, size_t len);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif /* __midipp_mmc_h_h__ */
diff --git a/libs/midi++2/midi++/nullmidi.h b/libs/midi++2/midi++/nullmidi.h
index a94b1015b0..a74e5e3d9b 100644
--- a/libs/midi++2/midi++/nullmidi.h
+++ b/libs/midi++2/midi++/nullmidi.h
@@ -57,6 +57,6 @@ class Null_MidiPort : public Port
virtual int selectable() const { return -1; }
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __nullmidi_h__
diff --git a/libs/midi++2/midi++/parser.h b/libs/midi++2/midi++/parser.h
index 4ac07cc15d..36d19f3da9 100644
--- a/libs/midi++2/midi++/parser.h
+++ b/libs/midi++2/midi++/parser.h
@@ -183,7 +183,7 @@ class Parser : public sigc::trackable {
void process_mtc_quarter_frame (byte *msg);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midi_parse_h__
diff --git a/libs/midi++2/midi++/port.h b/libs/midi++2/midi++/port.h
index a186f1fd5f..4a5319b120 100644
--- a/libs/midi++2/midi++/port.h
+++ b/libs/midi++2/midi++/port.h
@@ -40,7 +40,7 @@ class Port : public sigc::trackable {
ALSA_Sequencer,
CoreMidi_MidiPort,
Null,
- FIFO,
+ FIFO
};
@@ -140,7 +140,6 @@ class Port : public sigc::trackable {
static size_t nports;
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __libmidi_port_h__
-
diff --git a/libs/midi++2/midi++/port_request.h b/libs/midi++2/midi++/port_request.h
index 28a0d1d70b..86838dd04d 100644
--- a/libs/midi++2/midi++/port_request.h
+++ b/libs/midi++2/midi++/port_request.h
@@ -54,7 +54,7 @@ struct PortRequest {
const std::string &xtype);
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midi_port_request_h__
diff --git a/libs/midi++2/midi++/types.h b/libs/midi++2/midi++/types.h
index b9d9bf33e7..218416d213 100644
--- a/libs/midi++2/midi++/types.h
+++ b/libs/midi++2/midi++/types.h
@@ -57,10 +57,10 @@ namespace MIDI {
enum MTC_Status {
MTC_Stopped = 0,
MTC_Forward,
- MTC_Backward,
+ MTC_Backward
};
-}; /* namespace MIDI */
+} // namespace MIDI
#endif // __midi_types_h__
diff --git a/libs/midi++2/midiparser.cc b/libs/midi++2/midiparser.cc
index 04ac2728f1..424bfa04f8 100644
--- a/libs/midi++2/midiparser.cc
+++ b/libs/midi++2/midiparser.cc
@@ -101,7 +101,7 @@ Parser::midi_event_type_name (eventType t)
default:
return "unknow MIDI event type";
}
-};
+}
Parser::Parser (Port &p)
: _port (p)
diff --git a/libs/pbd3/.cvsignore b/libs/pbd/.cvsignore
index e9a15e81e9..e9a15e81e9 100644
--- a/libs/pbd3/.cvsignore
+++ b/libs/pbd/.cvsignore
diff --git a/libs/pbd3/AUTHORS b/libs/pbd/AUTHORS
index e69de29bb2..e69de29bb2 100644
--- a/libs/pbd3/AUTHORS
+++ b/libs/pbd/AUTHORS
diff --git a/libs/pbd3/COPYING b/libs/pbd/COPYING
index d60c31a97a..d60c31a97a 100644
--- a/libs/pbd3/COPYING
+++ b/libs/pbd/COPYING
diff --git a/libs/pbd3/ChangeLog b/libs/pbd/ChangeLog
index 59e92915ba..59e92915ba 100644
--- a/libs/pbd3/ChangeLog
+++ b/libs/pbd/ChangeLog
diff --git a/libs/pbd3/NEWS b/libs/pbd/NEWS
index e69de29bb2..e69de29bb2 100644
--- a/libs/pbd3/NEWS
+++ b/libs/pbd/NEWS
diff --git a/libs/pbd3/README b/libs/pbd/README
index e69de29bb2..e69de29bb2 100644
--- a/libs/pbd3/README
+++ b/libs/pbd/README
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
new file mode 100644
index 0000000000..4b15dd70d1
--- /dev/null
+++ b/libs/pbd/SConscript
@@ -0,0 +1,75 @@
+# -*- python -*-
+
+import os
+import os.path
+import glob
+
+Import('env libraries i18n install_prefix')
+
+pbd = env.Copy()
+
+domain = 'libpbd'
+
+pbd.Append(DOMAIN=domain,MAJOR=4,MINOR=1,MICRO=0)
+pbd.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"")
+pbd.Append(CXXFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
+pbd.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
+pbd.Append(PACKAGE=domain)
+pbd.Append(POTFILE=domain + '.pot')
+
+pbd_files = Split("""
+basename.cc
+base_ui.cc
+convert.cc
+command.cc
+controllable.cc
+dmalloc.cc
+error.cc
+id.cc
+mountpoint.cc
+path.cc
+pathscanner.cc
+pool.cc
+pthread_utils.cc
+receiver.cc
+stacktrace.cc
+stateful.cc
+strsplit.cc
+textreceiver.cc
+transmitter.cc
+undo.cc
+version.cc
+whitespace.cc
+xml++.cc
+""")
+
+conf = Configure(pbd)
+if conf.CheckFunc('getmntent'):
+ conf.env.Append(CCFLAGS="-DHAVE_GETMNTENT")
+if conf.CheckCHeader('execinfo.h'):
+ conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO")
+pbd = conf.Finish()
+
+pbd.Merge ([ libraries['sigc2'],
+ libraries['xml'],
+ libraries['glibmm2'],
+ libraries['glib2'] ])
+
+pbd.VersionBuild(['version.cc','pbd/version.h'], 'SConscript')
+
+libpbd = pbd.SharedLibrary('pbd', pbd_files)
+Default(libpbd)
+
+mount_env = Environment(CCFLAGS='-DTEST_MOUNTPOINT -Ilibs/pbd')
+mount_env.Program('mountpoint', 'mountpoint.cc')
+
+if env['NLS']:
+ i18n (pbd, pbd_files, env)
+
+env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd))
+
+env.Alias('tarball', env.Distribute (env['DISTTREE'],
+ [ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] +
+ pbd_files +
+ glob.glob('po/*.po') +
+ glob.glob('pbd/*.h')))
diff --git a/libs/pbd3/base_ui.cc b/libs/pbd/base_ui.cc
index d3c8d5e4c7..d3c8d5e4c7 100644
--- a/libs/pbd3/base_ui.cc
+++ b/libs/pbd/base_ui.cc
diff --git a/libs/pbd3/basename.cc b/libs/pbd/basename.cc
index a51e393b78..a51e393b78 100644
--- a/libs/pbd3/basename.cc
+++ b/libs/pbd/basename.cc
diff --git a/libs/pbd3/command.cc b/libs/pbd/command.cc
index 3f5aca8e51..3f5aca8e51 100644
--- a/libs/pbd3/command.cc
+++ b/libs/pbd/command.cc
diff --git a/libs/pbd/controllable.cc b/libs/pbd/controllable.cc
new file mode 100644
index 0000000000..b1176c64a5
--- /dev/null
+++ b/libs/pbd/controllable.cc
@@ -0,0 +1,26 @@
+#include <pbd/controllable.h>
+#include <pbd/xml++.h>
+
+#include "i18n.h"
+
+using namespace PBD;
+
+sigc::signal<void,Controllable*> Controllable::Created;
+sigc::signal<void,Controllable*> Controllable::GoingAway;
+sigc::signal<bool,Controllable*> Controllable::StartLearning;
+sigc::signal<void,Controllable*> Controllable::StopLearning;
+
+Controllable::Controllable ()
+{
+ Created (this);
+}
+
+XMLNode&
+Controllable::get_state ()
+{
+ XMLNode* node = new XMLNode (X_("Controllable"));
+ char buf[64];
+ _id.print (buf);
+ node->add_property (X_("id"), buf);
+ return *node;
+}
diff --git a/libs/pbd3/convert.cc b/libs/pbd/convert.cc
index 60d39c91e2..60d39c91e2 100644
--- a/libs/pbd3/convert.cc
+++ b/libs/pbd/convert.cc
diff --git a/libs/pbd3/dmalloc.cc b/libs/pbd/dmalloc.cc
index 0e730946c8..0e730946c8 100644
--- a/libs/pbd3/dmalloc.cc
+++ b/libs/pbd/dmalloc.cc
diff --git a/libs/pbd3/error.cc b/libs/pbd/error.cc
index a6f8fb7f8f..a6f8fb7f8f 100644
--- a/libs/pbd3/error.cc
+++ b/libs/pbd/error.cc
diff --git a/libs/pbd3/gettext.h b/libs/pbd/gettext.h
index 339c74ffe7..339c74ffe7 100644
--- a/libs/pbd3/gettext.h
+++ b/libs/pbd/gettext.h
diff --git a/libs/pbd3/i18n.h b/libs/pbd/i18n.h
index 7c79d2eb53..7c79d2eb53 100644
--- a/libs/pbd3/i18n.h
+++ b/libs/pbd/i18n.h
diff --git a/libs/pbd/id.cc b/libs/pbd/id.cc
new file mode 100644
index 0000000000..f9afa72c98
--- /dev/null
+++ b/libs/pbd/id.cc
@@ -0,0 +1,63 @@
+#include <ostream>
+#include <iostream>
+#include <stdio.h>
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#include <inttypes.h>
+
+#include <pbd/id.h>
+
+using namespace std;
+using namespace PBD;
+
+Glib::Mutex* ID::counter_lock = 0;
+uint64_t ID::_counter = 0;
+
+void
+ID::init ()
+{
+ counter_lock = new Glib::Mutex;
+}
+
+ID::ID ()
+{
+ Glib::Mutex::Lock lm (*counter_lock);
+ id = _counter++;
+}
+
+ID::ID (string str)
+{
+ string_assign (str);
+}
+
+int
+ID::string_assign (string str)
+{
+ return sscanf (str.c_str(), "%" PRIu64, &id) != 0;
+}
+
+void
+ID::print (char* buf) const
+{
+ /* XXX sizeof buf is unknown. bad API design */
+ snprintf (buf, 16, "%" PRIu64, id);
+}
+
+ID&
+ID::operator= (string str)
+{
+ string_assign (str);
+ return *this;
+}
+
+ostream&
+operator<< (ostream& ostr, const ID& id)
+{
+ char buf[32];
+ id.print (buf);
+ ostr << buf;
+ return ostr;
+}
+
diff --git a/libs/pbd3/libpbd.pc.in b/libs/pbd/libpbd.pc.in
index 14d0208845..14d0208845 100644
--- a/libs/pbd3/libpbd.pc.in
+++ b/libs/pbd/libpbd.pc.in
diff --git a/libs/pbd3/libpbd.spec.in b/libs/pbd/libpbd.spec.in
index d50622d638..d50622d638 100644
--- a/libs/pbd3/libpbd.spec.in
+++ b/libs/pbd/libpbd.spec.in
diff --git a/libs/pbd3/mountpoint.cc b/libs/pbd/mountpoint.cc
index 160f5e921c..c1bcb375f3 100644
--- a/libs/pbd3/mountpoint.cc
+++ b/libs/pbd/mountpoint.cc
@@ -88,7 +88,7 @@ mountpoint (string path)
return best;
}
-#else // no getmntent()
+#else // !HAVE_GETMNTENT
#include <sys/param.h>
#include <sys/ucred.h>
@@ -97,10 +97,55 @@ mountpoint (string path)
string
mountpoint (string path)
{
-//XXX IMPLEMENT ME using getmntinfo() or getfsstat().
- return "/";
+ struct statfs *mntbufp = 0;
+ int count;
+ unsigned int maxmatch = 0;
+ unsigned int matchlen;
+ const char *cpath = path.c_str();
+ char best[PATH_MAX+1];
+
+ if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) {
+ free(mntbufp);
+ return "\0";
+ }
+
+ best[0] = '\0';
+
+ for (int i = 0; i < count; ++i) {
+ unsigned int n = 0;
+ matchlen = 0;
+
+ /* note: strcmp's semantics are not
+ strict enough to use for this.
+ */
+
+ while (cpath[n] && mntbufp[i].f_mntonname[n]) {
+ if (cpath[n] != mntbufp[i].f_mntonname[n]) {
+ break;
+ }
+ matchlen++;
+ n++;
+ }
+
+ if (cpath[matchlen] == '\0') {
+ snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ free(mntbufp);
+ return best;
+
+ } else {
+
+ if (matchlen > maxmatch) {
+ snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname);
+ maxmatch = matchlen;
+ }
+ }
+ }
+
+ free(mntbufp);
+
+ return best;
}
-#endif
+#endif // HAVE_GETMNTENT
#ifdef TEST_MOUNTPOINT
@@ -110,4 +155,4 @@ main (int argc, char *argv[])
exit (0);
}
-#endif
+#endif // TEST_MOUNTPOINT
diff --git a/libs/pbd/path.cc b/libs/pbd/path.cc
new file mode 100644
index 0000000000..80f916c9ae
--- /dev/null
+++ b/libs/pbd/path.cc
@@ -0,0 +1,164 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#include <cerrno>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include <glibmm/miscutils.h>
+#include <glibmm/fileutils.h>
+
+#include <pbd/path.h>
+#include <pbd/tokenizer.h>
+
+namespace PBD {
+
+Path::Path ()
+{
+
+}
+
+Path::Path (const string& path)
+{
+ vector<string> tmp;
+
+ if(!tokenize ( path, string(":;"), std::back_inserter (tmp))) {
+ g_warning ("%s : %s\n", G_STRLOC, G_STRFUNC);
+ return;
+ }
+
+ add_readable_directories (tmp);
+}
+
+Path::Path (const vector<string>& paths)
+{
+ add_readable_directories (paths);
+}
+
+Path::Path (const Path& other)
+ : m_dirs(other.m_dirs)
+{
+
+}
+
+bool
+Path::readable_directory (const string& directory_path)
+{
+ if (g_access (directory_path.c_str(), R_OK) == 0) {
+ if (Glib::file_test(directory_path, Glib::FILE_TEST_IS_DIR)) {
+ return true;
+ } else {
+ g_warning (" %s : Path exists but is not a directory\n", G_STRLOC);
+ }
+ } else {
+ g_warning ("%s : %s : %s\n", G_STRLOC, directory_path.c_str(), g_strerror(errno));
+ }
+ return false;
+}
+
+void
+Path::add_readable_directory (const string& directory_path)
+{
+ if(readable_directory(directory_path)) {
+ m_dirs.push_back(directory_path);
+ }
+}
+
+void
+Path::add_readable_directories (const vector<string>& paths)
+{
+ for(vector<string>::const_iterator i = paths.begin(); i != paths.end(); ++i) {
+ add_readable_directory (*i);
+ }
+}
+
+const string
+Path::path_string() const
+{
+ string path;
+
+ for (vector<string>::const_iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) {
+ path += (*i);
+ path += G_SEARCHPATH_SEPARATOR;
+ }
+
+ g_message ("%s : %s", G_STRLOC, path.c_str());
+
+ return path.substr (0, path.length() - 1); // drop final colon
+}
+
+const Path&
+Path::operator= (const Path& path)
+{
+ m_dirs = path.m_dirs;
+ return *this;
+}
+
+const Path&
+Path::operator+= (const string& directory_path)
+{
+ add_readable_directory (directory_path);
+ return *this;
+}
+
+const Path
+operator+ (const Path& lhs_path, const Path& rhs_path)
+{
+ Path tmp_path(lhs_path); // does this do what I think it does.
+ // concatenate paths into new Path
+ tmp_path.m_dirs.insert(tmp_path.m_dirs.end(), rhs_path.m_dirs.begin(), rhs_path.m_dirs.end());
+ return tmp_path;
+}
+
+Path&
+Path::add_subdirectory_to_path (const string& subdir)
+{
+ vector<string> tmp;
+ string directory_path;
+
+ for (vector<string>::iterator i = m_dirs.begin(); i != m_dirs.end(); ++i) {
+ directory_path = Glib::build_filename (*i, subdir);
+ if(readable_directory(directory_path)) {
+ tmp.push_back(directory_path);
+ }
+ }
+ m_dirs = tmp;
+ return *this;
+}
+
+bool
+find_file_in_path (const Path& path, const string& filename, string& resulting_path)
+{
+ for (vector<string>::const_iterator i = path.dirs().begin(); i != path.dirs().end(); ++i) {
+ resulting_path = Glib::build_filename ((*i), filename);
+ if (g_access (resulting_path.c_str(), R_OK) == 0) {
+ g_message ("File %s found in Path : %s\n", resulting_path.c_str(),
+ path.path_string().c_str());
+ return true;
+ }
+ }
+
+ g_warning ("%s : Could not locate file %s in path %s\n", G_STRLOC, filename.c_str(),
+ path.path_string().c_str());
+
+ return false;
+}
+
+} // namespace PBD
+
diff --git a/libs/pbd3/pathscanner.cc b/libs/pbd/pathscanner.cc
index 2af227a3a0..2af227a3a0 100644
--- a/libs/pbd3/pathscanner.cc
+++ b/libs/pbd/pathscanner.cc
diff --git a/libs/pbd3/pbd/.DS_Store b/libs/pbd/pbd/.DS_Store
index 5008ddfcf5..5008ddfcf5 100644
--- a/libs/pbd3/pbd/.DS_Store
+++ b/libs/pbd/pbd/.DS_Store
Binary files differ
diff --git a/libs/pbd3/pbd/.cvsignore b/libs/pbd/pbd/.cvsignore
index 67020331ba..67020331ba 100644
--- a/libs/pbd3/pbd/.cvsignore
+++ b/libs/pbd/pbd/.cvsignore
diff --git a/libs/pbd3/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc
index 0e34787a2d..0e34787a2d 100644
--- a/libs/pbd3/pbd/abstract_ui.cc
+++ b/libs/pbd/pbd/abstract_ui.cc
diff --git a/libs/pbd3/pbd/abstract_ui.h b/libs/pbd/pbd/abstract_ui.h
index f80db7bf1a..f80db7bf1a 100644
--- a/libs/pbd3/pbd/abstract_ui.h
+++ b/libs/pbd/pbd/abstract_ui.h
diff --git a/libs/pbd3/pbd/base_ui.h b/libs/pbd/pbd/base_ui.h
index b4570f8707..b4570f8707 100644
--- a/libs/pbd3/pbd/base_ui.h
+++ b/libs/pbd/pbd/base_ui.h
diff --git a/libs/pbd3/pbd/basename.h b/libs/pbd/pbd/basename.h
index 35aebe166c..a7e36acff0 100644
--- a/libs/pbd3/pbd/basename.h
+++ b/libs/pbd/pbd/basename.h
@@ -8,6 +8,6 @@ namespace PBD
extern std::string basename_nosuffix (const std::string&);
-};
+} // namespace PBD
#endif // __stupid_basename_h__
diff --git a/libs/pbd3/pbd/command.h b/libs/pbd/pbd/command.h
index 35ae011530..35ae011530 100644
--- a/libs/pbd3/pbd/command.h
+++ b/libs/pbd/pbd/command.h
diff --git a/libs/pbd3/pbd/compose.h b/libs/pbd/pbd/compose.h
index 0df9519aaf..0df9519aaf 100644
--- a/libs/pbd3/pbd/compose.h
+++ b/libs/pbd/pbd/compose.h
diff --git a/libs/pbd/pbd/controllable.h b/libs/pbd/pbd/controllable.h
new file mode 100644
index 0000000000..c46e477b6e
--- /dev/null
+++ b/libs/pbd/pbd/controllable.h
@@ -0,0 +1,46 @@
+#ifndef __pbd_controllable_h__
+#define __pbd_controllable_h__
+
+#include <sigc++/trackable.h>
+#include <sigc++/signal.h>
+
+#include <pbd/stateful.h>
+#include <pbd/id.h>
+
+class XMLNode;
+
+namespace PBD {
+
+class Controllable : public virtual sigc::trackable, public Stateful {
+ public:
+ Controllable ();
+ virtual ~Controllable() { GoingAway (this); }
+
+ virtual void set_value (float) = 0;
+ virtual float get_value (void) const = 0;
+
+ virtual bool can_send_feedback() const { return true; }
+
+ sigc::signal<void> LearningFinished;
+
+ static sigc::signal<void,Controllable*> Created;
+ static sigc::signal<void,Controllable*> GoingAway;
+
+
+ static sigc::signal<bool,PBD::Controllable*> StartLearning;
+ static sigc::signal<void,PBD::Controllable*> StopLearning;
+
+ sigc::signal<void> Changed;
+
+ const PBD::ID& id() const { return _id; }
+
+ int set_state (const XMLNode&) { return 0; }
+ XMLNode& get_state ();
+
+ private:
+ PBD::ID _id;
+};
+
+}
+
+#endif /* __pbd_controllable_h__ */
diff --git a/libs/pbd3/pbd/convert.h b/libs/pbd/pbd/convert.h
index 12e63ba6fc..12e63ba6fc 100644
--- a/libs/pbd3/pbd/convert.h
+++ b/libs/pbd/pbd/convert.h
diff --git a/libs/pbd3/pbd/error.h b/libs/pbd/pbd/error.h
index 4136f02ee2..4136f02ee2 100644
--- a/libs/pbd3/pbd/error.h
+++ b/libs/pbd/pbd/error.h
diff --git a/libs/pbd3/pbd/failed_constructor.h b/libs/pbd/pbd/failed_constructor.h
index 62eb6c0d71..62eb6c0d71 100644
--- a/libs/pbd3/pbd/failed_constructor.h
+++ b/libs/pbd/pbd/failed_constructor.h
diff --git a/libs/pbd3/pbd/fastlog.h b/libs/pbd/pbd/fastlog.h
index 4269705a44..4269705a44 100644
--- a/libs/pbd3/pbd/fastlog.h
+++ b/libs/pbd/pbd/fastlog.h
diff --git a/libs/pbd3/pbd/forkexec.h b/libs/pbd/pbd/forkexec.h
index 2af3711390..2af3711390 100644
--- a/libs/pbd3/pbd/forkexec.h
+++ b/libs/pbd/pbd/forkexec.h
diff --git a/libs/pbd/pbd/id.h b/libs/pbd/pbd/id.h
new file mode 100644
index 0000000000..9a3f10478d
--- /dev/null
+++ b/libs/pbd/pbd/id.h
@@ -0,0 +1,47 @@
+#ifndef __pbd_id_h__
+#define __pbd_id_h__
+
+#include <stdint.h>
+#include <string>
+
+#include <glibmm/thread.h>
+
+namespace PBD {
+
+class ID {
+ public:
+ ID ();
+ ID (std::string);
+
+ bool operator== (const ID& other) const {
+ return id == other.id;
+ }
+
+ bool operator!= (const ID& other) const {
+ return id != other.id;
+ }
+
+ ID& operator= (std::string);
+
+ bool operator< (const ID& other) const {
+ return id < other.id;
+ }
+
+ void print (char* buf) const;
+
+ static uint64_t counter() { return _counter; }
+ static void init_counter (uint64_t val) { _counter = val; }
+ static void init ();
+
+ private:
+ uint64_t id;
+ int string_assign (std::string);
+
+ static Glib::Mutex* counter_lock;
+ static uint64_t _counter;
+};
+
+}
+std::ostream& operator<< (std::ostream& ostr, const PBD::ID&);
+
+#endif /* __pbd_id_h__ */
diff --git a/libs/pbd3/pbd/mathfix.h b/libs/pbd/pbd/mathfix.h
index f0dc7e491e..f0dc7e491e 100644
--- a/libs/pbd3/pbd/mathfix.h
+++ b/libs/pbd/pbd/mathfix.h
diff --git a/libs/pbd3/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
index c8bfe5de4c..c8bfe5de4c 100644
--- a/libs/pbd3/pbd/memento_command.h
+++ b/libs/pbd/pbd/memento_command.h
diff --git a/libs/pbd3/pbd/mountpoint.h b/libs/pbd/pbd/mountpoint.h
index 86ccc58190..86ccc58190 100644
--- a/libs/pbd3/pbd/mountpoint.h
+++ b/libs/pbd/pbd/mountpoint.h
diff --git a/libs/pbd/pbd/path.h b/libs/pbd/pbd/path.h
new file mode 100644
index 0000000000..0b77a7c237
--- /dev/null
+++ b/libs/pbd/pbd/path.h
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+#ifndef PBD_PATH
+#define PBD_PATH
+
+#include <string>
+#include <vector>
+
+namespace PBD {
+
+using std::string;
+using std::vector;
+
+/**
+ The Path class is a helper class for getting a vector of absolute
+ paths contained in a path string where a path string contains
+ absolute directory paths separated by a colon(:) or a semi-colon(;)
+ on windows.
+ */
+class Path {
+public:
+
+ /**
+ Create an empty Path.
+ */
+ Path ();
+
+ /**
+ Initialize Path from a string, each absolute path contained
+ in the "path" will be accessed to ensure it exists and is
+ readable.
+ \param path A path string.
+ */
+ Path (const string& path);
+
+ /**
+ Initialize Path from a vector of path strings, each absolute
+ path contained in paths will be accessed to ensure it
+ exists and is readable.
+ \param path A path string.
+ */
+ Path (const vector<string>& paths);
+
+ Path(const Path& path);
+
+ /**
+ Indicate whether there are any directories in m_dirs, if Path is
+ initialized with an empty string as the result of for instance
+ calling Glib::getenv where the environment variable doesn't
+ exist or if none of the directories in the path string are
+ accessible then false is returned.
+
+ \return true if there are any paths in m_paths.
+ */
+ //operator bool () const { return !m_dirs.empty(); }
+
+ /**
+ \return vector containing the absolute paths to the directories
+ contained
+ */
+ operator const vector<string>& () const { return m_dirs; }
+
+ /**
+ \return vector containing the absolute paths to the directories
+ contained
+ */
+ const vector<string>& dirs () const { return m_dirs; }
+
+ const string path_string() const;
+
+ const Path& operator= (const Path& path);
+
+ const Path& operator+= (const string& directory_path);
+
+ Path& add_subdirectory_to_path (const string& subdirectory);
+
+protected:
+
+ friend const Path operator+ (const Path&, const Path&);
+
+ bool readable_directory (const string& directory_path);
+
+ void add_readable_directory (const string& directory_path);
+
+ void add_readable_directories (const vector<string>& paths);
+
+ vector<string> m_dirs;
+
+};
+
+bool find_file_in_path (const Path& path, const string& filename, string& resulting_path_to_file);
+
+} // namespace PBD
+
+#endif // PBD_PATH
+
+
diff --git a/libs/pbd3/pbd/pathscanner.h b/libs/pbd/pbd/pathscanner.h
index 346e7858c4..346e7858c4 100644
--- a/libs/pbd3/pbd/pathscanner.h
+++ b/libs/pbd/pbd/pathscanner.h
diff --git a/libs/pbd3/pbd/pool.h b/libs/pbd/pbd/pool.h
index f8e19e72fb..f8e19e72fb 100644
--- a/libs/pbd3/pbd/pool.h
+++ b/libs/pbd/pbd/pool.h
diff --git a/libs/pbd3/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h
index 482b5b54cf..482b5b54cf 100644
--- a/libs/pbd3/pbd/pthread_utils.h
+++ b/libs/pbd/pbd/pthread_utils.h
diff --git a/libs/pbd/pbd/rcu.h b/libs/pbd/pbd/rcu.h
new file mode 100644
index 0000000000..6d9586cb3c
--- /dev/null
+++ b/libs/pbd/pbd/rcu.h
@@ -0,0 +1,120 @@
+#ifndef __pbd_rcu_h__
+#define __pbd_rcu_h__
+
+#include "boost/shared_ptr.hpp"
+#include "glibmm/thread.h"
+
+#include <list>
+
+template<class T>
+class RCUManager
+{
+public:
+
+ RCUManager (T* new_rcu_value)
+ : m_rcu_value(new_rcu_value)
+ {
+
+ }
+
+ virtual ~RCUManager() { }
+
+ boost::shared_ptr<T> reader () const { return m_rcu_value; }
+
+ // should be private
+ virtual boost::shared_ptr<T> write_copy () = 0;
+
+ // should be private
+ virtual void update (boost::shared_ptr<T> new_value) = 0;
+
+protected:
+
+ boost::shared_ptr<T> m_rcu_value;
+
+
+};
+
+
+template<class T>
+class SerializedRCUManager : public RCUManager<T>
+{
+public:
+
+ SerializedRCUManager(T* new_rcu_value)
+ : RCUManager<T>(new_rcu_value)
+ {
+
+ }
+
+ virtual boost::shared_ptr<T> write_copy ()
+ {
+ m_lock.lock();
+
+ // I hope this is doing what I think it is doing :)
+ boost::shared_ptr<T> new_copy(new T(*RCUManager<T>::m_rcu_value));
+
+ // XXX todo remove old copies with only 1 reference from the list.
+
+ return new_copy;
+ }
+
+ virtual void update (boost::shared_ptr<T> new_value)
+ {
+ // So a current reader doesn't hold the only reference to
+ // the existing value when we assign it a new value which
+ // should ensure that deletion of old values doesn't
+ // occur in a reader thread.
+ boost::shared_ptr<T> old_copy = RCUManager<T>::m_rcu_value;
+
+ // we hold the lock at this point effectively blocking
+ // other writers.
+ RCUManager<T>::m_rcu_value = new_value;
+
+
+ // XXX add the old value to the list of old copies.
+
+ m_lock.unlock();
+ }
+
+private:
+ Glib::Mutex m_lock;
+
+ std::list<boost::shared_ptr<T> > m_old_values;
+};
+
+template<class T>
+class RCUWriter
+{
+public:
+
+ RCUWriter(RCUManager<T>& manager)
+ : m_manager(manager)
+ {
+ m_copy = m_manager.write_copy();
+ }
+
+ ~RCUWriter()
+ {
+ // we can check here that the refcount of m_copy is 1
+
+ if(m_copy.use_count() == 1) {
+ m_manager.update(m_copy);
+ } else {
+
+ // critical error.
+ }
+
+ }
+
+ // or operator boost::shared_ptr<T> ();
+ boost::shared_ptr<T> get_copy() { return m_copy; }
+
+private:
+
+ RCUManager<T>& m_manager;
+
+ // preferably this holds a pointer to T
+ boost::shared_ptr<T> m_copy;
+};
+
+#endif /* __pbd_rcu_h__ */
diff --git a/libs/pbd3/pbd/receiver.h b/libs/pbd/pbd/receiver.h
index 5ce238df63..5ce238df63 100644
--- a/libs/pbd3/pbd/receiver.h
+++ b/libs/pbd/pbd/receiver.h
diff --git a/libs/pbd3/pbd/restartable_rw.h b/libs/pbd/pbd/restartable_rw.h
index ee84e4e295..ee84e4e295 100644
--- a/libs/pbd3/pbd/restartable_rw.h
+++ b/libs/pbd/pbd/restartable_rw.h
diff --git a/libs/pbd3/pbd/ringbuffer.h b/libs/pbd/pbd/ringbuffer.h
index 1d9c9b04e3..1d9c9b04e3 100644
--- a/libs/pbd3/pbd/ringbuffer.h
+++ b/libs/pbd/pbd/ringbuffer.h
diff --git a/libs/pbd3/pbd/ringbufferNPT.h b/libs/pbd/pbd/ringbufferNPT.h
index fee2efce3d..fee2efce3d 100644
--- a/libs/pbd3/pbd/ringbufferNPT.h
+++ b/libs/pbd/pbd/ringbufferNPT.h
diff --git a/libs/pbd3/pbd/selectable.h b/libs/pbd/pbd/selectable.h
index 470bc3cfcc..470bc3cfcc 100644
--- a/libs/pbd3/pbd/selectable.h
+++ b/libs/pbd/pbd/selectable.h
diff --git a/libs/pbd3/pbd/serializable.h b/libs/pbd/pbd/serializable.h
index f6ac4e92fb..f6ac4e92fb 100644
--- a/libs/pbd3/pbd/serializable.h
+++ b/libs/pbd/pbd/serializable.h
diff --git a/libs/pbd3/pbd/stacktrace.h b/libs/pbd/pbd/stacktrace.h
index d7278bd35a..d7278bd35a 100644
--- a/libs/pbd3/pbd/stacktrace.h
+++ b/libs/pbd/pbd/stacktrace.h
diff --git a/libs/ardour/ardour/stateful.h b/libs/pbd/pbd/stateful.h
index 4f4cb20b39..3038f16b4f 100644
--- a/libs/ardour/ardour/stateful.h
+++ b/libs/pbd/pbd/stateful.h
@@ -15,11 +15,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
+ $Id: stateful.h 17 2005-09-24 19:13:41Z taybin $
*/
-#ifndef __ardour_stateful_h__
-#define __ardour_stateful_h__
+#ifndef __pbd_stateful_h__
+#define __pbd_stateful_h__
#include <string>
@@ -47,5 +47,5 @@ class Stateful {
XMLNode *_instant_xml;
};
-#endif /* __ardour_stateful_h__ */
+#endif /* __pbd_stateful_h__ */
diff --git a/libs/pbd3/pbd/stl_delete.h b/libs/pbd/pbd/stl_delete.h
index 6e5bfa0734..6e5bfa0734 100644
--- a/libs/pbd3/pbd/stl_delete.h
+++ b/libs/pbd/pbd/stl_delete.h
diff --git a/libs/pbd3/pbd/stl_functors.h b/libs/pbd/pbd/stl_functors.h
index 4a96e91a28..4a96e91a28 100644
--- a/libs/pbd3/pbd/stl_functors.h
+++ b/libs/pbd/pbd/stl_functors.h
diff --git a/libs/pbd3/pbd/strsplit.h b/libs/pbd/pbd/strsplit.h
index e55ad1c825..e55ad1c825 100644
--- a/libs/pbd3/pbd/strsplit.h
+++ b/libs/pbd/pbd/strsplit.h
diff --git a/libs/pbd3/pbd/textreceiver.h b/libs/pbd/pbd/textreceiver.h
index b8bfe5bc78..b8bfe5bc78 100644
--- a/libs/pbd3/pbd/textreceiver.h
+++ b/libs/pbd/pbd/textreceiver.h
diff --git a/libs/pbd3/pbd/thrown_error.h b/libs/pbd/pbd/thrown_error.h
index 83cf8acfac..83cf8acfac 100644
--- a/libs/pbd3/pbd/thrown_error.h
+++ b/libs/pbd/pbd/thrown_error.h
diff --git a/libs/pbd/pbd/tokenizer.h b/libs/pbd/pbd/tokenizer.h
new file mode 100644
index 0000000000..a976b79341
--- /dev/null
+++ b/libs/pbd/pbd/tokenizer.h
@@ -0,0 +1,49 @@
+#ifndef PBD_TOKENIZER
+#define PBD_TOKENIZER
+
+#include <iterator>
+#include <string>
+
+namespace PBD {
+
+/**
+ Tokenize string, this should work for standard
+ strings aswell as Glib::ustring. This is a bit of a hack,
+ there are much better string tokenizing patterns out there.
+*/
+template<typename StringType, typename Iter>
+unsigned int
+tokenize(const StringType& str,
+ const StringType& delims,
+ Iter it)
+{
+ typename StringType::size_type start_pos = 0;
+ typename StringType::size_type end_pos = 0;
+ unsigned int token_count = 0;
+
+ do {
+ start_pos = str.find_first_not_of(delims, start_pos);
+ end_pos = str.find_first_of(delims, start_pos);
+ if (start_pos != end_pos) {
+ if (end_pos == str.npos) {
+ end_pos = str.length();
+ }
+ *it++ = str.substr(start_pos, end_pos - start_pos);
+ ++token_count;
+ start_pos = str.find_first_not_of(delims, end_pos + 1);
+ }
+ } while (start_pos != str.npos);
+
+ if (start_pos != str.npos) {
+ *it++ = str.substr(start_pos, str.length() - start_pos);
+ ++token_count;
+ }
+
+ return token_count;
+}
+
+} // namespace PBD
+
+#endif // PBD_TOKENIZER
+
+
diff --git a/libs/pbd3/pbd/touchable.h b/libs/pbd/pbd/touchable.h
index 0298574dfa..0298574dfa 100644
--- a/libs/pbd3/pbd/touchable.h
+++ b/libs/pbd/pbd/touchable.h
diff --git a/libs/pbd3/pbd/transmitter.h b/libs/pbd/pbd/transmitter.h
index 357cb9965f..357cb9965f 100644
--- a/libs/pbd3/pbd/transmitter.h
+++ b/libs/pbd/pbd/transmitter.h
diff --git a/libs/pbd3/pbd/undo.h b/libs/pbd/pbd/undo.h
index 33577ed4d7..33577ed4d7 100644
--- a/libs/pbd3/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
diff --git a/libs/pbd3/pbd/whitespace.h b/libs/pbd/pbd/whitespace.h
index 6620a8fb50..6620a8fb50 100644
--- a/libs/pbd3/pbd/whitespace.h
+++ b/libs/pbd/pbd/whitespace.h
diff --git a/libs/pbd3/pbd/xml++.h b/libs/pbd/pbd/xml++.h
index afb896e1d5..5dcb4f084a 100644
--- a/libs/pbd3/pbd/xml++.h
+++ b/libs/pbd/pbd/xml++.h
@@ -37,7 +37,6 @@ private:
string _filename;
XMLNode *_root;
int _compression;
- bool _initialized;
public:
XMLTree();
@@ -45,9 +44,8 @@ public:
XMLTree(const XMLTree *);
~XMLTree();
- bool initialized() const { return _initialized; };
XMLNode *root() const { return _root; };
- XMLNode *set_root(XMLNode *n) { _initialized = true; return _root = n; };
+ XMLNode *set_root(XMLNode *n) { return _root = n; };
const string & filename() const { return _filename; };
const string & set_filename(const string &fn) { return _filename = fn; };
@@ -69,7 +67,6 @@ public:
class XMLNode {
private:
- bool _initialized;
string _name;
bool _is_content;
string _content;
@@ -83,18 +80,17 @@ public:
XMLNode(const XMLNode&);
~XMLNode();
- bool initialized() const { return _initialized; };
const string name() const { return _name; };
bool is_content() const { return _is_content; };
const string & content() const { return _content; };
- const string & set_content(const string &);
+ const string & set_content (const string &);
XMLNode *add_content(const string & = string());
- const XMLNodeList & children(const string & = string()) const;
- XMLNode *add_child(const char *);
- XMLNode *add_child_copy(const XMLNode&);
- void add_child_nocopy (XMLNode&);
+ const XMLNodeList & children (const string & = string()) const;
+ XMLNode *add_child (const char *);
+ XMLNode *add_child_copy (const XMLNode&);
+ void add_child_nocopy (XMLNode&);
const XMLPropertyList & properties() const { return _proplist; };
XMLProperty *property(const char * );
diff --git a/libs/pbd3/pool.cc b/libs/pbd/pool.cc
index 089766482d..be8032b7b6 100644
--- a/libs/pbd3/pool.cc
+++ b/libs/pbd/pool.cc
@@ -70,7 +70,7 @@ Pool::alloc ()
} else {
return ptr;
}
-};
+}
void
Pool::release (void *ptr)
diff --git a/libs/pbd3/pthread_utils.cc b/libs/pbd/pthread_utils.cc
index db242cea7b..db242cea7b 100644
--- a/libs/pbd3/pthread_utils.cc
+++ b/libs/pbd/pthread_utils.cc
diff --git a/libs/pbd3/receiver.cc b/libs/pbd/receiver.cc
index 5e7c10de70..5e7c10de70 100644
--- a/libs/pbd3/receiver.cc
+++ b/libs/pbd/receiver.cc
diff --git a/libs/pbd3/stacktrace.cc b/libs/pbd/stacktrace.cc
index 1e7dfa08e9..1e7dfa08e9 100644
--- a/libs/pbd3/stacktrace.cc
+++ b/libs/pbd/stacktrace.cc
diff --git a/libs/ardour/stateful.cc b/libs/pbd/stateful.cc
index b8e301b273..786410e817 100644
--- a/libs/ardour/stateful.cc
+++ b/libs/pbd/stateful.cc
@@ -15,15 +15,14 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
+ $Id: stateful.cc 629 2006-06-21 23:01:03Z paul $
*/
-#include <cstdio>
#include <unistd.h>
-#include <ardour/stateful.h>
-#include <ardour/utils.h>
+#include <pbd/stateful.h>
#include <pbd/xml++.h>
+#include <pbd/error.h>
#include "i18n.h"
@@ -39,7 +38,10 @@ Stateful::~Stateful ()
{
// Do not delete _extra_xml. The use of add_child_nocopy()
// means it needs to live on indefinately.
- delete _instant_xml;
+
+ if (_instant_xml) {
+ delete _instant_xml;
+ }
}
void
@@ -132,4 +134,3 @@ Stateful::instant_xml (const string& str, const string& dir)
return 0;
}
-
diff --git a/libs/pbd3/strsplit.cc b/libs/pbd/strsplit.cc
index 7f29a77887..7f29a77887 100644
--- a/libs/pbd3/strsplit.cc
+++ b/libs/pbd/strsplit.cc
diff --git a/libs/pbd3/textreceiver.cc b/libs/pbd/textreceiver.cc
index 43620e9830..43620e9830 100644
--- a/libs/pbd3/textreceiver.cc
+++ b/libs/pbd/textreceiver.cc
diff --git a/libs/pbd3/transmitter.cc b/libs/pbd/transmitter.cc
index 876a9d86e5..876a9d86e5 100644
--- a/libs/pbd3/transmitter.cc
+++ b/libs/pbd/transmitter.cc
diff --git a/libs/pbd3/undo.cc b/libs/pbd/undo.cc
index aa27f95789..aa27f95789 100644
--- a/libs/pbd3/undo.cc
+++ b/libs/pbd/undo.cc
diff --git a/libs/pbd/whitespace.cc b/libs/pbd/whitespace.cc
new file mode 100644
index 0000000000..e35a8a8c0e
--- /dev/null
+++ b/libs/pbd/whitespace.cc
@@ -0,0 +1,44 @@
+#include <pbd/whitespace.h>
+
+using namespace std;
+
+void
+strip_whitespace_edges (string& str)
+{
+ string::size_type i;
+ string::size_type len;
+ string::size_type s;
+
+ len = str.length();
+
+ /* strip front */
+
+ for (i = 0; i < len; ++i) {
+ if (isgraph (str[i])) {
+ break;
+ }
+ }
+
+ /* strip back */
+
+ if (len > 1) {
+
+ s = i;
+ i = len - 1;
+
+ do {
+ if (isgraph (str[i]) || i == 0) {
+ break;
+ }
+
+ --i;
+
+ } while (true);
+
+ str = str.substr (s, (i - s) + 1);
+
+ } else {
+ str = str.substr (s);
+ }
+}
+
diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc
new file mode 100644
index 0000000000..03fa116279
--- /dev/null
+++ b/libs/pbd/xml++.cc
@@ -0,0 +1,420 @@
+/* xml++.cc
+ * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
+ * are covered by the GNU Lesser General Public License, which should be
+ * included with libxml++ as the file COPYING.
+ */
+
+#include <pbd/xml++.h>
+#include <libxml/debugXML.h>
+
+static XMLNode *readnode(xmlNodePtr);
+static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int);
+
+XMLTree::XMLTree()
+ : _filename(),
+ _root(0),
+ _compression(0)
+{
+}
+
+XMLTree::XMLTree(const string &fn)
+ : _filename(fn),
+ _root(0),
+ _compression(0)
+{
+ read();
+}
+
+XMLTree::XMLTree(const XMLTree * from)
+{
+ _filename = from->filename();
+ _root = new XMLNode(*from->root());
+ _compression = from->compression();
+}
+
+XMLTree::~XMLTree()
+{
+ if (_root) {
+ delete _root;
+ }
+}
+
+int
+XMLTree::set_compression(int c)
+{
+ if (c > 9) {
+ c = 9;
+ } else if (c < 0) {
+ c = 0;
+ }
+
+ _compression = c;
+
+ return _compression;
+}
+
+bool
+XMLTree::read(void)
+{
+ xmlDocPtr doc;
+
+ if (_root) {
+ delete _root;
+ _root = 0;
+ }
+
+ xmlKeepBlanksDefault(0);
+
+ doc = xmlParseFile(_filename.c_str());
+ if (!doc) {
+ return false;
+ }
+
+ _root = readnode(xmlDocGetRootElement(doc));
+ xmlFreeDoc(doc);
+
+ return true;
+}
+
+bool
+XMLTree::read_buffer(const string & buffer)
+{
+ xmlDocPtr doc;
+
+ _filename = "";
+
+ if (_root) {
+ delete _root;
+ _root = 0;
+ }
+
+ doc = xmlParseMemory((char *) buffer.c_str(), buffer.length());
+ if (!doc) {
+ return false;
+ }
+
+ _root = readnode(xmlDocGetRootElement(doc));
+ xmlFreeDoc(doc);
+
+ return true;
+}
+
+bool
+XMLTree::write(void) const
+{
+ xmlDocPtr doc;
+ XMLNodeList children;
+ int result;
+
+ xmlKeepBlanksDefault(0);
+ doc = xmlNewDoc((xmlChar *) "1.0");
+ xmlSetDocCompressMode(doc, _compression);
+ writenode(doc, _root, doc->children, 1);
+ result = xmlSaveFormatFile(_filename.c_str(), doc, 1);
+ xmlFreeDoc(doc);
+
+ if (result == -1) {
+ return false;
+ }
+
+ return true;
+}
+
+void
+XMLTree::debug(FILE* out) const
+{
+ xmlDocPtr doc;
+ XMLNodeList children;
+
+ xmlKeepBlanksDefault(0);
+ doc = xmlNewDoc((xmlChar *) "1.0");
+ xmlSetDocCompressMode(doc, _compression);
+ writenode(doc, _root, doc->children, 1);
+ xmlDebugDumpDocument (out, doc);
+ xmlFreeDoc(doc);
+}
+
+const string &
+XMLTree::write_buffer(void) const
+{
+ static string retval;
+ char *ptr;
+ int len;
+ xmlDocPtr doc;
+ XMLNodeList children;
+
+ xmlKeepBlanksDefault(0);
+ doc = xmlNewDoc((xmlChar *) "1.0");
+ xmlSetDocCompressMode(doc, _compression);
+ writenode(doc, _root, doc->children, 1);
+ xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len);
+ xmlFreeDoc(doc);
+
+ retval = ptr;
+
+ free(ptr);
+
+ return retval;
+}
+
+XMLNode::XMLNode(const string & n)
+ : _name(n), _is_content(false), _content(string())
+{
+}
+
+XMLNode::XMLNode(const string & n, const string & c)
+ :_name(n), _is_content(true), _content(c)
+{
+}
+
+XMLNode::XMLNode(const XMLNode& from)
+{
+ XMLPropertyList props;
+ XMLPropertyIterator curprop;
+ XMLNodeList nodes;
+ XMLNodeIterator curnode;
+
+ _name = from.name();
+ set_content(from.content());
+
+ props = from.properties();
+ for (curprop = props.begin(); curprop != props.end(); ++curprop) {
+ add_property((*curprop)->name().c_str(), (*curprop)->value());
+ }
+
+ nodes = from.children();
+ for (curnode = nodes.begin(); curnode != nodes.end(); ++curnode) {
+ add_child_copy(**curnode);
+ }
+}
+
+XMLNode::~XMLNode()
+{
+ XMLNodeIterator curchild;
+ XMLPropertyIterator curprop;
+
+ for (curchild = _children.begin(); curchild != _children.end(); ++curchild) {
+ delete *curchild;
+ }
+
+ for (curprop = _proplist.begin(); curprop != _proplist.end(); ++curprop) {
+ delete *curprop;
+ }
+}
+
+const string &
+XMLNode::set_content(const string & c)
+{
+ if (c.empty()) {
+ _is_content = false;
+ } else {
+ _is_content = true;
+ }
+
+ _content = c;
+
+ return _content;
+}
+
+const XMLNodeList &
+XMLNode::children(const string & n) const
+{
+ static XMLNodeList retval;
+ XMLNodeConstIterator cur;
+
+ if (n.length() == 0) {
+ return _children;
+ }
+
+ retval.erase(retval.begin(), retval.end());
+
+ for (cur = _children.begin(); cur != _children.end(); ++cur) {
+ if ((*cur)->name() == n) {
+ retval.insert(retval.end(), *cur);
+ }
+ }
+
+ return retval;
+}
+
+XMLNode *
+XMLNode::add_child(const char * n)
+{
+ return add_child_copy(XMLNode (n));
+}
+
+void
+XMLNode::add_child_nocopy (XMLNode& n)
+{
+ _children.insert(_children.end(), &n);
+}
+
+XMLNode *
+XMLNode::add_child_copy(const XMLNode& n)
+{
+ XMLNode *copy = new XMLNode (n);
+ _children.insert(_children.end(), copy);
+ return copy;
+}
+
+XMLNode *
+XMLNode::add_content(const string & c)
+{
+ return add_child_copy(XMLNode (string(), c));
+}
+
+XMLProperty *
+XMLNode::property(const char * n)
+{
+ string ns(n);
+ if (_propmap.find(ns) == _propmap.end()) {
+ return 0;
+ }
+
+ return _propmap[ns];
+}
+
+XMLProperty *
+XMLNode::add_property(const char * n, const string & v)
+{
+ string ns(n);
+ if(_propmap.find(ns) != _propmap.end()){
+ remove_property(ns);
+ }
+
+ XMLProperty *tmp = new XMLProperty(ns, v);
+
+ if (!tmp) {
+ return 0;
+ }
+
+ _propmap[tmp->name()] = tmp;
+ _proplist.insert(_proplist.end(), tmp);
+
+ return tmp;
+}
+
+XMLProperty *
+XMLNode::add_property(const char * n, const char * v)
+{
+ string vs(v);
+ return add_property(n, vs);
+}
+
+void
+XMLNode::remove_property(const string & n)
+{
+ if (_propmap.find(n) != _propmap.end()) {
+ _proplist.remove(_propmap[n]);
+ _propmap.erase(n);
+ }
+}
+
+void
+XMLNode::remove_nodes(const string & n)
+{
+ XMLNodeIterator i = _children.begin();
+ XMLNodeIterator tmp;
+
+ while (i != _children.end()) {
+ tmp = i;
+ ++tmp;
+ if ((*i)->name() == n) {
+ _children.erase (i);
+ }
+ i = tmp;
+ }
+}
+
+void
+XMLNode::remove_nodes_and_delete(const string & n)
+{
+ XMLNodeIterator i = _children.begin();
+ XMLNodeIterator tmp;
+
+ while (i != _children.end()) {
+ tmp = i;
+ ++tmp;
+ if ((*i)->name() == n) {
+ delete *i;
+ _children.erase (i);
+ }
+ i = tmp;
+ }
+}
+
+XMLProperty::XMLProperty(const string &n, const string &v)
+ : _name(n),
+ _value(v)
+{
+}
+
+XMLProperty::~XMLProperty()
+{
+}
+
+static XMLNode *
+readnode(xmlNodePtr node)
+{
+ string name, content;
+ xmlNodePtr child;
+ XMLNode *tmp;
+ xmlAttrPtr attr;
+
+ if (node->name) {
+ name = (char *) node->name;
+ }
+
+ tmp = new XMLNode(name);
+
+ for (attr = node->properties; attr; attr = attr->next) {
+ content = "";
+ if (attr->children) {
+ content = (char *) attr->children->content;
+ }
+ tmp->add_property((char *) attr->name, content);
+ }
+
+ if (node->content) {
+ tmp->set_content((char *) node->content);
+ } else {
+ tmp->set_content(string());
+ }
+
+ for (child = node->children; child; child = child->next) {
+ tmp->add_child_nocopy (*readnode(child));
+ }
+
+ return tmp;
+}
+
+static void
+writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root = 0)
+{
+ XMLPropertyList props;
+ XMLPropertyIterator curprop;
+ XMLNodeList children;
+ XMLNodeIterator curchild;
+ xmlNodePtr node;
+
+ if (root) {
+ node = doc->children = xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0);
+ } else {
+ node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0);
+ }
+
+ if (n->is_content()) {
+ node->type = XML_TEXT_NODE;
+ xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(), n->content().length());
+ }
+
+ props = n->properties();
+ for (curprop = props.begin(); curprop != props.end(); ++curprop) {
+ xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(), (xmlChar *) (*curprop)->value().c_str());
+ }
+
+ children = n->children();
+ for (curchild = children.begin(); curchild != children.end(); ++curchild) {
+ writenode(doc, *curchild, node);
+ }
+}
diff --git a/libs/pbd3/SConscript b/libs/pbd3/SConscript
deleted file mode 100644
index fedb3cded4..0000000000
--- a/libs/pbd3/SConscript
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- python -*-
-
-import os
-import os.path
-import glob
-
-Import('env libraries i18n install_prefix')
-
-pbd3 = env.Copy()
-
-domain = 'libpbd'
-
-pbd3.Append(DOMAIN=domain,MAJOR=4,MINOR=0,MICRO=0)
-pbd3.Append(CXXFLAGS="-DPACKAGE=\\\"" + domain + "\\\"")
-pbd3.Append(CXXFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
-pbd3.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED")
-pbd3.Append(PACKAGE=domain)
-pbd3.Append(POTFILE=domain + '.pot')
-
-pbd3_files = Split("""
-basename.cc
-base_ui.cc
-convert.cc
-command.cc
-dmalloc.cc
-error.cc
-mountpoint.cc
-pathscanner.cc
-pool.cc
-pthread_utils.cc
-receiver.cc
-stacktrace.cc
-strsplit.cc
-textreceiver.cc
-transmitter.cc
-undo.cc
-version.cc
-whitespace.cc
-xml++.cc
-""")
-
-conf = Configure(pbd3)
-if conf.CheckFunc('getmntent'):
- conf.env.Append(CCFLAGS="-DHAVE_GETMNTENT")
-if conf.CheckCHeader('execinfo.h'):
- conf.env.Append(CXXFLAGS="-DHAVE_EXECINFO")
-pbd3 = conf.Finish()
-
-pbd3.Merge ([ libraries['sigc2'], libraries['xml'], libraries['glibmm2'], libraries['glib2'] ])
-
-pbd3.VersionBuild(['version.cc','pbd/version.h'], 'SConscript')
-
-libpbd3 = pbd3.SharedLibrary('pbd', pbd3_files)
-
-Default(libpbd3)
-
-if env['NLS']:
- i18n (pbd3, pbd3_files, env)
-
-env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2'), libpbd3))
-
-env.Alias('tarball', env.Distribute (env['DISTTREE'],
- [ 'SConscript', 'i18n.h', 'gettext.h', 'pbd/abstract_ui.cc' ] +
- pbd3_files +
- glob.glob('po/*.po') +
- glob.glob('pbd/*.h')))
diff --git a/libs/pbd3/whitespace.cc b/libs/pbd3/whitespace.cc
deleted file mode 100644
index 7f74940457..0000000000
--- a/libs/pbd3/whitespace.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <pbd/whitespace.h>
-
-using namespace std;
-
-void
-strip_whitespace_edges (string& str)
-{
- string::size_type i;
- string::size_type len;
- string::size_type s;
-
- len = str.length();
-
- for (i = 0; i < len; ++i) {
- if (isgraph (str[i])) {
- break;
- }
- }
-
- s = i;
-
- for (i = len - 1; i >= 0; --i) {
- if (isgraph (str[i])) {
- break;
- }
- }
-
- str = str.substr (s, (i - s) + 1);
-}
-
diff --git a/libs/pbd3/xml++.cc b/libs/pbd3/xml++.cc
deleted file mode 100644
index e496d8b2fd..0000000000
--- a/libs/pbd3/xml++.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-/* xml++.cc
- * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
- * are covered by the GNU Lesser General Public License, which should be
- * included with libxml++ as the file COPYING.
- */
-
-#include <pbd/xml++.h>
-#include <libxml/debugXML.h>
-
-static XMLNode *readnode(xmlNodePtr);
-static void writenode(xmlDocPtr, XMLNode *, xmlNodePtr, int);
-
-XMLTree::XMLTree()
- : _filename(),
- _root(),
- _compression(0),
- _initialized(false)
-{
-}
-
-XMLTree::XMLTree(const string &fn)
- : _filename(fn),
- _root(0),
- _compression(0),
- _initialized(false)
-{
- read();
-}
-
-XMLTree::XMLTree(const XMLTree * from)
-{
- _filename = from->filename();
- _root = new XMLNode(*from->root());
- _compression = from->compression();
- _initialized = true;
-}
-
-XMLTree::~XMLTree()
-{
- if (_initialized && _root)
- delete _root;
-}
-
-int
-XMLTree::set_compression(int c)
-{
- if (c > 9)
- c = 9;
-
- if (c < 0)
- c = 0;
-
- _compression = c;
-
- return _compression;
-}
-
-bool
-XMLTree::read(void)
-{
- xmlDocPtr doc;
-
- if (_root) {
- delete _root;
- _root = 0;
- }
-
- xmlKeepBlanksDefault(0);
-
- doc = xmlParseFile(_filename.c_str());
- if (!doc) {
- _initialized = false;
- return false;
- }
-
- _root = readnode(xmlDocGetRootElement(doc));
- xmlFreeDoc(doc);
- _initialized = true;
-
- return true;
-}
-
-bool
-XMLTree::read_buffer(const string & buffer)
-{
- xmlDocPtr doc;
-
- _filename = "";
-
- if (_root) {
- delete _root;
- _root = 0;
- }
-
- doc = xmlParseMemory((char *) buffer.c_str(), buffer.length());
- if (!doc) {
- _initialized = false;
- return false;
- }
-
- _root = readnode(xmlDocGetRootElement(doc));
- xmlFreeDoc(doc);
- _initialized = true;
-
- return true;
-}
-
-bool
-XMLTree::write(void) const
-{
- xmlDocPtr doc;
- XMLNodeList children;
- int result;
-
- xmlKeepBlanksDefault(0);
- doc = xmlNewDoc((xmlChar *) "1.0");
- xmlSetDocCompressMode(doc, _compression);
- writenode(doc, _root, doc->children, 1);
- result = xmlSaveFormatFile(_filename.c_str(), doc, 1);
- xmlFreeDoc(doc);
-
- if (result == -1)
- return false;
-
- return true;
-}
-
-void
-XMLTree::debug(FILE* out) const
-{
- xmlDocPtr doc;
- XMLNodeList children;
-
- xmlKeepBlanksDefault(0);
- doc = xmlNewDoc((xmlChar *) "1.0");
- xmlSetDocCompressMode(doc, _compression);
- writenode(doc, _root, doc->children, 1);
- xmlDebugDumpDocument (out, doc);
- xmlFreeDoc(doc);
-}
-
-const string &
-XMLTree::write_buffer(void) const
-{
- static string retval;
- char *ptr;
- int len;
- xmlDocPtr doc;
- XMLNodeList children;
-
- xmlKeepBlanksDefault(0);
- doc = xmlNewDoc((xmlChar *) "1.0");
- xmlSetDocCompressMode(doc, _compression);
- writenode(doc, _root, doc->children, 1);
- xmlDocDumpMemory(doc, (xmlChar **) & ptr, &len);
- xmlFreeDoc(doc);
-
- retval = ptr;
-
- free(ptr);
-
- return retval;
-}
-
-XMLNode::XMLNode(const string & n)
- : _name(n), _is_content(false), _content(string())
-{
-
- if (_name.empty())
- _initialized = false;
- else
- _initialized = true;
-}
-
-XMLNode::XMLNode(const string & n, const string & c)
- :_name(string()), _is_content(true), _content(c)
-{
- _initialized = true;
-}
-
-XMLNode::XMLNode(const XMLNode& from)
- : _initialized(false)
-{
- XMLPropertyList props;
- XMLPropertyIterator curprop;
- XMLNodeList nodes;
- XMLNodeIterator curnode;
-
- _name = from.name();
- set_content(from.content());
-
- props = from.properties();
- for (curprop = props.begin(); curprop != props.end(); curprop++)
- add_property((*curprop)->name().c_str(), (*curprop)->value());
-
- nodes = from.children();
- for (curnode = nodes.begin(); curnode != nodes.end(); curnode++)
- add_child_copy(**curnode);
-}
-
-XMLNode::~XMLNode()
-{
- XMLNodeIterator curchild;
- XMLPropertyIterator curprop;
-
- for (curchild = _children.begin(); curchild != _children.end();
- curchild++)
- delete *curchild;
-
- for (curprop = _proplist.begin(); curprop != _proplist.end();
- curprop++)
- delete *curprop;
-}
-
-const string &
-XMLNode::set_content(const string & c)
-{
- if (c.empty())
- _is_content = false;
- else
- _is_content = true;
-
- _content = c;
-
- return _content;
-}
-
-const XMLNodeList &
-XMLNode::children(const string & n) const
-{
- static XMLNodeList retval;
- XMLNodeConstIterator cur;
-
- if (n.length() == 0)
- return _children;
-
- retval.erase(retval.begin(), retval.end());
-
- for (cur = _children.begin(); cur != _children.end(); cur++)
- if ((*cur)->name() == n)
- retval.insert(retval.end(), *cur);
-
- return retval;
-}
-
-XMLNode *
-XMLNode::add_child(const char * n)
-{
- return add_child_copy(XMLNode (n));
-}
-
-void
-XMLNode::add_child_nocopy (XMLNode& n)
-{
- _children.insert(_children.end(), &n);
-}
-
-XMLNode *
-XMLNode::add_child_copy(const XMLNode& n)
-{
- XMLNode *copy = new XMLNode (n);
- _children.insert(_children.end(), copy);
- return copy;
-}
-
-XMLNode *
-XMLNode::add_content(const string & c)
-{
- return add_child_copy(XMLNode (string(), c));
-}
-
-XMLProperty *
-XMLNode::property(const char * n)
-{
- string ns(n);
- if (_propmap.find(ns) == _propmap.end())
- return 0;
- return _propmap[ns];
-}
-
-XMLProperty *
-XMLNode::add_property(const char * n, const string & v)
-{
- string ns(n);
- if(_propmap.find(ns) != _propmap.end()){
- remove_property(ns);
- }
-
- XMLProperty *tmp = new XMLProperty(ns, v);
-
- if (!tmp)
- return 0;
-
- _propmap[tmp->name()] = tmp;
- _proplist.insert(_proplist.end(), tmp);
-
- return tmp;
-}
-
-XMLProperty *
-XMLNode::add_property(const char * n, const char * v)
-{
- string vs(v);
- return add_property(n, vs);
-}
-
-void
-XMLNode::remove_property(const string & n)
-{
- if (_propmap.find(n) != _propmap.end()) {
- _proplist.remove(_propmap[n]);
- _propmap.erase(n);
- }
-}
-
-void
-XMLNode::remove_nodes(const string & n)
-{
- XMLNodeIterator i = _children.begin();
- XMLNodeIterator tmp;
-
- while (i != _children.end()) {
- tmp = i;
- ++tmp;
- if ((*i)->name() == n) {
- _children.erase (i);
- }
- i = tmp;
- }
-}
-
-void
-XMLNode::remove_nodes_and_delete(const string & n)
-{
- XMLNodeIterator i = _children.begin();
- XMLNodeIterator tmp;
-
- while (i != _children.end()) {
- tmp = i;
- ++tmp;
- if ((*i)->name() == n) {
- delete *i;
- _children.erase (i);
- }
- i = tmp;
- }
-}
-
-XMLProperty::XMLProperty(const string &n, const string &v)
- : _name(n),
- _value(v)
-{
-}
-
-XMLProperty::~XMLProperty()
-{
-}
-
-static XMLNode *
-readnode(xmlNodePtr node)
-{
- string name, content;
- xmlNodePtr child;
- XMLNode *tmp;
- xmlAttrPtr attr;
-
- if (node->name)
- name = (char *) node->name;
-
- tmp = new XMLNode(name);
-
- for (attr = node->properties; attr; attr = attr->next) {
- content = "";
- if (attr->children)
- content = (char *) attr->children->content;
- tmp->add_property((char *) attr->name, content);
- }
-
- if (node->content)
- tmp->set_content((char *) node->content);
- else
- tmp->set_content(string());
-
- for (child = node->children; child; child = child->next)
- tmp->add_child_nocopy (*readnode(child));
-
- return tmp;
-}
-
-static void
-writenode(xmlDocPtr doc, XMLNode * n, xmlNodePtr p, int root =
- 0)
-{
- XMLPropertyList props;
- XMLPropertyIterator curprop;
- XMLNodeList children;
- XMLNodeIterator curchild;
- xmlNodePtr node;
-
- if (root)
- node = doc->children =
- xmlNewDocNode(doc, 0, (xmlChar *) n->name().c_str(), 0);
-
- else
- node = xmlNewChild(p, 0, (xmlChar *) n->name().c_str(), 0);
-
- if (n->is_content()) {
- node->type = XML_TEXT_NODE;
- xmlNodeSetContentLen(node, (const xmlChar *) n->content().c_str(),
- n->content().length());
- }
-
- props = n->properties();
- for (curprop = props.begin(); curprop != props.end(); curprop++)
- xmlSetProp(node, (xmlChar *) (*curprop)->name().c_str(),
- (xmlChar *) (*curprop)->value().c_str());
-
- children = n->children();
- for (curchild = children.begin(); curchild != children.end();
- curchild++)
- writenode(doc, *curchild, node);
-}
diff --git a/libs/soundtouch/STTypes.h b/libs/soundtouch/STTypes.h
index dc6a97001a..c404675ecd 100644
--- a/libs/soundtouch/STTypes.h
+++ b/libs/soundtouch/STTypes.h
@@ -105,6 +105,6 @@ namespace soundtouch
#endif
#endif // INTEGER_SAMPLES
-};
+}
#endif
diff --git a/libs/surfaces/control_protocol/SConscript b/libs/surfaces/control_protocol/SConscript
index f8a7d574f5..ce59b1c67c 100644
--- a/libs/surfaces/control_protocol/SConscript
+++ b/libs/surfaces/control_protocol/SConscript
@@ -34,7 +34,7 @@ cp.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"")
cp.Merge ([
libraries['ardour'],
libraries['sigc2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['midi++2'],
libraries['xml'],
libraries['usb'],
diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc
index 10295bc698..dd9adc206e 100644
--- a/libs/surfaces/control_protocol/control_protocol.cc
+++ b/libs/surfaces/control_protocol/control_protocol.cc
@@ -49,7 +49,7 @@ void
ControlProtocol::next_track (uint32_t initial_id)
{
uint32_t limit = session->nroutes();
- Route* cr = route_table[0];
+ boost::shared_ptr<Route> cr = route_table[0];
uint32_t id;
if (cr) {
@@ -88,7 +88,7 @@ void
ControlProtocol::prev_track (uint32_t initial_id)
{
uint32_t limit = session->nroutes() - 1;
- Route* cr = route_table[0];
+ boost::shared_ptr<Route> cr = route_table[0];
uint32_t id;
if (cr) {
@@ -128,29 +128,32 @@ void
ControlProtocol::set_route_table_size (uint32_t size)
{
while (route_table.size() < size) {
- route_table.push_back (0);
+ route_table.push_back (boost::shared_ptr<Route> ((Route*) 0));
}
}
void
-ControlProtocol::set_route_table (uint32_t table_index, ARDOUR::Route*)
+ControlProtocol::set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route> r)
{
+ if (table_index >= route_table.size()) {
+ return;
+ }
+
+ route_table[table_index] = r;
+
+ // XXX SHAREDPTR need to handle r->GoingAway
}
bool
ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id)
{
- if (table_index >= route_table.size()) {
- return false;
- }
-
- Route* r = session->route_by_remote_id (remote_control_id);
+ boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id);
if (!r) {
return false;
}
-
- route_table[table_index] = r;
+
+ set_route_table (table_index, r);
return true;
}
@@ -162,9 +165,9 @@ ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn)
return;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
- AudioTrack* at = dynamic_cast<AudioTrack*>(r);
+ boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
if (at) {
at->set_record_enable (yn, this);
@@ -178,9 +181,9 @@ ControlProtocol::route_get_rec_enable (uint32_t table_index)
return false;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
- AudioTrack* at = dynamic_cast<AudioTrack*>(r);
+ boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
if (at) {
return at->record_enabled ();
@@ -197,7 +200,7 @@ ControlProtocol::route_get_gain (uint32_t table_index)
return 0.0f;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return 0.0f;
@@ -213,7 +216,7 @@ ControlProtocol::route_set_gain (uint32_t table_index, float gain)
return;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
r->set_gain (gain, this);
@@ -227,7 +230,7 @@ ControlProtocol::route_get_effective_gain (uint32_t table_index)
return 0.0f;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return 0.0f;
@@ -244,7 +247,7 @@ ControlProtocol::route_get_peak_input_power (uint32_t table_index, uint32_t whic
return 0.0f;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return 0.0f;
@@ -261,7 +264,7 @@ ControlProtocol::route_get_muted (uint32_t table_index)
return false;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return false;
@@ -277,7 +280,7 @@ ControlProtocol::route_set_muted (uint32_t table_index, bool yn)
return;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
r->set_mute (yn, this);
@@ -292,7 +295,7 @@ ControlProtocol::route_get_soloed (uint32_t table_index)
return false;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return false;
@@ -308,7 +311,7 @@ ControlProtocol::route_set_soloed (uint32_t table_index, bool yn)
return;
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
r->set_solo (yn, this);
@@ -322,7 +325,7 @@ ControlProtocol:: route_get_name (uint32_t table_index)
return "";
}
- Route* r = route_table[table_index];
+ boost::shared_ptr<Route> r = route_table[table_index];
if (r == 0) {
return "";
diff --git a/libs/surfaces/control_protocol/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
index 69135f2b4b..8be652b9df 100644
--- a/libs/surfaces/control_protocol/control_protocol/control_protocol.h
+++ b/libs/surfaces/control_protocol/control_protocol/control_protocol.h
@@ -25,8 +25,9 @@
#include <string>
#include <vector>
#include <list>
+#include <boost/shared_ptr.hpp>
#include <sigc++/sigc++.h>
-
+#include <pbd/stateful.h>
#include <control_protocol/basic_ui.h>
namespace ARDOUR {
@@ -34,7 +35,7 @@ namespace ARDOUR {
class Route;
class Session;
-class ControlProtocol : public sigc::trackable, public BasicUI {
+class ControlProtocol : public sigc::trackable, public Stateful, public BasicUI {
public:
ControlProtocol (Session&, std::string name);
virtual ~ControlProtocol();
@@ -73,7 +74,7 @@ class ControlProtocol : public sigc::trackable, public BasicUI {
*/
void set_route_table_size (uint32_t size);
- void set_route_table (uint32_t table_index, ARDOUR::Route*);
+ void set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route>);
bool set_route_table (uint32_t table_index, uint32_t remote_control_id);
void route_set_rec_enable (uint32_t table_index, bool yn);
@@ -94,7 +95,7 @@ class ControlProtocol : public sigc::trackable, public BasicUI {
std::string route_get_name (uint32_t table_index);
protected:
- std::vector<ARDOUR::Route*> route_table;
+ std::vector<boost::shared_ptr<ARDOUR::Route> > route_table;
std::string _name;
bool _active;
diff --git a/libs/surfaces/generic_midi/SConscript b/libs/surfaces/generic_midi/SConscript
index 1760eb24e9..f9c2de08f8 100644
--- a/libs/surfaces/generic_midi/SConscript
+++ b/libs/surfaces/generic_midi/SConscript
@@ -23,6 +23,7 @@ genericmidi.Append(POTFILE = domain + '.pot')
genericmidi_files=Split("""
interface.cc
generic_midi_control_protocol.cc
+midicontrollable.cc
""")
genericmidi.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE")
@@ -34,7 +35,7 @@ genericmidi.Merge ([
libraries['ardour'],
libraries['ardour_cp'],
libraries['midi++2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['sigc2'],
libraries['usb'],
libraries['xml'],
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
index 95b9d22393..d905c0bc41 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc
@@ -1,20 +1,65 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#include <algorithm>
+
+#include <pbd/error.h>
+#include <pbd/failed_constructor.h>
+
#include <midi++/port.h>
+#include <midi++/manager.h>
+#include <midi++/port_request.h>
#include <ardour/route.h>
#include <ardour/session.h>
#include "generic_midi_control_protocol.h"
+#include "midicontrollable.h"
using namespace ARDOUR;
+using namespace PBD;
#include "i18n.h"
GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s)
: ControlProtocol (s, _("GenericMIDI"))
{
- _port = s.midi_port();
- s.MIDI_PortChanged.connect (mem_fun (*this, &GenericMidiControlProtocol::port_change));
+ MIDI::Manager* mm = MIDI::Manager::instance();
+
+ /* XXX it might be nice to run "control" through i18n, but thats a bit tricky because
+ the name is defined in ardour.rc which is likely not internationalized.
+ */
+ _port = mm->port (X_("control"));
+
+ if (_port == 0) {
+ error << _("no MIDI port named \"control\" exists - generic MIDI control disabled") << endmsg;
+ throw failed_constructor();
+ }
+
+ _feedback_interval = 10000; // microseconds
+ last_feedback_time = 0;
+
+ Controllable::StartLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::start_learning));
+ Controllable::StopLearning.connect (mem_fun (*this, &GenericMidiControlProtocol::stop_learning));
+ Session::SendFeedback.connect (mem_fun (*this, &GenericMidiControlProtocol::send_feedback));
}
GenericMidiControlProtocol::~GenericMidiControlProtocol ()
@@ -24,42 +69,165 @@ GenericMidiControlProtocol::~GenericMidiControlProtocol ()
int
GenericMidiControlProtocol::set_active (bool yn)
{
- /* start delivery/outbound thread */
+ /* start/stop delivery/outbound thread */
return 0;
}
void
-GenericMidiControlProtocol::port_change ()
+GenericMidiControlProtocol::set_feedback_interval (microseconds_t ms)
{
- _port = session->midi_port ();
+ _feedback_interval = ms;
}
-void
-GenericMidiControlProtocol::set_port (MIDI::Port* p)
+void
+GenericMidiControlProtocol::send_feedback ()
{
- _port = p;
+ microseconds_t now = get_microseconds ();
+
+ if (last_feedback_time != 0) {
+ if ((now - last_feedback_time) < _feedback_interval) {
+ return;
+ }
+ }
+
+ _send_feedback ();
+
+ last_feedback_time = now;
}
void
-GenericMidiControlProtocol::send_route_feedback (list<Route*>& routes)
+GenericMidiControlProtocol::_send_feedback ()
{
- if (_port != 0) {
-
- const int32_t bufsize = 16 * 1024;
- MIDI::byte buf[bufsize];
- int32_t bsize = bufsize;
- MIDI::byte* end = buf;
-
- for (list<Route*>::iterator r = routes.begin(); r != routes.end(); ++r) {
- end = (*r)->write_midi_feedback (end, bsize);
+ const int32_t bufsize = 16 * 1024;
+ MIDI::byte buf[bufsize];
+ int32_t bsize = bufsize;
+ MIDI::byte* end = buf;
+
+ for (MIDIControllables::iterator r = controllables.begin(); r != controllables.end(); ++r) {
+ end = (*r)->write_feedback (end, bsize);
+ }
+
+ if (end == buf) {
+ return;
+ }
+
+ _port->write (buf, (int32_t) (end - buf));
+}
+
+bool
+GenericMidiControlProtocol::start_learning (Controllable* c)
+{
+ if (c == 0) {
+ return false;
+ }
+
+ MIDIControllable* mc = new MIDIControllable (*_port, *c);
+
+ {
+ Glib::Mutex::Lock lm (pending_lock);
+ std::pair<MIDIControllables::iterator,bool> result;
+ result = pending_controllables.insert (mc);
+ if (result.second) {
+ c->LearningFinished.connect (bind (mem_fun (*this, &GenericMidiControlProtocol::learning_stopped), mc));
}
-
- if (end == buf) {
- return;
- }
-
- _port->write (buf, (int32_t) (end - buf));
- //cerr << "MIDI feedback: wrote " << (int32_t) (end - buf) << " to midi port\n";
}
+
+ mc->learn_about_external_control ();
+ return true;
}
+void
+GenericMidiControlProtocol::learning_stopped (MIDIControllable* mc)
+{
+ Glib::Mutex::Lock lm (pending_lock);
+ Glib::Mutex::Lock lm2 (controllables_lock);
+
+ MIDIControllables::iterator i = find (pending_controllables.begin(), pending_controllables.end(), mc);
+
+ if (i != pending_controllables.end()) {
+ pending_controllables.erase (i);
+ }
+
+ controllables.insert (mc);
+}
+
+void
+GenericMidiControlProtocol::stop_learning (Controllable* c)
+{
+ Glib::Mutex::Lock lm (pending_lock);
+
+ /* learning timed out, and we've been told to consider this attempt to learn to be cancelled. find the
+ relevant MIDIControllable and remove it from the pending list.
+ */
+
+ for (MIDIControllables::iterator i = pending_controllables.begin(); i != pending_controllables.end(); ++i) {
+ if (&(*i)->get_controllable() == c) {
+ (*i)->stop_learning ();
+ delete (*i);
+ pending_controllables.erase (i);
+ break;
+ }
+ }
+}
+
+XMLNode&
+GenericMidiControlProtocol::get_state ()
+{
+ XMLNode* node = new XMLNode (_name); /* node name must match protocol name */
+ XMLNode* children = new XMLNode (X_("controls"));
+
+ node->add_child_nocopy (*children);
+
+ Glib::Mutex::Lock lm2 (controllables_lock);
+ for (MIDIControllables::iterator i = controllables.begin(); i != controllables.end(); ++i) {
+ children->add_child_nocopy ((*i)->get_state());
+ }
+
+ return *node;
+}
+
+int
+GenericMidiControlProtocol::set_state (const XMLNode& node)
+{
+ XMLNodeList nlist;
+ XMLNodeConstIterator niter;
+ Controllable* c;
+
+ {
+ Glib::Mutex::Lock lm (pending_lock);
+ pending_controllables.clear ();
+ }
+
+ Glib::Mutex::Lock lm2 (controllables_lock);
+
+ controllables.clear ();
+
+ nlist = node.children();
+
+ if (nlist.empty()) {
+ return 0;
+ }
+
+ nlist = nlist.front()->children ();
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ XMLProperty* prop;
+
+ if ((prop = (*niter)->property ("id")) != 0) {
+
+ ID id = prop->value ();
+
+ c = session->controllable_by_id (id);
+
+ if (c) {
+ MIDIControllable* mc = new MIDIControllable (*_port, *c);
+ if (mc->set_state (**niter) == 0) {
+ controllables.insert (mc);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
index 70cbd181c8..5f5a470b13 100644
--- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h
+++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h
@@ -1,34 +1,58 @@
#ifndef ardour_generic_midi_control_protocol_h
#define ardour_generic_midi_control_protocol_h
+#include <set>
+#include <glibmm/thread.h>
+#include <ardour/types.h>
+
#include <control_protocol/control_protocol.h>
namespace MIDI {
class Port;
}
+namespace PBD {
+ class Controllable;
+}
+
namespace ARDOUR {
+ class Session;
+}
-class GenericMidiControlProtocol : public ControlProtocol {
+class MIDIControllable;
+
+class GenericMidiControlProtocol : public ARDOUR::ControlProtocol {
public:
- GenericMidiControlProtocol (Session&);
+ GenericMidiControlProtocol (ARDOUR::Session&);
virtual ~GenericMidiControlProtocol();
int set_active (bool yn);
static bool probe() { return true; }
- void set_port (MIDI::Port*);
MIDI::Port* port () const { return _port; }
+ void set_feedback_interval (ARDOUR::microseconds_t);
+
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
- void send_route_feedback (std::list<Route*>&);
-
private:
- void route_feedback (ARDOUR::Route&, bool);
MIDI::Port* _port;
+ ARDOUR::microseconds_t _feedback_interval;
+ ARDOUR::microseconds_t last_feedback_time;
- void port_change ();
-};
+ void _send_feedback ();
+ void send_feedback ();
-}
+ typedef std::set<MIDIControllable*> MIDIControllables;
+ MIDIControllables controllables;
+ MIDIControllables pending_controllables;
+ Glib::Mutex controllables_lock;
+ Glib::Mutex pending_lock;
+
+ bool start_learning (PBD::Controllable*);
+ void stop_learning (PBD::Controllable*);
+
+ void learning_stopped (MIDIControllable*);
+};
-#endif // ardour_generic_midi_control_protocol_h
+#endif /* ardour_generic_midi_control_protocol_h */
diff --git a/libs/surfaces/generic_midi/interface.cc b/libs/surfaces/generic_midi/interface.cc
index c6c59c6589..230be694f2 100644
--- a/libs/surfaces/generic_midi/interface.cc
+++ b/libs/surfaces/generic_midi/interface.cc
@@ -1,3 +1,5 @@
+#include <pbd/failed_constructor.h>
+
#include <control_protocol/control_protocol.h>
#include "generic_midi_control_protocol.h"
@@ -6,7 +8,13 @@ using namespace ARDOUR;
ControlProtocol*
new_generic_midi_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
- GenericMidiControlProtocol* gmcp = new GenericMidiControlProtocol (*s);
+ GenericMidiControlProtocol* gmcp;
+
+ try {
+ gmcp = new GenericMidiControlProtocol (*s);
+ } catch (failed_constructor& err) {
+ return 0;
+ }
if (gmcp->set_active (true)) {
delete gmcp;
diff --git a/libs/midi++2/midicontrollable.cc b/libs/surfaces/generic_midi/midicontrollable.cc
index f0dbd9cb77..d6135fd2a8 100644
--- a/libs/midi++2/midicontrollable.cc
+++ b/libs/surfaces/generic_midi/midicontrollable.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1998-99 Paul Barton-Davis
+ Copyright (C) 1998-2006 Paul Davis
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
@@ -15,40 +15,48 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id$
+ $Id: midicontrollable.cc 629 2006-06-21 23:01:03Z paul $
*/
#include <cstdio> /* for sprintf, sigh */
+#include <climits>
#include <pbd/error.h>
+#include <pbd/xml++.h>
#include <midi++/port.h>
#include <midi++/channel.h>
-#include <midi++/controllable.h>
+
+#include "midicontrollable.h"
using namespace sigc;
using namespace MIDI;
using namespace PBD;
+using namespace ARDOUR;
+
+bool MIDIControllable::_send_feedback = false;
-Controllable::Controllable (Port *p, bool is_bistate)
+MIDIControllable::MIDIControllable (Port& p, Controllable& c, bool is_bistate)
+ : controllable (c), _port (p), bistate (is_bistate)
{
+ setting = false;
+ last_written = 0; // got a better idea ?
control_type = none;
_control_description = "MIDI Control: none";
control_additional = (byte) -1;
- bistate = is_bistate;
connections = 0;
feedback = true; // for now
/* use channel 0 ("1") as the initial channel */
- midi_rebind (p, 0);
+ midi_rebind (0);
}
-Controllable::~Controllable ()
+MIDIControllable::~MIDIControllable ()
{
drop_external_control ();
}
void
-Controllable::midi_forget ()
+MIDIControllable::midi_forget ()
{
/* stop listening for incoming messages, but retain
our existing event + type information.
@@ -68,41 +76,30 @@ Controllable::midi_forget ()
}
void
-Controllable::midi_rebind (Port *p, channel_t c)
+MIDIControllable::midi_rebind (channel_t c)
{
- if ((port = p) == 0) {
- midi_forget ();
+ if (c >= 0) {
+ bind_midi (c, control_type, control_additional);
} else {
- if (c >= 0) {
- bind_midi (c, control_type, control_additional);
- } else {
- midi_forget ();
- }
+ midi_forget ();
}
}
void
-Controllable::learn_about_external_control ()
+MIDIControllable::learn_about_external_control ()
{
drop_external_control ();
-
- if (port) {
- midi_learn_connection = port->input()->any.connect (mem_fun (*this, &Controllable::midi_receiver));
- learning_started ();
-
- } else {
- info << "No MIDI port specified - external control disabled" << endmsg;
- }
+ midi_learn_connection = _port.input()->any.connect (mem_fun (*this, &MIDIControllable::midi_receiver));
}
void
-Controllable::stop_learning ()
+MIDIControllable::stop_learning ()
{
midi_learn_connection.disconnect ();
}
void
-Controllable::drop_external_control ()
+MIDIControllable::drop_external_control ()
{
if (connections > 0) {
midi_sense_connection[0].disconnect ();
@@ -119,22 +116,22 @@ Controllable::drop_external_control ()
}
void
-Controllable::midi_sense_note_on (Parser &p, EventTwoBytes *tb)
+MIDIControllable::midi_sense_note_on (Parser &p, EventTwoBytes *tb)
{
midi_sense_note (p, tb, true);
}
void
-Controllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb)
+MIDIControllable::midi_sense_note_off (Parser &p, EventTwoBytes *tb)
{
midi_sense_note (p, tb, false);
}
void
-Controllable::midi_sense_note (Parser &p, EventTwoBytes *msg, bool is_on)
+MIDIControllable::midi_sense_note (Parser &p, EventTwoBytes *msg, bool is_on)
{
if (!bistate) {
- set_value (msg->note_number/127.0);
+ controllable.set_value (msg->note_number/127.0);
} else {
/* Note: parser handles the use of zero velocity to
@@ -143,49 +140,49 @@ Controllable::midi_sense_note (Parser &p, EventTwoBytes *msg, bool is_on)
*/
if (msg->note_number == control_additional) {
- set_value (is_on ? 1 : 0);
+ controllable.set_value (is_on ? 1 : 0);
}
}
}
void
-Controllable::midi_sense_controller (Parser &, EventTwoBytes *msg)
+MIDIControllable::midi_sense_controller (Parser &, EventTwoBytes *msg)
{
if (control_additional == msg->controller_number) {
if (!bistate) {
- set_value (msg->value/127.0);
+ controllable.set_value (msg->value/127.0);
} else {
if (msg->value > 64.0) {
- set_value (1);
+ controllable.set_value (1);
} else {
- set_value (0);
+ controllable.set_value (0);
}
}
}
}
void
-Controllable::midi_sense_program_change (Parser &p, byte msg)
+MIDIControllable::midi_sense_program_change (Parser &p, byte msg)
{
/* XXX program change messages make no sense for bistates */
if (!bistate) {
- set_value (msg/127.0);
+ controllable.set_value (msg/127.0);
}
}
void
-Controllable::midi_sense_pitchbend (Parser &p, pitchbend_t pb)
+MIDIControllable::midi_sense_pitchbend (Parser &p, pitchbend_t pb)
{
/* pitchbend messages make no sense for bistates */
/* XXX gack - get rid of assumption about typeof pitchbend_t */
- set_value ((pb/(float) SHRT_MAX));
+ controllable.set_value ((pb/(float) SHRT_MAX));
}
void
-Controllable::midi_receiver (Parser &p, byte *msg, size_t len)
+MIDIControllable::midi_receiver (Parser &p, byte *msg, size_t len)
{
/* we only respond to channel messages */
@@ -195,17 +192,17 @@ Controllable::midi_receiver (Parser &p, byte *msg, size_t len)
/* if the our port doesn't do input anymore, forget it ... */
- if (!port->input()) {
+ if (!_port.input()) {
return;
}
bind_midi ((channel_t) (msg[0] & 0xf), eventType (msg[0] & 0xF0), msg[1]);
- learning_stopped ();
+ controllable.LearningFinished ();
}
void
-Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
+MIDIControllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
{
char buf[64];
@@ -215,17 +212,17 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
control_channel = chn;
control_additional = additional;
- if (port == 0 || port->input() == 0) {
+ if (_port.input() == 0) {
return;
}
- Parser& p = *port->input();
+ Parser& p = *_port.input();
int chn_i = chn;
switch (ev) {
case MIDI::off:
midi_sense_connection[0] = p.channel_note_off[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_note_off));
+ (mem_fun (*this, &MIDIControllable::midi_sense_note_off));
/* if this is a bistate, connect to noteOn as well,
and we'll toggle back and forth between the two.
@@ -233,7 +230,7 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
if (bistate) {
midi_sense_connection[1] = p.channel_note_on[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_note_on));
+ (mem_fun (*this, &MIDIControllable::midi_sense_note_on));
connections = 2;
} else {
connections = 1;
@@ -243,10 +240,10 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
case MIDI::on:
midi_sense_connection[0] = p.channel_note_on[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_note_on));
+ (mem_fun (*this, &MIDIControllable::midi_sense_note_on));
if (bistate) {
midi_sense_connection[1] = p.channel_note_off[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_note_off));
+ (mem_fun (*this, &MIDIControllable::midi_sense_note_off));
connections = 2;
} else {
connections = 1;
@@ -256,7 +253,7 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
case MIDI::controller:
midi_sense_connection[0] = p.channel_controller[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_controller));
+ (mem_fun (*this, &MIDIControllable::midi_sense_controller));
connections = 1;
snprintf (buf, sizeof (buf), "MIDI control: Controller %d", control_additional);
_control_description = buf;
@@ -266,7 +263,7 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
if (!bistate) {
midi_sense_connection[0] = p.channel_program_change[chn_i].connect
(mem_fun (*this,
- &Controllable::midi_sense_program_change));
+ &MIDIControllable::midi_sense_program_change));
connections = 1;
_control_description = "MIDI control: ProgramChange";
}
@@ -275,7 +272,7 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
case MIDI::pitchbend:
if (!bistate) {
midi_sense_connection[0] = p.channel_pitchbend[chn_i].connect
- (mem_fun (*this, &Controllable::midi_sense_pitchbend));
+ (mem_fun (*this, &MIDIControllable::midi_sense_pitchbend));
connections = 1;
_control_description = "MIDI control: Pitchbend";
}
@@ -287,40 +284,83 @@ Controllable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
}
void
-Controllable::set_control_type (channel_t chn, eventType ev, MIDI::byte additional)
+MIDIControllable::send_feedback ()
{
- bind_midi (chn, ev, additional);
-}
+ byte msg[3];
-bool
-Controllable::get_control_info (channel_t& chn, eventType& ev, byte& additional)
-{
- if (control_type == none) {
- chn = -1;
- return false;
- }
+ if (setting || !_send_feedback || control_type == none) {
+ return;
+ }
- ev = control_type;
- chn = control_channel;
- additional = control_additional;
+ msg[0] = (control_type & 0xF0) | (control_channel & 0xF);
+ msg[1] = control_additional;
+ msg[2] = (byte) (controllable.get_value() * 127.0f);
- return true;
+ _port.write (msg, 3);
}
+MIDI::byte*
+MIDIControllable::write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force)
+{
+ if (control_type != none &&_send_feedback && bufsize > 2) {
+
+ MIDI::byte gm = (MIDI::byte) (controllable.get_value() * 127.0);
+
+ if (gm != last_written) {
+ *buf++ = (0xF0 & control_type) | (0xF & control_channel);
+ *buf++ = control_additional; /* controller number */
+ *buf++ = gm;
+ last_written = gm;
+ bufsize -= 3;
+ }
+ }
+
+ return buf;
+}
-void
-Controllable::send_midi_feedback (float val)
+int
+MIDIControllable::set_state (const XMLNode& node)
{
- byte msg[3];
+ const XMLProperty* prop;
+ int xx;
- if (port == 0 || control_type == none) {
- return;
+ if ((prop = node.property ("event")) != 0) {
+ sscanf (prop->value().c_str(), "0x%x", &xx);
+ control_type = (MIDI::eventType) xx;
+ } else {
+ return -1;
}
-
- msg[0] = (control_type & 0xF0) | (control_channel & 0xF);
- msg[1] = control_additional;
- msg[2] = (byte) (val * 127.0f);
- port->write (msg, 3);
+ if ((prop = node.property ("channel")) != 0) {
+ sscanf (prop->value().c_str(), "%d", &xx);
+ control_channel = (MIDI::channel_t) xx;
+ } else {
+ return -1;
+ }
+
+ if ((prop = node.property ("additional")) != 0) {
+ sscanf (prop->value().c_str(), "0x%x", &xx);
+ control_additional = (MIDI::byte) xx;
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+XMLNode&
+MIDIControllable::get_state ()
+{
+ char buf[32];
+ XMLNode& node (controllable.get_state ());
+
+ snprintf (buf, sizeof(buf), "0x%x", (int) control_type);
+ node.add_property ("event", buf);
+ snprintf (buf, sizeof(buf), "%d", (int) control_channel);
+ node.add_property ("channel", buf);
+ snprintf (buf, sizeof(buf), "0x%x", (int) control_additional);
+ node.add_property ("additional", buf);
+
+ return node;
}
diff --git a/libs/surfaces/generic_midi/midicontrollable.h b/libs/surfaces/generic_midi/midicontrollable.h
new file mode 100644
index 0000000000..ab15f9f4ab
--- /dev/null
+++ b/libs/surfaces/generic_midi/midicontrollable.h
@@ -0,0 +1,97 @@
+/*
+ Copyright (C) 1998-2006 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id: controllable.h 4 2005-05-13 20:47:18Z taybin $
+*/
+
+#ifndef __gm_midicontrollable_h__
+#define __gm_midicontrollable_h__
+
+#include <string>
+
+#include <sigc++/sigc++.h>
+
+#include <midi++/types.h>
+#include <pbd/controllable.h>
+#include <pbd/stateful.h>
+#include <ardour/types.h>
+
+namespace MIDI {
+
+class Channel;
+class Port;
+class Parser;
+
+}
+
+class MIDIControllable : public Stateful
+{
+ public:
+ MIDIControllable (MIDI::Port&, PBD::Controllable&, bool bistate = false);
+ virtual ~MIDIControllable ();
+
+ void send_feedback ();
+ MIDI::byte* write_feedback (MIDI::byte* buf, int32_t& bufsize, bool force = false);
+
+ void midi_rebind (MIDI::channel_t channel=-1);
+ void midi_forget ();
+ void learn_about_external_control ();
+ void stop_learning ();
+ void drop_external_control ();
+
+ bool get_midi_feedback () { return feedback; }
+ void set_midi_feedback (bool val) { feedback = val; }
+
+ MIDI::Port& get_port() const { return _port; }
+ PBD::Controllable& get_controllable() const { return controllable; }
+
+ std::string control_description() const { return _control_description; }
+
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
+ private:
+ PBD::Controllable& controllable;
+ MIDI::Port& _port;
+ bool setting;
+ MIDI::byte last_written;
+ bool bistate;
+ int midi_msg_id; /* controller ID or note number */
+ sigc::connection midi_sense_connection[2];
+ sigc::connection midi_learn_connection;
+ size_t connections;
+ MIDI::eventType control_type;
+ MIDI::byte control_additional;
+ MIDI::channel_t control_channel;
+ std::string _control_description;
+ bool feedback;
+
+ static bool _send_feedback;
+
+ void midi_receiver (MIDI::Parser &p, MIDI::byte *, size_t);
+ void midi_sense_note (MIDI::Parser &, MIDI::EventTwoBytes *, bool is_on);
+ void midi_sense_note_on (MIDI::Parser &p, MIDI::EventTwoBytes *tb);
+ void midi_sense_note_off (MIDI::Parser &p, MIDI::EventTwoBytes *tb);
+ void midi_sense_controller (MIDI::Parser &, MIDI::EventTwoBytes *);
+ void midi_sense_program_change (MIDI::Parser &, MIDI::byte);
+ void midi_sense_pitchbend (MIDI::Parser &, MIDI::pitchbend_t);
+
+ void bind_midi (MIDI::channel_t, MIDI::eventType, MIDI::byte);
+};
+
+#endif // __gm_midicontrollable_h__
+
diff --git a/libs/surfaces/tranzport/SConscript b/libs/surfaces/tranzport/SConscript
index 8f3568aa8f..3f9cc5cc15 100644
--- a/libs/surfaces/tranzport/SConscript
+++ b/libs/surfaces/tranzport/SConscript
@@ -34,7 +34,7 @@ tranzport.Merge ([
libraries['ardour'],
libraries['ardour_cp'],
libraries['sigc2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['midi++2'],
libraries['xml'],
libraries['usb'],
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc
index ee8fa95bc2..426c837b2f 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.cc
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc
@@ -579,7 +579,7 @@ TranzportControlProtocol::monitor_work ()
if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
// do we care? not particularly.
- info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
+ PBD::info << string_compose (_("%1: thread not running with realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
}
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
@@ -693,7 +693,7 @@ TranzportControlProtocol::update_state ()
/* per track */
if (route_table[0]) {
- AudioTrack* at = dynamic_cast<AudioTrack*> (route_table[0]);
+ boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
if (at && at->record_enabled()) {
pending_lights[LightTrackrec] = true;
} else {
@@ -1574,3 +1574,15 @@ TranzportControlProtocol::print (int row, int col, const char *text)
}
}
+XMLNode&
+TranzportControlProtocol::get_state ()
+{
+ XMLNode* node = new XMLNode (_name); /* node name must match protocol name */
+ return *node;
+}
+
+int
+TranzportControlProtocol::set_state (const XMLNode& node)
+{
+ return 0;
+}
diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.h b/libs/surfaces/tranzport/tranzport_control_protocol.h
index 546cc2f2af..e6e1a83e46 100644
--- a/libs/surfaces/tranzport/tranzport_control_protocol.h
+++ b/libs/surfaces/tranzport/tranzport_control_protocol.h
@@ -23,6 +23,9 @@ class TranzportControlProtocol : public ARDOUR::ControlProtocol
static bool probe ();
+ XMLNode& get_state ();
+ int set_state (const XMLNode&);
+
private:
static const int VENDORID = 0x165b;
static const int PRODUCTID = 0x8101;
diff --git a/tools/.cvsignore b/tools/.cvsignore
deleted file mode 100644
index 4149fafb53..0000000000
--- a/tools/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
-ard_i18n
-Makefile.in
-Makefile
diff --git a/tools/config.guess b/tools/config.guess
index 78f6b92cd3..917bbc50f3 100755
--- a/tools/config.guess
+++ b/tools/config.guess
@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-timestamp='2003-01-10'
+timestamp='2005-07-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,13 +17,15 @@ timestamp='2003-01-10'
#
# 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.
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
@@ -53,7 +55,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@@ -66,11 +68,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
+ echo "$timestamp" ; exit ;;
--version | -v )
- echo "$version" ; exit 0 ;;
+ echo "$version" ; exit ;;
--help | --h* | -h )
- echo "$usage"; exit 0 ;;
+ echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -106,6 +108,7 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
@@ -122,7 +125,7 @@ case $CC_FOR_BUILD,$HOST_CC,$CC in
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ;'
+esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -195,141 +198,109 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
- exit 0 ;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- macppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvmeppc:OpenBSD:*:*)
- echo powerpc-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mipseb-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sun3:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- *:MicroBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
- exit 0 ;;
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
+ case $UNAME_RELEASE in
+ *4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- eval $set_cc_for_build
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
- if test "$?" = 0 ; then
- case `$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- 3-1307)
- UNAME_MACHINE="alphaev7"
- ;;
- esac
- fi
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit 0 ;;
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
- exit 0 ;;
+ exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
- exit 0 ;;
+ exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
- exit 0;;
+ exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
- exit 0 ;;
+ exit ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
- exit 0 ;;
+ exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
- exit 0 ;;
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
+ exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
@@ -337,29 +308,32 @@ EOF
else
echo pyramid-pyramid-bsd
fi
- exit 0 ;;
+ exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
- exit 0 ;;
- DRS?6000:UNIX_SV:4.2*:7*)
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7 && exit 0 ;;
+ sparc) echo sparc-icl-nx7; exit ;;
esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
@@ -368,10 +342,10 @@ EOF
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
+ exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
@@ -383,10 +357,10 @@ EOF
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
- exit 0 ;;
+ exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -397,37 +371,40 @@ EOF
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
- exit 0 ;;
+ exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
@@ -451,32 +428,33 @@ EOF
exit (-1);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c \
- && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && exit 0
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
- exit 0 ;;
+ exit ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
- exit 0 ;;
+ exit ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
- exit 0 ;;
+ exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
- exit 0 ;;
+ exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
- exit 0 ;;
+ exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
- exit 0 ;;
+ exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
- exit 0 ;;
+ exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
@@ -492,29 +470,29 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit 0 ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
- exit 0 ;;
+ exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
- exit 0 ;;
+ exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
- exit 0 ;;
+ exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
- exit 0 ;;
+ exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
+ exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
- exit 0 ;;
+ exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
@@ -522,7 +500,7 @@ EOF
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit 0 ;;
+ exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
@@ -537,14 +515,18 @@ EOF
exit(0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
- echo rs6000-ibm-aix3.2.5
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
- exit 0 ;;
+ exit ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
@@ -558,28 +540,28 @@ EOF
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
+ exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
- exit 0 ;;
+ exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
- exit 0 ;;
+ exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
+ exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
- exit 0 ;;
+ exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
- exit 0 ;;
+ exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
- exit 0 ;;
+ exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
- exit 0 ;;
+ exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
@@ -641,9 +623,19 @@ EOF
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
- # avoid double evaluation of $set_cc_for_build
- test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
@@ -651,11 +643,11 @@ EOF
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
+ exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
- exit 0 ;;
+ exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
@@ -683,147 +675,166 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
- exit 0 ;;
+ exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
- exit 0 ;;
+ exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
- exit 0 ;;
+ exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
- exit 0 ;;
+ exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
- exit 0 ;;
+ exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
- exit 0 ;;
+ exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
- exit 0 ;;
+ exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
- exit 0 ;;
+ exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit 0 ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit 0 ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit 0 ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit 0 ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit 0 ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
*:UNICOS/mp:*:*)
- echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:FreeBSD:*:*)
- # Determine whether the default compiler uses glibc.
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #if __GLIBC__ >= 2
- LIBC=gnu
- #else
- LIBC=
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
- exit 0 ;;
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
- exit 0 ;;
+ exit ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
- exit 0 ;;
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
- exit 0 ;;
- x86:Interix*:3*)
- echo i586-pc-interix3
- exit 0 ;;
+ exit ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
- exit 0 ;;
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
- exit 0 ;;
+ exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
- exit 0 ;;
+ exit ;;
+ amd64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
- exit 0 ;;
+ exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
*:GNU:*:*)
+ # the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
- exit 0 ;;
+ exit ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
@@ -841,7 +852,7 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
mips64:Linux:*:*)
eval $set_cc_for_build
@@ -860,14 +871,14 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
- test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -881,7 +892,7 @@ EOF
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit 0 ;;
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -889,22 +900,25 @@ EOF
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
- exit 0 ;;
+ exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
- exit 0 ;;
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
@@ -922,15 +936,15 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0 ;;
+ exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit 0 ;;
+ exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit 0 ;;
+ exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
@@ -953,17 +967,23 @@ EOF
LIBC=gnuaout
#endif
#endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
- test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
- exit 0 ;;
+ exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
@@ -971,24 +991,27 @@ EOF
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
+ exit ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
+ exit ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
- exit 0 ;;
+ exit ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
- exit 0 ;;
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
+ exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -996,15 +1019,16 @@ EOF
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
- exit 0 ;;
- i*86:*:5:[78]*)
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit 0 ;;
+ exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
@@ -1022,73 +1046,73 @@ EOF
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
- exit 0 ;;
+ exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
- exit 0 ;;
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
- exit 0 ;;
+ exit ;;
paragon:*:*:*)
echo i860-intel-osf1
- exit 0 ;;
+ exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
- exit 0 ;;
+ exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
- exit 0 ;;
+ exit ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
- exit 0 ;;
+ exit ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
- exit 0 ;;
- M68*:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
+ && { echo i486-ncr-sysv4; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
- exit 0 ;;
+ exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
- exit 0 ;;
+ exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
- exit 0 ;;
+ exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
@@ -1096,68 +1120,73 @@ EOF
else
echo ns32k-sni-sysv
fi
- exit 0 ;;
+ exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
- exit 0 ;;
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
- exit 0 ;;
+ exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
- exit 0 ;;
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
- exit 0 ;;
+ exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
- exit 0 ;;
+ exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit 0 ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
- exit 0 ;;
+ exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
- exit 0 ;;
+ exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
- exit 0 ;;
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Darwin:*:*)
- case `uname -p` in
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
*86) UNAME_PROCESSOR=i686 ;;
- powerpc) UNAME_PROCESSOR=powerpc ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
@@ -1165,22 +1194,25 @@ EOF
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
- exit 0 ;;
- NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
- exit 0 ;;
+ exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
- exit 0 ;;
+ exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
@@ -1191,25 +1223,44 @@ EOF
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
- exit 0 ;;
+ exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
- exit 0 ;;
+ exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
- exit 0 ;;
+ exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
- exit 0 ;;
+ exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
- exit 0 ;;
+ exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
- exit 0 ;;
+ exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
- exit 0 ;;
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1241,7 +1292,7 @@ main ()
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
+ printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
@@ -1330,11 +1381,12 @@ main ()
}
EOF
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
@@ -1343,22 +1395,22 @@ then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
- exit 0 ;;
+ exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit 0 ;;
+ exit ;;
c34*)
echo c34-convex-bsd
- exit 0 ;;
+ exit ;;
c38*)
echo c38-convex-bsd
- exit 0 ;;
+ exit ;;
c4*)
echo c4-convex-bsd
- exit 0 ;;
+ exit ;;
esac
fi
@@ -1369,7 +1421,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- ftp://ftp.gnu.org/pub/gnu/config/
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/tools/osx_packaging/ardour2_mac_ui.rc b/tools/osx_packaging/ardour2_mac_ui.rc
new file mode 100644
index 0000000000..fb739a94b7
--- /dev/null
+++ b/tools/osx_packaging/ardour2_mac_ui.rc
@@ -0,0 +1,1225 @@
+#
+# This is the GTK style file for Ardour
+#
+#
+
+style "very_small_text"
+{
+ font_name = "sans 9"
+}
+
+style "small_text"
+{
+ font_name = "sans 10"
+}
+
+style "small_bold_text"
+{
+ font_name = "sans bold 10"
+}
+
+style "medium_bold_text"
+{
+ font_name = "sans bold 11"
+}
+
+style "medium_text"
+{
+ font_name = "sans 11"
+}
+
+style "red_medium_text" = "medium_text"
+{
+ fg[NORMAL] = { 1.0, 0, 0 }
+ fg[ACTIVE] = { 1.0, 0, 0 }
+ fg[SELECTED] = { 1.0, 0, 0 }
+}
+
+
+style "large_text"
+{
+ font_name = "sans 18"
+}
+
+style "larger_bold_text"
+{
+ font_name = "sans bold 14"
+}
+
+style "plugin_name_text"
+{
+ font_name = "sans bold 25"
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+}
+
+style "plugin_maker_text"
+{
+ font_name = "sans bold 14"
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+}
+
+style "first_action_message"
+{
+ font_name = "sans medium 34"
+}
+
+style "verbose_canvas_cursor"
+{
+ font_name = "sans bold 24"
+}
+
+style "marker_text"
+{
+ font_name = "sans 9"
+}
+
+style "time_axis_view_item_name"
+{
+ font_name = "sans medium 10"
+}
+
+style "default_base" = "medium_text"
+{
+ GtkWidget::cursor_color = {1.0, 1.0, 1.0 }
+ GtkButton::default_border = { 0, 0, 0, 0 }
+ GtkButton::default_outside_border = { 0, 0, 0, 0 }
+ GtkTreeView::vertical-padding = 0
+ GtkTreeView::horizontal-padding = 0
+
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ fg[ACTIVE] = { 0.80, 0.80, 0.80 }
+ fg[PRELIGHT] = { 1.0, 1.0, 1.0 }
+ fg[INSENSITIVE] = { 0.80, 0.80, 0.80 }
+ fg[SELECTED] = { 0.80, 0.80, 0.80 }
+
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+ bg[ACTIVE] = { 0.40, 0.40, 0.40 }
+ bg[PRELIGHT] = "#565690"
+ bg[INSENSITIVE] = { 0.10, 0.10, 0.10 }
+ bg[SELECTED] = { 0, 0.40, 0.60 }
+
+ text[NORMAL] = { 0.80, 0.80, 0.80 }
+ text[ACTIVE] = { 0.80, 0.80, 0.80 }
+ text[PRELIGHT] = { 0.80, 0.80, 0.80 }
+ text[INSENSITIVE] = { 0.80, 0.80, 0.80}
+ text[SELECTED] = { 1.0, 1.0, 1.0 }
+
+ base[ACTIVE] = "#2f272f"
+ base[NORMAL] = "#1c1e21"
+ base[PRELIGHT] = { 0.20, 0.20, 0.20 }
+ base[INSENSITIVE] = "#4c5159"
+ base[SELECTED] = { 0.25, 0.25, 0.25 }
+
+ engine "clearlooks" {
+ menubarstyle = 2 # 0 = flat, 1 = sunken, 2 = flat gradient
+ menuitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient), 2 = 3d-ish (button)
+ listviewitemstyle = 1 # 0 = flat, 1 = 3d-ish (gradient)
+ progressbarstyle = 0 # 0 = candy bar, 1 = flat
+ }
+}
+
+style "base_frame"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+}
+
+style "transport_base" = "medium_bold_text"
+{
+ bg[NORMAL] = { 0.10, 0.10, 0.10 }
+ bg[ACTIVE] = { 0, 0, 0 }
+ bg[PRELIGHT] = { 0, 0, 0 }
+ bg[INSENSITIVE] = { 0, 0, 0 }
+ bg[SELECTED] = { 0, 0, 0 }
+}
+
+style "black_mackie_menu_bar" = "medium_bold_text"
+{
+ font_name = "sans bold 12"
+ fg[NORMAL] = { 1.0, 1.0, 1.0 }
+ bg[NORMAL] = { 0, 0, 0 }
+}
+
+style "default_buttons_menus"
+{
+ font_name = "sans 11"
+ fg[ACTIVE] = { 1.0, 1.0, 1.0 }
+
+ bg[NORMAL] = { 0.35, 0.35, 0.35 }
+ bg[ACTIVE] = "#565690"
+ bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
+ bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
+ bg[SELECTED] = { 0.20, 0.20, 0.20 }
+}
+
+style "very_small_button" = "default_buttons_menus"
+{
+ font_name = "sans 8"
+ ythickness = 0
+ xthickness = 0
+}
+
+style "small_button" = "default_buttons_menus"
+{
+}
+
+style "very_small_red_active_and_selected_button" = "very_small_button"
+{
+ bg[ACTIVE] = { 1.0, 0, 0}
+ bg[SELECTED] = { 1.0, 0, 0}
+}
+
+style "small_red_active_and_selected_button" = "small_button"
+{
+ fg[ACTIVE] = { 0, 0, 0 }
+ bg[ACTIVE] = { 1.0, 0, 0}
+ bg[SELECTED] = { 1.0, 0, 0}
+}
+
+style "track_rec_enable_button" = "small_button"
+{
+ fg[SELECTED] = { 0.0, 0.0, 0.0 }
+ fg[ACTIVE] = { 0.0, 0.0, 0.0 }
+ fg[PRELIGHT] = { 0.0, 0.0, 0.0 }
+
+ bg[SELECTED] = { 1.0, 0.0, 0.0 }
+ bg[ACTIVE] = { 0.91, 0.68, 0.68}
+ bg[PRELIGHT] = { 1.0, 0.0, 0.0 }
+}
+
+style "mixer_rec_enable_button" = "track_rec_enable_button"
+{
+ font_name = "sans 8"
+ xthickness = 0
+ ythickness = 0
+}
+
+style "solo_button" = "small_button"
+{
+ bg[PRELIGHT] = { 0, 1.0, 0 }
+ bg[ACTIVE] = { 0.66, 0.97, 0.19 }
+
+ fg[PRELIGHT] = { 0, 0, 0 }
+ fg[ACTIVE] = { 0, 0, 0 }
+}
+
+style "mixer_solo_button" = "solo_button"
+{
+ font_name = "sans 8"
+ xthickness = 0
+ ythickness = 0
+
+}
+
+
+style "mute_button" = "small_button"
+{
+ bg[PRELIGHT] = { 1.0, 0.65, 0.13 }
+ bg[ACTIVE] = { 1.0, 0.98, 0.53 }
+
+ fg[PRELIGHT] = { 0, 0, 0 }
+}
+
+style "mixer_mute_button" = "mute_button"
+{
+ font_name = "sans 8"
+ xthickness = 0
+ ythickness = 0
+}
+
+style "track_loop_button" = "small_button"
+{
+ bg[ACTIVE] = { 1.0, 0.98, 0.53 }
+ bg[PRELIGHT] = { 1.0, 0.98, 0.53 }
+
+}
+
+style "mixer_red_active_button" = "very_small_button"
+{
+ fg[ACTIVE] = { 0, 1.0, 1.0 }
+ bg[ACTIVE] = { 0.7, 0, 0 }
+
+ base[INSENSITIVE] = { 0.21, 0.21, 0.21 }
+ bg[INSENSITIVE] = { 0.21, 0.21, 0.21 }
+}
+
+style "time_button" = "default_buttons_menus"
+{
+ font_name = "sans 10"
+}
+
+style "default_menus" = "default_buttons_menus"
+{
+ font_name = "sans 11"
+}
+
+style "transport_button"
+{
+ font_name = "sans 9"
+ bg[ACTIVE] = { 0.50, 1.0, 0.50 }
+ fg[ACTIVE] = { 0, 0, 0 }
+}
+
+style "transport_rec_button"
+{
+ bg[ACTIVE] = { 1.0, 0, 0 }
+ bg[PRELIGHT] = { 0.91, 0.68, 0.68 } #blinking rec button color
+}
+
+style "shuttle_control" = "very_small_text"
+{
+ fg[NORMAL] = { 0.85, 0.92, 0.98 }
+ fg[ACTIVE] = { 0.85, 0.92, 0.98 }
+ fg[PRELIGHT] = { 0.85, 0.92, 0.98 }
+ fg[SELECTED] = { 0.85, 0.92, 0.98 }
+ fg[INSENSITIVE] = { 0.85, 0.92, 0.98 }
+
+ bg[NORMAL] = { 0.31, 0.31, 0.31 }
+ bg[PRELIGHT] = { 0.31, 0.31, 0.31 }
+ bg[INSENSITIVE] = { 0.31, 0.31, 0.31 }
+ bg[ACTIVE] = { 0.50, 1.0, 0.50 }
+ bg[SELECTED] = { 1.0, 0.04, 0.04 }
+}
+
+style "ardour_adjusters" = "default_buttons_menus"
+{
+ bg[NORMAL] = { 0.60, 0.60, 0.60 }
+ bg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0.06, 0.06, 0.06 }
+}
+
+style "ardour_progressbars" = "default_buttons_menus"
+{
+ bg[NORMAL] = { 0, 0, 0 }
+ bg[PRELIGHT] = { 0.00, 0.36, 0.40 }
+}
+
+style "options_window" = "default_base"
+{
+ font_name = "sans 11"
+ fg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+}
+
+style "option_entry" = "default_base"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+ fg[INSENSITIVE] = { 0.80, 0.80, 0.80 }
+
+ base[INSENSITIVE] = { 0.12, 0.12, 0.12 }
+
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+ bg[ACTIVE] = { 0.40, 0.40, 0.40 }
+}
+
+style "red_when_active" = "medium_text"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.31, 0.31, 0.31 }
+
+ fg[ACTIVE] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 1.0, 0, 0}
+}
+
+style "xrun_warn"
+{
+ font_name = "sans bold 18"
+
+ fg[NORMAL] = { 1.0, 1.0, 1.0 }
+ fg[ACTIVE] = { 1.0, 1.0, 1.0 }
+ text[NORMAL] = { 1.0, 1.0, 1.0 }
+ text[ACTIVE] = { 1.0, 1.0, 1.0 }
+ base[NORMAL] = { 0.09, 0.48, 0.46 }
+ base[ACTIVE] = { 0.09, 0.48, 0.46 }
+ bg[NORMAL] = { 1.0, 0.48, 0.46 }
+ bg[ACTIVE] = { 0.09, 1.0, 0.46 }
+}
+
+style "menu_bar_base"
+{
+ bg[NORMAL] = { 0, 0, 0 }
+ bg[ACTIVE] = { 0, 0, 0 }
+ bg[PRELIGHT] = { 0, 0, 0 }
+ bg[INSENSITIVE] = { 0, 0, 0 }
+ bg[SELECTED] = { 0, 0, 0 }
+}
+
+style "fatal_message" = "medium_text"
+{
+ fg[ACTIVE] = { 1.0, 0, 1.0 }
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0,0,0 }
+ bg[NORMAL] = { 0,0,0 }
+ base[ACTIVE] = { 0,0,0 }
+ base[NORMAL] = { 0,0,0 }
+}
+
+style "error_message" = "medium_text"
+{
+ fg[ACTIVE] = { 1.0, 0, 0 }
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0,0,0 }
+ bg[NORMAL] = { 0,0,0 }
+ base[ACTIVE] = { 0,0,0 }
+ base[NORMAL] = { 0,0,0 }
+}
+
+style "info_message" = "medium_text"
+{
+ fg[ACTIVE] = { 1.0, 0, 0 }
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0,0,0 }
+ bg[NORMAL] = { 0,0,0 }
+ base[ACTIVE] = { 0,0,0 }
+ base[NORMAL] = { 0,0,0 }
+}
+
+style "warning_message" = "medium_text"
+{
+ fg[ACTIVE] = { 0.30,0.30, 1.0 }
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0, 0, 0 }
+ bg[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[NORMAL] = { 0, 0, 0 }
+}
+
+style "medium_entry" = "medium_text"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+ fg[SELECTED] = { 0.50, 1.0, 0.50 }
+
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0.5, 0.5, 1.0 }
+}
+
+style "medium_entry_noselection_fg" = "medium_entry"
+{
+ fg[SELECTED] = { 0.50, 1.0, 0.50 }
+}
+
+style "medium_entry_noselection_bg" = "medium_entry"
+{
+ bg[SELECTED] = { 0.50, 1.0, 1.0 }
+}
+
+style "medium_bold_entry" = "medium_bold_text"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+}
+
+
+style "small_entry" = "small_text"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+ bg[NORMAL] = { 0.0, 0.0, 0.0 }
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+}
+
+style "red_active_small_entry" = "small_entry"
+{
+ fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+ fg[SELECTED] = { 1.0, 0, 0 }
+}
+
+style "small_bold_entry" = "small_bold_text"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[ACTIVE] = { 0.50, 1.0, 1.0 }
+
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+}
+
+style "small_red_on_black_entry" = "small_bold_text"
+{
+ fg[NORMAL] = { 1.0, 0, 0 }
+ fg[ACTIVE] = { 1.0, 0, 0 }
+ base[NORMAL] = { 0.0, 0.0, 0.0 }
+ base[ACTIVE] = { 0.0, 0.0, 0.0 }
+ bg[NORMAL] = { 0.0, 0.0, 0.0 }
+ bg[ACTIVE] = { 0.0, 0.0, 0.0 }
+}
+
+style "big_clock_display" = "medium_entry"
+{
+ font_name = "courier bold 34"
+}
+
+style "transport_clock_display"
+{
+ font_name = "sans bold 14"
+
+ fg[NORMAL] = { 0.50, 1.0, 0.50 }
+ fg[ACTIVE] = { 1.0, 0, 0.0 }
+ fg[SELECTED] = { 1.0, 0, 0 }
+ fg[PRELIGHT] = { 1.0, 0, 0.0 }
+ fg[INSENSITIVE] = { 1.0, 0, 0.0 }
+
+ base[NORMAL] = { 0.0, 0.0, 0.0 }
+ base[ACTIVE] = { 0.0, 0.0, 0.0 }
+ bg[NORMAL] = { 0.0, 0.0, 0.0 }
+ bg[ACTIVE] = { 0.0, 0.0, 0.0 }
+}
+
+style "tempo_meter_clock_display"
+{
+ font_name = "sans 9"
+ fg[NORMAL] = { 1.0, 1.0, 1.0 }
+ fg[ACTIVE] = { 1.0, 1.0, 0.0 }
+ fg[SELECTED] = { 1.0, 0, 0 }
+ base[NORMAL] = { 0.0, 0.48, 1.0 }
+ base[ACTIVE] = { 0.09, 0.98, 0.46 }
+ bg[NORMAL] = { 0.0, 0.48, 1.0 }
+ bg[ACTIVE] = { 0.09, 0.98, 0.46 }
+}
+
+style "default_clock_display" = "medium text"
+{
+ font_name = "sans 10"
+ fg[NORMAL] = { 0.50, 1.0, 0.50 }
+ fg[ACTIVE] = { 1.0, 0.0, 0.0 }
+ fg[SELECTED] = { 1.0, 0, 0 }
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ bg[NORMAL] = { 0, 0, 0 }
+ bg[ACTIVE] = { 0, 0, 0 }
+}
+
+style "editor_time_ruler" = "small_text"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.09, 0.09, 0.09 }
+}
+
+style "audio_track_base" = "default_base"
+{
+ font_name = "sans 8"
+ fg[NORMAL] = { 0.77, 0.77, 0.72 }
+ bg[NORMAL] = { 0.18, 0.18, 0.22 }
+ bg[ACTIVE] = { 0.20, 0.20, 0.20 }
+ bg[PRELIGHT] = { 0.20, 0.20, 0.20 }
+ bg[INSENSITIVE] = { 0.20, 0.20, 0.20 }
+ bg[SELECTED] = { 0.20, 0.20, 0.20 }
+}
+
+style "audio_bus_base"
+{
+ font_name = "sans 8"
+ fg[NORMAL] = { 0.77, 0.77, 0.72 }
+ fg[NORMAL] = { 0.7, 0.8, 0.2 }
+ #bg[NORMAL] = {0, 0.36, 0.40 }
+ bg[NORMAL] = "#464666"
+}
+
+style "track_name_display"
+{
+ font_name = "sans medium 11"
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ fg[ACTIVE] = { 0.80, 0.80, 0.80 }
+
+ base[NORMAL] = { 0.06, 0.06, 0.06 }
+ base[ACTIVE] = { 0.26, 0.26, 0.26 }
+ bg[NORMAL] = { 0.26, 0.26, 0.26 }
+ bg[ACTIVE] = { 0.26, 0.26, 0.26 }
+}
+
+style "active_track_name_display"
+{
+ font_name = "sans medium 11"
+ text[NORMAL] = { 0.26, 0.26, 0.26 }
+ base[NORMAL] = { 0.89, 0.89, 0.89 }
+}
+
+style "track_separator"
+{
+ bg[NORMAL] = { 0.40, 0.40, 0.40 }
+}
+
+#
+# Track edit groups. These styles define
+# the colors that the "edit" button will
+# use as a track is moved from
+# track edit group to track edit group.
+# There are 8 edit groups. Edit group 0
+# is used for tracks that are not editable,
+# so we leave its style to the default.
+#
+
+style "edit_group_0"
+
+{
+ bg[ACTIVE] = { 1.0, 0.65, 0.13 }
+ bg[NORMAL] = { 0.31, 0.31, 0.31 }
+ fg[NORMAL] = { 0.82, 0.91, 0.99 }
+ fg[ACTIVE] = { 0, 0, 0 }
+}
+
+style "edit_group_1"
+{
+ fg[NORMAL] = { 0, 0, 0 }
+ fg[PRELIGHT] = { 0, 0, 0 }
+ fg[SELECTED] = { 0, 0, 0 }
+ bg[NORMAL] = { 0.93, 0.34, 0.08 }
+ bg[PRELIGHT] = { 0.93, 0.34, 0.08 }
+ bg[SELECTED] = { 0.93, 0.34, 0.08 }
+}
+
+style "edit_group_2"
+{
+ fg[NORMAL] = { 0, 0, 0 }
+ fg[PRELIGHT] = { 0, 0, 0 }
+ fg[SELECTED] = { 0, 0, 0 }
+ bg[NORMAL] = { 0.93, 0.34, 0.08 }
+ bg[PRELIGHT] = { 0.93, 0.34, 0.08 }
+ bg[SELECTED] = { 0.93, 0.34, 0.08 }
+}
+
+style "edit_group_3"
+{
+ fg[NORMAL] = { 0, 0, 0 }
+ fg[PRELIGHT] = { 0, 0, 0 }
+ fg[SELECTED] = { 0, 0, 0 }
+ bg[NORMAL] = { 0.93, 0.34, 0.08 }
+ bg[PRELIGHT] = { 0.93, 0.34, 0.08 }
+ bg[SELECTED] = { 0.93, 0.34, 0.08 }
+}
+
+style "region_list_display" = "small_bold_text"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ fg[ACTIVE] = { 0.80, 0.80, 0.80 }
+ fg[SELECTED] = { 0.50, 1.0, 1.0 }
+ bg[NORMAL] = { 0, 0, 0 }
+ bg[ACTIVE] = { 0, 0, 0 }
+ bg[SELECTED] = { 0, 0, 0 }
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 1, 0 }
+ base[INSENSITIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0.80, 0.80, 0.80 }
+}
+
+style "main_canvas_area"
+{
+ bg[NORMAL] = { 0.38, 0.38, 0.38 }
+ bg[ACTIVE] = { 0.38, 0.38, 0.38 }
+ bg[INSENSITIVE] = { 0.38, 0.38, 0.38 }
+ bg[SELECTED] = { 0.38, 0.38, 0.38 }
+ bg[PRELIGHT] = { 0.38, 0.38, 0.38 }
+}
+
+style "track_controls_inactive"
+{
+ bg[NORMAL] = { 0.60, 0.60, 0.66 }
+ bg[ACTIVE] = { 0.60, 0.60, 0.66 }
+ bg[INSENSITIVE] = { 0.60, 0.60, 0.66 }
+ bg[SELECTED] = { 0.60, 0.60, 0.66 }
+ bg[PRELIGHT] = { 0.60, 0.60, 0.66 }
+
+ font_name = "sans medium 10"
+ fg[NORMAL] = { 0.7, 0.8, 0.2 }
+}
+
+style "edit_controls_base_selected"
+{
+ bg[NORMAL] = { 0.56, 0.56, 0.56 }
+ bg[ACTIVE] = { 0.56, 0.56, 0.56 }
+ bg[INSENSITIVE] = { 0.56, 0.56, 0.56 }
+ bg[SELECTED] = { 0.56, 0.56, 0.56 }
+ bg[PRELIGHT] = { 0.56, 0.56, 0.56 }
+}
+
+style "automation_track_controls_base"
+{
+ bg[NORMAL] = { 0.22, 0.22, 0.29 }
+ bg[ACTIVE] = { 0.22, 0.22, 0.29 }
+ bg[INSENSITIVE] = { 0.22, 0.22, 0.29 }
+ bg[SELECTED] = { 0.22, 0.22, 0.29 }
+ bg[PRELIGHT] = { 0.22, 0.22, 0.29 }
+}
+
+# Plugin Editors
+style "plugin_slider"
+{
+ font_name ="sans bold 10"
+
+ # the slider itself. the inactive part is INSENSITIVE,
+ # the active part is something else.
+
+ fg[NORMAL] = { 0.37, 0.43, 0.52 }
+ fg[ACTIVE] = { 0.37, 0.43, 0.52 }
+ fg[INSENSITIVE] = {0.40, 0.40, 0.40 } # matches default_base
+ fg[SELECTED] = { 0.37, 0.43, 0.52 }
+ fg[PRELIGHT] = { 0.37, 0.43, 0.52 }
+
+ # draws the outer rectangle around the slider
+
+ bg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 0.80, 0.80, 0.80 }
+ bg[INSENSITIVE] = {0.80, 0.80, 0.80 }
+ bg[SELECTED] = { 0.80, 0.80, 0.80 }
+ bg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+
+ # the numeric display
+
+ text[NORMAL] = { 0.80, 0.80, 0.80 }
+ text[ACTIVE] = { 0.80, 0.80, 0.80 }
+ text[INSENSITIVE] = { 0.80, 0.80, 0.80 }
+ text[SELECTED] = { 0.80, 0.80, 0.80 }
+ text[PRELIGHT] = { 0.80, 0.80, 0.80 }
+}
+
+style "track_list_display" = "small_bold_text"
+{
+ text[NORMAL] = { 0.80, 0.80, 0.80 }
+ text[ACTIVE] = { 0.3, 0.3, 0.3 }
+ text[INSENSITIVE] = { 0, 0, 0 }
+ text[SELECTED] = { 0.8, 0.8, 0.8 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[INSENSITIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+}
+
+style "inspector_track_list_display" = "track_list_display"
+{
+ text[ACTIVE] = { 0.8, 0.8, 0.8 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0.2, 0.2, 0.2 }
+ base[INSENSITIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0.3, 0.3, 0.4 }
+}
+
+style "redirect_list_display"
+{
+ GtkTreeView::horizontal-separator = 0
+ GtkTreeView::vertical-separator = 0
+
+ font_name = "sans 10"
+ text[NORMAL] = { 0.80, 0.80, 0.80 }
+ text[ACTIVE] = { 0.5, 0.5, 0.9 }
+ text[INSENSITIVE] = { 0, 0, 0 }
+ text[SELECTED] = { 0.9, 0.3, 0.3 }
+
+ base[NORMAL] = { 0, 0, 0 }
+ base[ACTIVE] = { 0, 0, 0 }
+ base[INSENSITIVE] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+
+ # these two are explicitly used by the cell renderer for the
+ # text
+
+ fg[NORMAL] = { 0.5, 0.5, 0.5 } # used for inactive
+ fg[ACTIVE] = { 0.5, 1.0, 1.0 } # used for active
+}
+
+style "inspector_redirect_list_display" = "redirect_list_display"
+{
+ base[SELECTED] = { 0.3, 0.3, 0.3 }
+}
+
+# MixerPanZone:
+#
+# the NORMAL fg color is used for the pan puck
+# the ACTIVE fg color is used for the speaker boxes
+
+style "pan_zone" = "default_base"
+{
+ fg[NORMAL] = { 0.34, 0.95, 0.92 }
+ fg[ACTIVE] = { 0.95, 0.48, 0.11 }
+}
+
+style "wall_clock" = "medium_bold_text"
+{
+ fg[NORMAL] = { 1.0, 1.0, 1.0 }
+ bg[NORMAL] = { 0, 0, 0 }
+}
+
+style "paler_red_when_active" = "medium_text"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ fg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.31, 0.31, 0.31 }
+ bg[PRELIGHT] = { 0.31, 0.31, 0.31 }
+
+ fg[ACTIVE] = { 0.36, 0.46, 0.28 }
+ bg[ACTIVE] = { 1.00, 0.59, 0.59}
+}
+
+style "peak_display_peaked_entry" = "small_text"
+{
+ fg[NORMAL] = { 1.0, 1.0, 1.0 }
+ fg[ACTIVE] = { 1.0, 1.0, 1.0 }
+ fg[SELECTED] = { 1.0, 1.0, 1.0 }
+
+ bg[NORMAL] = {0.9, 0.0, 0.0 }
+ bg[ACTIVE] = { 0.9, 0.0, 0.0 }
+ bg[PRELIGHT] = { 0.9, 0.0, 0.0 }
+ bg[INSENSITIVE] = { 0.9, 0.0, 0.0 }
+ bg[SELECTED] = { 0.9, 0.0, 0.0 }
+ base[NORMAL] = { 0.9, 0.0, 0.0 }
+ base[ACTIVE] = { 0.9, 0.0, 0.0 }
+ base[PRELIGHT] = { 0.9, 0.0, 0.0 }
+ base[INSENSITIVE] = { 0.9, 0.0, 0.0 }
+ base[SELECTED] = { 0.9, 0.0, 0.0 }
+}
+
+style "selected_strip_frame"
+{
+ fg[NORMAL] = { 0.74, 0.42, 0.47 }
+ bg[NORMAL] = { 0.79, 0.28, 0.18 }
+}
+
+style "flashing_alert" = "very_small_text"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.31, 0.31, 0.31 }
+
+ fg[ACTIVE] = { 0.80, 0.80, 0.80 }
+ bg[ACTIVE] = { 1.0, 0, 0}
+}
+
+style "selected_io_selector_port_list" = "medium_text"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ fg[SELECTED] = { 0.50, 1.0, 1.0 }
+ base[NORMAL] = { 0, 0, 0 }
+ base[SELECTED] = { 0, 0, 0 }
+}
+
+style "io_selector_port_list" = "medium_text"
+{
+ fg[NORMAL] = {0.80, 0.80, 0.70 }
+ fg[SELECTED] = {0.80, 0.80, 0.70 }
+ base[NORMAL] = { 0.26, 0.26, 0.26 }
+ base[SELECTED] = { 0.26, 0.26, 0.26 }
+}
+
+style "io_selector_notebook" = "default_base"
+{
+ fg[NORMAL] = { 0.50, 1.0, 1.0 }
+ font_name ="sans bold 10"
+}
+
+style "tearoff_arrow" = "medium_bold_entry"
+{
+ fg[NORMAL] = { 0.80, 0.80, 0.80 }
+ fg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+ bg[NORMAL] = { 0.80, 0.80, 0.80 }
+ bg[PRELIGHT] = { 0.80, 0.80, 0.80 }
+}
+
+style "meter_metrics_strip" = "default_base"
+{
+ font_name = "sans 5"
+ fg[NORMAL] = { 1.0, 0.8, 0.2 }
+}
+
+style "location_row_button" = "default_buttons_menus"
+{
+ font_name = "sans 10"
+}
+
+style "location_rows_clock" = "default_clock_display"
+{
+ font_name = "sans 12"
+}
+
+style "pan_slider"
+{
+ font_name = "sans 8"
+
+ fg[NORMAL] = { 0.67, 0.23, 0.22 }
+ fg[ACTIVE] = { 0.67, 0.23, 0.22 }
+ fg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+ fg[SELECTED] = { 0.67, 0.23, 0.22 }
+ fg[PRELIGHT] = { 0.67, 0.23, 0.22 }
+
+ bg[NORMAL] = { 0, 0, 0 }
+ bg[ACTIVE] = { 0, 0, 0 }
+ bg[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+ bg[SELECTED] = { 0, 0, 0 }
+ bg[PRELIGHT] = { 0, 0, 0 }
+
+ text[NORMAL] = { 0.85, 0.92, 0.98 }
+ text[ACTIVE] = { 0.85, 0.92, 0.98 }
+ text[INSENSITIVE] = { 0.85, 0.92, 0.98 }
+ text[SELECTED] = { 0.85, 0.92, 0.98 }
+ text[PRELIGHT] = { 0.85, 0.92, 0.98 }
+}
+
+style "region_list_whole_file"
+{
+ fg[NORMAL] = { 0.4, 0.4, 0.9 }
+}
+
+style "ardour_button" ="default_buttons_menus"
+{
+ xthickness = 1
+ ythickness = 1
+}
+
+#---------------------------------------------------------------
+widget "*FirstActionMessage" style "first_action_message"
+widget "*VerboseCanvasCursor" style "verbose_canvas_cursor"
+widget "*MarkerText" style "marker_text"
+widget "*TimeAxisViewItemName" style "time_axis_view_item_name"
+#widget "*ExportProgress" style "default_buttons_menus"
+widget "*ExportFileLabel" style "small_bold_text"
+widget "*ExportFormatLabel" style "medium_bold_text"
+widget "*ExportHeader" style "small_bold_text"
+widget "*ExportFileDisplay" style "medium_entry"
+widget "*ExportFormatDisplay" style "medium_entry"
+widget "*ExportCheckbox" style "small_entry"
+widget "*ExportTrackSelector*" style "medium_entry_noselection_bg"
+widget "*EditModeSelector" style "medium_bold_entry"
+widget "*SnapTypeSelector" style "medium_bold_entry"
+widget "*SnapModeSelector" style "medium_bold_entry"
+widget "*ZoomFocusSelector" style "medium_bold_entry"
+widget "*ArdourContextMenu*" style "default_menus"
+widget "*EditGroupTitleButton*" style "default_buttons_menus"
+widget "*MixerGroupTitleButton*" style "default_buttons_menus"
+widget "*ErrorLogCloseButton" style "default_buttons_menus"
+widget "*EditorGTKButton*" style "default_buttons_menus"
+widget "*ToolbarButton" style "default_buttons_menus"
+widget "*ToolbarButton*" style "default_buttons_menus"
+widget "*CrossfadeEditButton" style "default_buttons_menus"
+widget "*CrossfadeEditButton*" style "default_buttons_menus"
+widget "*TrackHistoryButton*" style "default_buttons_menus"
+widget "*TrackSizeButton*" style "default_buttons_menus"
+widget "*TrackPlaylistButton*" style "default_buttons_menus"
+widget "*TrackAutomationButton*" style "default_buttons_menus"
+widget "*TrackGroupButton*" style "default_buttons_menus"
+widget "*TrackMixButton*" style "default_buttons_menus"
+widget "*TrackVisualButton*" style "default_buttons_menus"
+widget "*TrackRemoveButton*" style "default_buttons_menus"
+widget "*BaseButton" style "default_buttons_menus"
+widget "*TakeButtonLabel" style "default_buttons_menus"
+widget "*MixerWidthButton" style "default_buttons_menus"
+widget "*MixerHideButton" style "default_buttons_menus"
+widget "*MixerSendButton" style "default_buttons_menus"
+widget "*MixerSendButtonLabel" style "default_buttons_menus"
+widget "*MixerSendSwitch" style "default_buttons_menus"
+widget "*MixerInsertButton" style "default_buttons_menus"
+widget "*MixerInsertButtonLabel" style "default_buttons_menus"
+widget "*MixerInsertSwitch" style "default_buttons_menus"
+widget "*MixerMonitorInputButton*" style "very_small_button"
+widget "*MixerMonitorInputButton.*" style "very_small_button"
+widget "*MixerIOButton" style "very_small_button"
+widget "*MixerIOButtonLabel" style "very_small_button"
+widget "*AddRouteDialogSpinner" style "ardour_adjusters"
+widget "*AddRouteDialogRadioButton*" style "options_window"
+widget "*OptionsNotebook" style "options_window"
+widget "*OptionEditorToggleButton*" style "options_window"
+widget "*OptionsLabel" style "options_window"
+widget "*OptionEditorAuditionerLabel" style "options_window"
+widget "*OptionsEntry" style "option_entry"
+widget "*InspectorNotebook" style "options_window"
+widget "*NewSessionDialog" style "options_window"
+widget "*NewSessionDialogButton*" style "options_window"
+widget "*MixerSendSwitch*" style "very_small_red_active_and_selected_button"
+widget "*OptionEditorToggleButton" style "small_red_active_and_selected_button"
+widget "*NewSessionDialogButton" style "small_red_active_and_selected_button"
+widget "*MixerRecordEnableButton" style "mixer_rec_enable_button"
+widget "*MixerRecordEnableButton*" style "mixer_rec_enable_button"
+widget "*TrackRecordEnableButton" style "track_rec_enable_button"
+widget "*TrackRecordEnableButton*" style "track_rec_enable_button"
+widget "*TrackMuteButton*" style "mute_button"
+widget "*TrackLoopButton*" style "track_loop_button"
+widget "*EditorTimeButton*" style "time_button"
+widget "*EditorMixerButton*" style "default_buttons_menus"
+widget "*SoloButton*" style "solo_button"
+widget "*SoloButton.*" style "solo_button"
+widget "*SafeSoloButton*" style "solo_button"
+widget "*SafeSoloButton.*" style "solo_button"
+widget "*MixerPhaseInvertButton*" style "very_small_button"
+widget "*MixerPhaseInvertButton.*" style "very_small_button"
+widget "*MixerAutomationRecordingButton*" style "very_small_button"
+widget "*MixerAutomationRecordingButton.*" style "very_small_button"
+widget "*MixerAutomationModeButton*" style "very_small_button"
+widget "*MixerAutomationModeButton.*" style "very_small_button"
+widget "*MixerAutomationPlaybackButton*" style "very_small_button"
+widget "*MixerAutomationPlaybackButton.*" style "very_small_button"
+widget "*MixerMuteButton*" style "mixer_mute_button"
+widget "*MixerMuteButton.*" style "mixer_mute_button"
+widget "*MixerSoloButton*" style "mixer_solo_button"
+widget "*MixerSoloButton.*" style "mixer_solo_button"
+widget "*MixerNameButton" style "very_small_button"
+widget "*MixerNameButtonLabel" style "very_small_button"
+widget "*MixerGroupButton" style "very_small_button"
+widget "*MixerGroupButtonLabel" style "very_small_button"
+widget "*MixerCommentButton" style "very_small_button"
+widget "*MixerCommentButton*" style "very_small_button"
+widget "*EditGroupButton" style "very_small_button"
+widget "*EditGroupButtonLabel" style "very_small_button"
+widget "*TransportButton" style "transport_button"
+widget "*TransportButton*" style "transport_button"
+widget "*ShuttleButton" style "transport_button"
+widget "*ShuttleButton*" style "transport_button"
+widget "*ShuttleDisplay" style "transport_button"
+widget "*ShuttleDisplay*" style "transport_button"
+widget "*ShuttleControl" style "shuttle_control"
+widget "*TransportRecButton" style "transport_rec_button"
+widget "*TransportRecButton*" style "transport_rec_button"
+widget "*RecordingXrunWarningWindow" style "xrun_warn"
+widget "*RecordingXrunWarningWindow*" style "xrun_warn"
+widget "*MainMenuBar" style "menu_bar_base"
+widget "*ErrorMessage" style "error_message"
+widget "*FatalMessage" style "fatal_message"
+widget "*InfoMessage" style "info_message"
+widget "*WarningMessage" style "warning_message"
+widget "*BigClockDisplay" style "big_clock_display"
+widget "*TransportClockDisplay" style "transport_clock_display"
+widget "*SecondaryClockDisplay" style "transport_clock_display"
+widget "*BBTTempoLabel" style "tempo_meter_clock_display"
+widget "*BBTMeterLabel" style "tempo_meter_clock_display"
+widget "*SelectionStartClock" style "default_clock_display"
+widget "*SelectionEndClock" style "default_clock_display"
+widget "*EditCursorClock" style "default_clock_display"
+widget "*PreRollClock" style "default_clock_display"
+widget "*PostRollClock" style "default_clock_display"
+widget "*NudgeClock" style "default_clock_display"
+widget "*ZoomRangeClock" style "default_clock_display"
+widget "*SMPTEOffsetClock" style "default_clock_display"
+widget "*TransportLabel" style "small_bold_text"
+widget "*TakeLabel" style "small_bold_text"
+widget "*LocationLabel" style "small_bold_text"
+widget "*WipeLabel" style "small_bold_text"
+widget "*TakeTagLabel" style "small_bold_text"
+widget "*ToolBarLabel" style "small_bold_text"
+widget "*EditorDisplayLabel" style "small_bold_text"
+widget "*NewSessionLabel" style "large_text"
+widget "*GlobalButtonLabel" style "default_buttons_menus"
+widget "*ClickButton" style "medium_entry"
+widget "*RegionNameDisplay" style "medium_entry"
+widget "*PluginDisplay" style "medium_entry"
+widget "*SelectionDisplay" style "medium_entry"
+widget "*HistorySelector" style "medium_entry"
+widget "*LocationSelector" style "medium_entry"
+widget "*TakeSelector" style "medium_entry"
+widget "*RegionSelector" style "medium_entry"
+widget "*SMPTERuler" style "editor_time_ruler"
+widget "*BBTRuler" style "editor_time_ruler"
+widget "*FramesRuler" style "editor_time_ruler"
+widget "*MinSecRuler" style "editor_time_ruler"
+widget "*BaseFrame" style "base_frame"
+widget "*AudioTrackStripBase" style "audio_track_base"
+widget "*TimeAxisViewControlsBaseUnselected" style "audio_track_base"
+widget "*AudioTrackControlsBaseUnselected" style "audio_track_base"
+widget "*AudioTrackFader" style "audio_track_base"
+widget "*AudioBusStripBase" style "audio_bus_base"
+widget "*BusControlsBaseUnselected" style "audio_bus_base"
+widget "*AudioBusFader" style "audio_bus_base"
+widget "*TrackSeparator" style "track_separator"
+widget "*TrackEditIndicator0*" style "edit_group_0"
+widget "*TrackEditIndicator1*" style "edit_group_1"
+widget "*TrackEditIndicator2*" style "edit_group_2"
+widget "*TrackEditIndicator3*" style "edit_group_3"
+widget "*TrackEditIndicator4*" style "edit_group_3"
+widget "*TrackEditIndicator5*" style "edit_group_3"
+widget "*TrackEditIndicator6*" style "edit_group_3"
+widget "*TrackEditIndicator7*" style "edit_group_3"
+widget "*EditorTrackNameDisplay" style "track_name_display"
+widget "*EditorTrackNameDisplay*" style "track_name_display"
+widget "*EditorActiveTrackNameDisplay" style "active_track_name_display"
+widget "*EditorActiveTrackNameDisplay*" style "active_track_name_display"
+widget "*EditorRegionList" style "region_list_display"
+widget "*CrossfadeEditAuditionButton" style "red_when_active"
+widget "*CrossfadeEditAuditionButton*" style "red_when_active"
+widget "*CrossfadeEditCurveButton" style "red_when_active"
+widget "*CrossfadeEditCurveButton*" style "red_when_active"
+widget "*CrossfadeEditLabel" style "medium_text"
+widget "*CrossfadeEditFrame" style "base_frame"
+widget "*MouseModeButton" style "default_buttons_menus"
+widget "*MouseModeButton*" style "default_buttons_menus"
+widget "*EditorMainCanvas" style "main_canvas_area"
+widget "*AudioTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
+widget "*BusControlsBaseInactiveUnselected" style "track_controls_inactive"
+widget "*AutomationTrackControlsBaseInactiveUnselected" style "track_controls_inactive"
+widget "*AudioTrackControlsBaseInactiveSelected" style "track_controls_inactive"
+widget "*BusControlsBaseInactiveSelected" style "track_controls_inactive"
+widget "*AutomationTrackControlsBaseInactiveSelected" style "track_controls_inactive"
+widget "*AudioTrackStripBaseInactive" style "track_controls_inactive"
+widget "*AudioBusStripBaseInactive" style "track_controls_inactive"
+widget "*AudioTrackControlsBaseSelected" style "edit_controls_base_selected"
+widget "*BusControlsBaseSelected" style "edit_controls_base_selected"
+widget "*AutomationTrackControlsBase" style "automation_track_controls_base"
+widget "*AutomationTrackControlsBaseSelected" style "edit_controls_base_selected"
+widget "*EditorMenuBar*" style "black_mackie_menu_bar"
+widget "*MainMenuBar*" style "black_mackie_menu_bar"
+widget "*ZoomClickBox" style "medium_bold_entry"
+widget "*PluginParameterLabel" style "medium_text"
+widget "*PluginNameInfo" style "plugin_name_text"
+widget "*PluginMakerInfo" style "plugin_maker_text"
+widget "*PluginParameterInfo" style "medium_text"
+widget "*MotionControllerValue" style "medium_entry"
+widget "*ParameterValueDisplay" style "medium_bold_entry"
+widget "*PluginUIClickBox" style "medium_bold_entry"
+widget "*PluginUIClickBox*" style "medium_bold_entry"
+widget "*PluginSlider" style "plugin_slider"
+widget "*TrackListDisplay" style "track_list_display"
+widget "*TrackListDisplay.*" style "small_bold_text"
+widget "*EditGroupList" style "track_list_display"
+widget "*RegionListDisplay" style "small_bold_entry"
+widget "*RegionListDisplay.*" style "small_bold_text"
+widget "*RedirectSelector" style "redirect_list_display"
+widget "*RedirectSelector.*" style "redirect_list_display"
+widget "*MixerTrackCommentArea" style "option_entry"
+widget "*MixerPanZone" style "pan_zone"
+widget "*MixerTrackDisplayList" style "track_list_display"
+widget "*MixerSnapshotDisplayList" style "track_list_display"
+widget "*MixerAuxDisplayList" style "track_list_display"
+widget "*MixerGroupList" style "track_list_display"
+widget "*WallClock" style "wall_clock"
+widget "*CPULoad" style "wall_clock"
+widget "*RegionEditorLabel" style "medium_text"
+widget "*RegionEditorSmallLabel" style "small_text"
+widget "*RegionEditorEntry" style "medium_entry"
+widget "*RegionEditorClock" style "default_clock_display"
+widget "*RegionEditorToggleButton" style "paler_red_when_active"
+widget "*RegionEditorToggleButton*" style "paler_red_when_active"
+widget "*MixerStripSpeedBase" style "small_entry"
+widget "*MixerStripSpeedBase*" style "small_entry"
+widget "*MixerStripSpeedBaseNotOne" style "small_red_on_black_entry"
+widget "*MixerStripSpeedBaseNotOne*" style "small_red_on_black_entry"
+widget "*MixerStripGainDisplay" style "small_entry"
+widget "*MixerStripGainUnitButton" style "very_small_button"
+widget "*MixerStripGainUnitButton*" style "very_small_button"
+widget "*MixerStripMeterPreButton" style "very_small_button"
+widget "*MixerStripMeterPreButton*" style "very_small_button"
+widget "*MixerStripPeakDisplay*" style "red_active_small_entry"
+widget "*MixerStripPeakDisplayPeak*" style "peak_display_peaked_entry"
+widget "*MixerStripSelectedFrame" style "selected_strip_frame"
+widget "*MixerStripFrame" style "base_frame"
+widget "*HWMonitorButton" style "red_when_active"
+widget "*HWMonitorButton*" style "red_when_active"
+widget "*BypassButton" style "red_when_active"
+widget "*BypassButton*" style "red_when_active"
+widget "*TransportSoloAlert" style "flashing_alert"
+widget "*TransportSoloAlert.*" style "flashing_alert"
+widget "*TransportAuditioningAlert" style "flashing_alert"
+widget "*TransportAuditioningAlert.*" style "flashing_alert"
+widget "*FadeCurve" style "medium_bold_entry"
+widget "*FadeCurve*" style "medium_bold_entry"
+widget "*IOSelectorButton" style "default_buttons_menus"
+widget "*IOSelectorButton*" style "default_buttons_menus"
+widget "*IOSelectorList" style "medium_entry_noselection_fg"
+widget "*IOSelectorPortList" style "io_selector_port_list"
+widget "*IOSelectorPortListSelected" style "selected_io_selector_port_list"
+widget "*IOSelectorNotebook" style "io_selector_notebook"
+widget "*IOSelectorNotebookTab" style "io_selector_notebook"
+widget "*IOSelectorFrame" style "base_frame"
+widget "*ConnectionEditorButton" style "default_buttons_menus"
+widget "*ConnectionEditorButton*" style "default_buttons_menus"
+widget "*ConnectionEditorList" style "medium_entry_noselection_fg"
+widget "*ConnectionEditorConnectionList" style "medium_entry"
+widget "*ConnectionEditorPortList" style "io_selector_port_list"
+widget "*ConnectionEditorPortListSelected" style "selected_io_selector_port_list"
+widget "*ConnectionEditorNotebook" style "io_selector_notebook"
+widget "*ConnectionEditorNotebookTab" style "io_selector_notebook"
+widget "*ConnectionEditorFrame" style "base_frame"
+widget "*RouteParamsListDisplay" style "inspector_track_list_display"
+widget "*RouteParamsPreListDisplay" style "inspector_redirect_list_display"
+widget "*RouteParamsPostListDisplay" style "inspector_redirect_list_display"
+widget "*TearOffArrow" style "tearoff_arrow"
+widget "*RouteParamsTitleButton" style "medium_text"
+widget "*RouteParamsTitleLabel" style "medium_text"
+widget "*PluginAutomateRecordButton" style "small_red_active_and_selected_button"
+widget "*PluginAutomateRecordButton*" style "small_red_active_and_selected_button"
+widget "*PluginAutomatePlayButton" style "small_red_active_and_selected_button"
+widget "*PluginAutomatePlayButton*" style "small_red_active_and_selected_button"
+widget "*PluginAutomateButton" style "small_button"
+widget "*PluginAutomateButton*" style "small_button"
+widget "*PluginSaveButton" style "small_button"
+widget "*PluginSaveButton*" style "small_button"
+widget "*PluginLoadButton" style "small_button"
+widget "*PluginLoadButton*" style "small_button"
+widget "*FaderMetricsStrip" style "meter_metrics_strip"
+widget "*MeterMetricsStrip" style "meter_metrics_strip"
+widget "*MetricDialogFrame" style "base_frame"
+widget "*MetricEntry" style "medium_bold_entry"
+widget "*MetricButton" style "default_buttons_menus"
+widget "*MetricButton.*" style "default_buttons_menus"
+widget "*MetricLabel" style "medium_text"
+widget "*TimeStretchButton" style "default_buttons_menus"
+widget "*TimeStretchButton.*" style "default_buttons_menus"
+widget "*TimeStretchProgress" style "default_buttons_menus"
+widget "*ChoiceWindow" style "default_buttons_menus"
+widget "*ChoicePrompt" style "default_buttons_menus"
+widget "*ChoiceButton" style "default_buttons_menus"
+widget "*ChoiceButton*" style "default_buttons_menus"
+widget "*SelectionModeButton" style "default_buttons_menus"
+widget "*SelectionModeButton*" style "default_buttons_menus"
+widget "*TrackLabel" style "medium_text"
+widget "*TrackPlugName" style "medium_text"
+widget "*TrackParameterName" style "small_text"
+widget "*AddRouteDialog*" style "medium_text"
+widget "*AddRouteDialog.GtkLabel" style "medium_text"
+widget "*AddRouteDialogChannelChoice" style "medium_bold_entry"
+widget "*AddRouteDialogSpinner" style "medium_bold_entry"
+widget "*AddRouteDialogSpinner*" style "medium_bold_entry"
+widget "*AddRouteDialogRadioButton" style "red_when_active"
+widget "*AddRouteDialogButton" style "default_buttons_menus"
+widget "*AddRouteDialogNameTemplateEntry" style "medium_bold_entry"
+widget "*NewSessionIOLabel" style "larger_bold_text"
+widget "*NewSessionSR1Label" style "red_medium_text"
+widget "*NewSessionSR2Label" style "medium_text"
+widget "*NewSessionChannelChoice" style "medium_bold_entry"
+widget "*NewSessionMainButton" style "larger_bold_text"
+widget "*NewSessionMainButton*" style "larger_bold_text"
+widget "*NewSessionMainLabel" style "larger_bold_text"
+widget "*LocationEditRowClock" style "location_rows_clock"
+widget "*LocationEditNameLabel" style "medium_text"
+widget "*LocationEditSetButton" style "location_row_button"
+widget "*LocationEditSetButton*" style "location_row_button"
+widget "*LocationEditGoButton" style "location_row_button"
+widget "*LocationEditGoButton*" style "location_row_button"
+widget "*LocationEditCdButton" style "small_red_active_and_selected_button"
+widget "*LocationEditCdButton*" style "small_red_active_and_selected_button"
+widget "*LocationEditHideButton" style "small_red_active_and_selected_button"
+widget "*LocationEditHideButton*" style "small_red_active_and_selected_button"
+widget "*LocationEditNumberLabel" style "small_text"
+widget "*LocationLocEditorFrame" style "base_frame"
+widget "*LocationRangeEditorFrame" style "base_frame"
+widget "*LocationEditNameEntry" style "option_entry"
+widget "*LocationAddLocationButton" style "default_buttons_menus"
+widget "*LocationAddLocationButton*" style "default_buttons_menus"
+widget "*LocationAddRangeButton" style "default_buttons_menus"
+widget "*LocationAddRangeButton*" style "default_buttons_menus"
+widget "*LocationEditRemoveButton" style "location_row_button"
+widget "*LocationEditRemoveButton*" style "location_row_button"
+widget "*PanSlider" style "pan_slider"
+widget "*PanningLinkButton" style "mixer_red_active_button"
+widget "*PanningLinkButton.*" style "mixer_red_active_button"
+widget "*PanningLinkDirectionButton" style "very_small_button"
+widget "*PanningLinkDirectionButton.*" style "very_small_button"
+widget "*ChannelCountSelector" style "medium_bold_entry"
+widget "*ChannelCountSelector.GtkArrow" style "default_buttons_menus"
+widget "*RegionListWholeFile" style "region_list_whole_file"
+
+class "GtkWidget" style "default_base"
+class "GtkScrollbar" style "ardour_adjusters"
+class "GtkLabel" style "default_buttons_menus"
+class "GtkButton" style "ardour_button"
+class "GtkArrow" style "tearoff_arrow"
+class "GtkProgressBar" style "ardour_progressbars"
+
diff --git a/vst/SConscript b/vst/SConscript
index fead9ba512..a711a1386d 100644
--- a/vst/SConscript
+++ b/vst/SConscript
@@ -17,8 +17,8 @@ winmain.c
"""
)
-ardour_vst.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst", LIBPATH='#gtk2_ardour')
-ardour_vst.Append (LINKFLAGS='-L/usr/X11R6/lib -lasound -lardourgtk -lX11 -lpthread')
+ardour_vst.Append (CCFLAGS="-DVST_SUPPORT", CPPPATH="#libs/fst", LIBPATH='#gtk2_ardour', LIBS="ardourgtk")
+ardour_vst.Append (LINKFLAGS='-L/usr/X11R6/lib -lasound -lX11 -lpthread')
ardour_vst["CC"] ="winegcc"
ardour_vst["LINK"] ="wineg++ -mwindows"
@@ -27,7 +27,7 @@ ardour_vst.Merge ([
libraries['ardour_cp'],
libraries['gtkmm2ext'],
libraries['midi++2'],
- libraries['pbd3'],
+ libraries['pbd'],
libraries['gtkmm2'],
libraries['glib2'],
libraries['libgnomecanvas2'],