Compare commits

...

143 Commits
8.6 ... master

Author SHA1 Message Date
Robin Gareus 9d046af47a Update Lua allocator for sessions scripts
* increase memory pool (bindings alone require 1.5 MB), and all session
  scripts have a shared memory pool.
* use TLSF (like Lua DSP processors) - this fixes an issue with atomics
  (notably int62_t, temporal) on macOS and ARM, which need to be
  aligned.
2024-05-15 20:18:21 +02:00
Robin Gareus afb519cd84
Bump required boost version to 1.68 (for optional::has_value) 2024-05-15 18:50:17 +02:00
Robin Gareus 1f0ee56726
Fix Lua Session scripts (amend df12126909) 2024-05-15 17:33:59 +02:00
Robin Gareus b3df8ea6ef
Expose UI config fonts to libwidgets
Currently this is only for the benefit of derivative projects.
2024-05-15 17:02:35 +02:00
agfline fc1377ae46
AAF: set session name from AAF filename instead of AAF composition name
https://github.com/agfline/LibAAF/issues/5#issuecomment-1952193515
2024-05-15 04:51:36 +02:00
Robin Gareus 7b75748299
Revert "As we've yet to implement user options, let's prefer AAF filenames rather than extracting an internal Comp name"
This reverts commit 2e55f4452f.
2024-05-15 04:49:43 +02:00
Robin Gareus 0bac1e07f5
There is no TraxLive here (amend a0e2749) 2024-05-15 03:35:23 +02:00
Robin Gareus a0e27495c6
Abstract base class for ArdourFader
This allows derivative projects to use other fader
render implementations.
2024-05-15 02:41:37 +02:00
Robin Gareus dad32d8b11
Clean up slider-controller includes 2024-05-14 23:41:51 +02:00
Robin Gareus 3c524098b4
Fix CC event for DM10-mkII Plugin 2024-05-14 22:07:31 +02:00
Paul Davis 86c3b70c54 add some utility functions to Buffers and BufferSets to allow some kinds of debugging easily 2024-05-14 12:25:58 -06:00
Robin Gareus ac47688023
Add Lua plugin to map DM10-mkII Studio HiHat MIDI messages 2024-05-14 17:20:52 +02:00
Robin Gareus 5b02561573
Fix MIDI Tracer (print polypress value) 2024-05-14 17:20:01 +02:00
Robin Gareus e75ad3399e
Fix BBT marker calculation when removing time 2024-05-14 03:20:04 +02:00
Robin Gareus aa55bf35eb
Catch issues with invalid region vs. source length
e.g. the session from
https://tracker.ardour.org/view.php?id=9704#c28732
2024-05-14 02:12:45 +02:00
Robin Gareus caae3501ec
TransportMasterWidget may not have a session
Other parts in this dialog already test for session == nullptr.
This can happen in the Preferences, when switching a timecode
master w/o a session (not possible in Ardour, but some derivative
project).
2024-05-13 23:11:43 +02:00
Paul Davis c3eb30d96b action group names must not be translatable 2024-05-13 15:08:53 -06:00
Robin Gareus 6b8018d927
Indicate remaining record time for FLAC with >= 2024-05-13 21:54:18 +02:00
Robin Gareus 68d3be8918
Support querying disk space for disks > 16TB
under the hood `fsblkcnt_t` is used.
2024-05-13 21:32:10 +02:00
Robin Gareus 1b1d6e767b
Include YTK in doxygen doc 2024-05-13 20:09:30 +02:00
Paul Davis 2f32a22a4d Revert "ensure that the master send is directly before the main outs."
MasterSends are not (currently) part of Ardour.

This reverts commit dcdcaf4b47.
2024-05-10 15:16:13 -06:00
Paul Davis 384739aa80 Revert "fix for metering of a MasterSend (internal send)"
MasterSends are not (currently) part of Ardour.

This reverts commit de1a425704.
2024-05-10 15:15:32 -06:00
Paul Davis fce1f15a87 avoid timecnt_t exception when loading a region with an excessively long length
This is not a fix for whatever underlying problem causes this, but it does allow sessions to load
when the faulty region(s) are not in use
2024-05-10 08:36:06 -06:00
Paul Davis dcdcaf4b47 ensure that the master send is directly before the main outs. 2024-05-10 08:35:03 -06:00
Paul Davis b929e8a4e2 revert inadvertently committed change made for debugging. 2024-05-10 08:35:03 -06:00
Paul Davis de1a425704 fix for metering of a MasterSend (internal send)
Metering for these sends should be effectively PostFader not Output,
and should not reflect the impact of solo & mute.
2024-05-10 08:35:03 -06:00
Paul Davis edc03002eb for DEBUG::Processors, use display_name() not name()
This allows us to differentiate between different instances of the same
type of processor (e.g. Trim vs Fader, which are both of type Amp)
2024-05-10 08:35:03 -06:00
John Emmas 2e55f4452f As we've yet to implement user options, let's prefer AAF filenames rather than extracting an internal Comp name
This helps to avoid situations where 2 x unrelated AAF imports use the same name internally - and/or they give us meaningless session names like "Untitled.ardour"
2024-05-10 15:07:44 +01:00
Robin Gareus c62fbc5c5b
Fix boundary condition first/last marker label length 2024-05-08 19:16:07 +02:00
Robin Gareus a0dc432e7a
Fix Marker label ellipsis for concurrent markers
* Sort markers: range-end before range-start
* When two marker have the same position, use distance
  to next marker not on the same position
2024-05-08 19:07:09 +02:00
Robin Gareus e542a8e0a0
Add action to reset all peak-hold (incl input meters) 2024-05-08 17:09:13 +02:00
Robin Gareus 3bab92f9a7
Add action to reset all meter peak hold 2024-05-08 15:11:36 +02:00
Paul Davis 94e0f2d3cd make dbl-click on mixer strip name button start a rename 2024-05-07 16:58:26 -06:00
Paul Davis 7d04a8bdd4 remove redundant button number check 2024-05-07 16:58:26 -06:00
Paul Davis 90d21161e7 more correct implementation for RouteProcessorSelection::set (AxisView*)
Suspending changes while clearing core selection stripables doesn't work
correctly, because we are not notified of the change before attempting
to add the argument.
2024-05-07 16:58:26 -06:00
Paul Davis fd1f68c34a allow mixer strip button events to fall through to parent, part 2 2024-05-07 16:58:26 -06:00
Paul Davis 29aeb88ce1 allow mixer strip button events to fall through to parent 2024-05-07 16:58:26 -06:00
Robin Gareus 88df55f86d
Remove debug messages, cleanup output (2/2) 2024-05-08 00:56:57 +02:00
Robin Gareus 5d175786e8
Remove debug messages, cleanup output (1/2) 2024-05-08 00:56:43 +02:00
Mattias Ohlsson 10109c3147
Fix typos 2024-05-07 18:52:02 +02:00
John Emmas dc74533fab Remove a declaration that won't be needed now 2024-05-07 16:06:47 +01:00
John Emmas a345d05f0f When importing AAF's move some code so that it only gets executed once per Source, rather than once for every Region
Fixes a problem where the Editor's 'Sources' pane was showing too many entries if there were more Regions than Sources.
2024-05-07 10:32:25 +01:00
Robin Gareus 4b8b5acfc4
Fix builds with gcc-14 lstat (#9703 PR #893)
from stat(2)
```
lstat():
    /* glibc 2.19 and earlier */ _BSD_SOURCE
        || /* Since glibc 2.20 */ _DEFAULT_SOURCE
        || _XOPEN_SOURCE >= 500
        || /* Since glibc 2.10: */ _POSIX_C_SOURCE >= 200112L

```
2024-05-07 00:17:56 +02:00
Robin Gareus 4f59b1ddf5
show/hide group-tab spacer above VCA pane 2024-05-06 23:47:10 +02:00
Robin Gareus 70898a676b
Allow to run IOTasklist without rt permissions 2024-05-06 23:20:26 +02:00
Paul Davis 576403c4cb no track movement up/down when a selected track is already at the relevant edge 2024-05-06 10:11:09 -06:00
Paul Davis f92d821a72 working track drag-n-drop, re-picked from a 2nd implementation on a branch 2024-05-05 15:09:34 -06:00
Paul Davis fdd91cc325 remove debug output 2024-05-05 15:05:09 -06:00
Paul Davis 51d2b3329c more work catching button release after track drag 2024-05-05 15:03:12 -06:00
Paul Davis c3fb69c385 catch button release after track drag 2024-05-05 15:02:59 -06:00
Paul Davis b515174e6a initialize track_drag member of Editor 2024-05-05 15:02:41 -06:00
Paul Davis e71fcaa92d add private object to Editor for use with track drag-n-drop 2024-05-05 15:02:29 -06:00
Paul Davis e170b34bf0 add pure virtual API for track DnD to PublicEditor 2024-05-05 15:02:19 -06:00
Paul Davis 89d7d85239 remove weird unused member of ARDOUR_UI 2024-05-05 15:02:03 -06:00
Paul Davis 81d1724931 NO-OP: add clarifying comment 2024-05-05 15:01:54 -06:00
Robin Gareus dec7b9a9af
Fix macOS signing when excluding xjadeo 2024-05-05 18:49:12 +02:00
Robin Gareus 8cf0fe5c77
Fix FPE when adding audio pins to a MIDI plugins 2024-05-04 20:17:25 +02:00
jean-emmanuel 4e44f44e71
mixer: use ardour widgets instead of native gtk's for plugin list dropdown and search clear button 2024-05-03 21:19:48 +02:00
Maciej Bliziński 18949a8730
Add a hint about quotes in post-export.
When I saw the post-export hint, I thought I needed to quote the arguments. Usually, either you provide a string which will be interpolated by the shell, in which case you need to add quotes, or you build an array of strings, and in this case you don't need to add quotes - but you build an array and not write a command template. Ardour's approach is a departure from this mode, so let's save future people time trying to figure this detail out.
2024-05-03 21:11:34 +02:00
Olivier HUMBERT 68402aae12
Update French translation 2024-05-03 21:09:24 +02:00
Florian Hülsmann 27154d9769
set explicit StartupWMClass for better Linux desktop UX 2024-05-03 21:06:49 +02:00
Robin Gareus df4f998231
Arrangement DnD now defaults to move (not copy) 2024-05-03 21:02:20 +02:00
Robin Gareus 100ee72cec
Fix copying RegionFx Automation 2024-05-03 14:44:49 +02:00
Robin Gareus 233a82d5f9
Separate xjadeo and harvid packaging (and remove 32c)
This is mainly for the benefit of traxlive, which needs
ffmpeg to encode mp3 or import encoded files, without
support for video.
2024-05-03 03:52:57 +02:00
Robin Gareus 37d24eee7d
Flush Audioregion local [fx] cache when changing region gain 2024-05-02 23:04:50 +02:00
Ben Loftis 27e2348b47 when capturing a midi pgm change, display the pgm num (for LT) 2024-05-02 12:43:12 -05:00
Ben Loftis a88d430609 null check for a missing session (for LT) 2024-05-02 12:42:23 -05:00
John Emmas 631ee17e34 Modify class ARDOUR::DiskReader because it now includes members declared using 'thread_local'
On Windows, variables defined as having thread storage can have a different address in different threads and as such, they aren't allowed to be imported or exported from a DLL.
2024-05-02 10:22:44 +01:00
Robin Gareus 99e2ac28e1
Update debug message to include regionfx and offset 2024-05-01 22:30:04 +02:00
Robin Gareus f355551839
Don't nag Trax users after export 2024-05-01 14:54:31 +02:00
Robin Gareus b9da1a5bd5
Expose HW concurrency to LV2 plugins 2024-05-01 03:51:42 +02:00
Robin Gareus 2ccda116c7
Add preference for I/O thread count 2024-04-30 03:54:57 +02:00
Robin Gareus 5b9e4fff63
Parallelize Disk I/O and RegionFx processing 2024-04-30 03:46:39 +02:00
Robin Gareus 4b0da72bc2
Delegate all DiskReader I/O to the IOTaskList (amend 170b9150) 2024-04-30 01:55:44 +02:00
Robin Gareus ee87b068e8
Move RegionFx ThreadBuffers to Butler thread 2024-04-30 01:54:33 +02:00
Robin Gareus 170b915038
Prepare for parallel Disk I/O 2024-04-30 00:01:32 +02:00
Robin Gareus 2af2df3516
Raise the butler's I/O priority
This likely won't make much difference on modern systems,
since it requires a kernel based I/O scheduler. which is
disabled (set to "none" for NVMe and SSDs).
2024-04-29 21:46:06 +02:00
Robin Gareus e90e31d682
Add a Tracks/Waveform icon 2024-04-29 21:00:27 +02:00
Robin Gareus ce4f91483b
Fix OSX packaging and signing for LiveTrax 2024-04-29 00:56:27 +02:00
Robin Gareus 9bafa8a216
Remove svn related part in bundle script 2024-04-29 00:42:12 +02:00
Robin Gareus 75167ac347
Bundle/package script updates for LiveTrax 2024-04-28 17:54:20 +02:00
Robin Gareus 5f7ecf59a5
Allow to compile w/o LV2 support (trax) 2024-04-28 17:50:51 +02:00
Robin Gareus dcb732f07c
Only allow editing top-most MIDI region in layered view
NoteDrag (change pitch) only works correctly for the topmost
region when using Stacked LayerDisplay. Note-grid is also only
displayed for the top layer.
2024-04-27 00:04:29 +02:00
Paul Davis 201580f7ba fix crashes caused by assert (_fx_line); item does not exist for livetrax 2024-04-25 13:07:00 -06:00
Paul Davis fc86629daf sometimes concision with variable naming is of no help 2024-04-25 13:07:00 -06:00
Paul Davis 21a39c5f1f profile initialization per-program needs to happen earlier, in ARDOUR::init() 2024-04-25 13:07:00 -06:00
Paul Davis b2570bcaa3 remove debug output 2024-04-25 13:07:00 -06:00
Paul Davis 0b8cfdee40 display MIDI scene markers 2024-04-25 13:07:00 -06:00
Paul Davis 87f40ddc7f some libardour support for MIDI scene support 2024-04-25 13:07:00 -06:00
Paul Davis a0756429cf auto-fication of a loop in InternalReturn 2024-04-25 13:07:00 -06:00
Paul Davis 7bcdd5b2e4 NO-OP: add space before bracket 2024-04-25 13:07:00 -06:00
Paul Davis e3b21ed77a NO-OP: linebeeak removed 2024-04-25 13:07:00 -06:00
Paul Davis a7dbf57afa more crash avoidance in sfdb UI if there's no auditioner 2024-04-25 13:07:00 -06:00
Paul Davis ad53c31e50 sfdb UI should not crash if there's no auditioner 2024-04-25 13:07:00 -06:00
Paul Davis 5d1233e60a NO-OP: fix space near braces/brackets 2024-04-25 13:07:00 -06:00
Paul Davis 43e0f08b93 sfdb_ui should be smart if there's no auditioner 2024-04-25 13:07:00 -06:00
Paul Davis 8f7f204ae4 port group display should not crash if there's no auditioner 2024-04-25 13:07:00 -06:00
Paul Davis 9052eb013e no crash if instrument selector has no _instrument_list 2024-04-25 13:07:00 -06:00
Paul Davis 125b0f9432 add a new Profile flag for livetrax 2024-04-25 13:07:00 -06:00
Paul Davis 16ed245977 allow true boxy buttons for ArdourButtons
Also add a default tweaks static member to force all buttons to a given tweak state
2024-04-25 13:03:52 -06:00
Paul Davis 46fa056da6 add unrounded rectangle methods to Gtkmm2ext for use in truly boxy buttons 2024-04-25 13:03:52 -06:00
Robin Gareus 354e60d657
Drop session's monitor bus reference when removing the bus 2024-04-25 19:18:06 +02:00
Robin Gareus 848832f8b0
Flush GraphNode RCU when removing Routes
Since 44610c787 RCU keeps references until another write happens.
even before then, some shared_ptr references may have been kept.

When using a process graph, a route's activision-set can
hold references to other graph-nodes (routes). This lead
to Routes not being deleted until a second graph-reorder
flushed the RCU.
2024-04-25 19:18:06 +02:00
Robin Gareus 97becda83a
Update icon rendering tool 2024-04-25 19:18:02 +02:00
Paul Davis f1a3eb1e3d use a different source file for ardour.menus in the livetrax case 2024-04-25 09:26:33 -06:00
Robin Gareus 4665cdcb6b
Add icons for livetrax (lock, mixer, meter) 2024-04-25 02:21:10 +02:00
Robin Gareus b00ddcfe1c
Fix -Waddress (and expand tabs)
The expansion of the macro resulted in:
"the comparison will always evaluate as 'true' for the address of .."
2024-04-24 18:06:27 +02:00
agfline 8ea3a14cd6
Update AAF import UI 2024-04-24 17:13:00 +02:00
agfline 41587d3c06
Update libaaf to v1.0-11-gb04c547 2024-04-24 17:13:00 +02:00
Robin Gareus 895fe2f753
Fix Windows builds 2/2 (amend b2d4280e0) 2024-04-24 06:08:26 +02:00
Robin Gareus df12126909
Fix Windows builds 1/2 (amend bcbb4393fc) 2024-04-24 06:02:13 +02:00
Robin Gareus 38adfdf79e
Add custom color for region effect automation 2024-04-23 21:56:26 +02:00
Robin Gareus b2d4280e0f
Add support for Region Fx Automation 2024-04-23 21:56:22 +02:00
Robin Gareus e5506d281a
GUI support for Region Fx (in Region Properties) 2024-04-23 21:56:18 +02:00
Robin Gareus 457238ec2e
Per [Audio] Region Fx
* apply effects during region-read in non-rt context
* Add multi-channel audioregion read cache
  to process stereo effects
2024-04-23 21:56:15 +02:00
Robin Gareus 1996945353
Add custom RegionFxPlugin
Less than a PluginInsert but more than an IOPlug.
2024-04-23 21:56:10 +02:00
Robin Gareus ad9a3ae103
Fix region-gain envelope auto-enable when dragging
When using freehand drawing of automation, the line itself
is not notified (no ::start_drag(), ::end_drag() calls).

This adds a end_draw() call which allows the AutomatioLine
to perform additional actions.
2024-04-23 21:56:05 +02:00
Robin Gareus b04fa05f20
NO-OP: sort debug bits 2024-04-23 21:55:59 +02:00
Robin Gareus 1cd9a9b57d
Only show automation mode button for PluginInsert ctrls
Previously the generic UI of I/O plugins (and upcoming Region
Fx showed an insensitive Automation mode (manual, play, touch etc)
dropdown for all controls.

That accomplished nothing but wasted space.
2024-04-23 21:55:54 +02:00
Robin Gareus 59b2369736
Remove unused gain-buffer for master-read (NOOP) 2024-04-23 21:52:02 +02:00
Robin Gareus f3823e8d7c
Fix redeclaration of DnDVbox 2024-04-23 21:51:55 +02:00
Robin Gareus 2bb4a9ac4e
Add API to configure plugins for non-realtime offline processing 2024-04-23 21:51:50 +02:00
Robin Gareus 598ff1cb9a
Separate PluginWindowProxy into public class 2024-04-23 21:51:31 +02:00
Robin Gareus f858316503
Plugins: Ignore offset for scratch/silent buffers
This allows to process buffers at an offset, as long
as the number of processed samples is less or equal to the
current buffersize.
2024-04-23 21:51:19 +02:00
Robin Gareus 2ca5f28910
NO-OP: whitespace 2024-04-23 21:51:07 +02:00
Robin Gareus 2f6a428f05
Overhaul and optimize thread-buffer allocation
Every route calls Session::ensure_buffers when configuring
processors. Previously that unconditionally invoked the
BufferManager, even if no change was required.

This also fixes a potential issue when bouncing tracks.
::write_one_track() increases the buffersize to 8k, but only for
the ChanCount required to bounce. This was never properly reset.

Furthermore this is in preparation for RegionFX which may
need to increase the ChanCount of Threadbuffers.
2024-04-23 21:51:04 +02:00
Robin Gareus 6dfcb60763
Automatable find_next/prev_ac_event requires no context
This allows to use the functions from a class that
does not inherit from Automatable but has AutomationControls
with an AutomationList.
2024-04-23 21:50:58 +02:00
Robin Gareus f111f200c1
Fix signal analysis when buffer-size changes
PI::signal-analysis buffers were not updated when a user
changes the buffersize.

This also remove a single use Session API.
2024-04-23 21:49:48 +02:00
Robin Gareus df8106bd85
PluginInsert match I/O: skip div by zero 2024-04-23 21:49:41 +02:00
Robin Gareus 92183430b9
IOPlug: various small fixes (port-names, VST compat, etc) 2024-04-23 21:49:28 +02:00
Robin Gareus 5216a6d987
Refactor and consolidate setting and copying plugin state 2024-04-21 16:32:47 +02:00
Robin Gareus f5b53a6d14
Consolidate PluginInsert Match, move to parent class 2024-04-21 16:32:47 +02:00
Robin Gareus 2da3141706
Consolidate plugin_factory, move to parent class 2024-04-21 16:32:47 +02:00
Robin Gareus d2bdf440c8
Consolidate PluginControl Code
This code was (for the most part) duplicated, and with
preparation for Region FX, a third copy motivated this
consolidation.
2024-04-21 16:32:47 +02:00
Robin Gareus 6191f89d55
Properly update Solo state when setting multiple ctrls 2024-04-21 16:32:13 +02:00
Robin Gareus bcbb4393fc
Allow Lua [session] script to directly set controllables 2024-04-21 16:32:10 +02:00
Paul Davis 894e6d27a4 NOOP: whitespace cleanup 2024-04-19 10:43:10 -06:00
Paul Davis c96e12ba58 expand null/destroyed tests for gdk objects in NSView methods 2024-04-19 10:42:59 -06:00
Robin Gareus e64a071e39
(YDK) amend previous commit, call parent method 2024-04-19 16:46:49 +02:00
Robin Gareus 08e394f681
(YDK) possible fix for Catalina event loop crashes
```
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libydk.dylib 0x0000000110d8942d -[GdkQuartzView setNeedsDisplay:] + 93
1 com.apple.AppKit 0x00007fff34af6848 -[NSView(NSViewContentStyle) _recursivelyInvalidateCachedContentStyle] + 120
2 com.apple.AppKit 0x00007fff34af60fb -[NSView _setSuperview:] + 521
3 com.apple.AppKit 0x00007fff34b200a6 -[NSView removeFromSuperview] + 140
4 com.apple.AppKit 0x00007fff34ba882f -[NSView removeFromSuperviewWithoutNeedingDisplay] + 36
5 com.apple.AppKit 0x00007fff34b27168 -[NSView _finalize] + 977
6 com.apple.AppKit 0x00007fff34b26c0c -[NSView dealloc] + 121
7 com.apple.AppKit 0x00007fff34e30db4 -[NSFrameView dealloc] + 119
8 com.apple.AppKit 0x00007fff34e30d36 -[NSTitledFrame dealloc] + 62
9 com.apple.AppKit 0x00007fff34e30ce9 -[NSThemeFrame dealloc] + 603
10 com.apple.Foundation 0x00007fff39ed5992 NSKVODeallocate + 172
11 com.apple.AppKit 0x00007fff34d85884 -[NSWindow dealloc] + 1083
12 com.apple.AppKit 0x00007fff34d85442 -[NSWindow _dealloc] + 76
13 libobjc.A.dylib 0x00007fff6f6f3054 AutoreleasePoolPage::releaseUntil(objc_object**) + 134
14 libobjc.A.dylib 0x00007fff6f6d7dba objc_autoreleasePoolPop + 175
15 com.apple.CoreFoundation 0x00007fff377c9cb5 _CFAutoreleasePoolPop + 22
16 com.apple.Foundation 0x00007fff39e7d04e -[NSAutoreleasePool drain] + 126
17 libydk.dylib 0x0000000110d8ef29 gdk_event_prepare + 73
18 libglib-2.0.0.dylib 0x00000001110ded45 g_main_context_prepare + 533
19 libglib-2.0.0.dylib 0x00000001110df800 g_main_context_iterate + 128
20 libglib-2.0.0.dylib 0x00000001110dfcc2 g_main_loop_run + 210
21 libytk.dylib 0x0000000110a4f11f gtk_main + 191
22 libgtkmm2ext.dylib 0x00000001104cef1e Gtkmm2ext::UI::run(Receiver&) + 318
23 com.harrisonconsoles.Mixbus10 0x000000010dc6fb9c main + 2652
```
2024-04-19 15:38:12 +02:00
Robin Gareus 136b7f42d5
Skip tags for plugins that are not installed
This prevents empty sub-menus in the "By Tag" Plugin menu.
2024-04-18 17:07:12 +02:00
Robin Gareus 4b6e372ce7
Fix deleting the same point multiple times (#9689)
When iterating over automation tracks, previously it was
possible that the same point was added multiple times to
the selection.
2024-04-15 00:39:20 +02:00
Edgar Aichinger c9c419213f
update german translation 2024-04-14 00:42:09 +02:00
202 changed files with 8322 additions and 3619 deletions

View File

@ -778,7 +778,11 @@ INPUT = ../libs/ardour \
../libs/widgets \
../libs/zita-convolver \
../libs/zita-resampler \
../libs/zita-resampler \
../gtk2_ardour \
../libs/tk/ytkmm/ytkmm/gtkmm \
../libs/tk/ydkmm/ydkmm/gdkmm \
../libs/tk/ydk/ydk/gdk \
mainpage.txt
## audiographer assumes it's documented separately (has it's own @mainpage)

View File

@ -7,3 +7,4 @@ Terminal=false
MimeType=application/x-ardour;
Type=Application
Categories=AudioVideo;Audio;AudioEditing;X-Recorders;X-Multitrack;X-Jack;
StartupWMClass=Ardour

View File

@ -553,6 +553,7 @@
<menuitem action="toggle-arrangement-ruler"/>
<menuitem action="toggle-marker-ruler"/>
<menuitem action="toggle-cue-marker-ruler"/>
<menuitem action="toggle-scene-marker-ruler"/>
<separator/>
<menuitem action="toggle-video-ruler"/>
</menu>
@ -805,6 +806,7 @@
<menuitem action="toggle-cd-marker-ruler"/>
<menuitem action="toggle-marker-ruler"/>
<menuitem action="toggle-cue-marker-ruler"/>
<menuitem action="toggle-scene-marker-ruler"/>
<separator/>
<menuitem action="toggle-video-ruler"/>
</popup>

View File

@ -1432,6 +1432,10 @@ ARDOUR_UI::format_disk_space_label (float remain_sec)
std::string label = string_compose (X_("<span weight=\"ultralight\">%1</span>: "), _("Rec"));
if (_session && FLAC == _session->config.get_native_file_header_format () && remain_sec <= 86400) {
label += u8"\u2265"; // Greater-Than or Equal To
}
if (remain_sec > 86400) {
disk_space_label.set_markup (label + _(">24h"));
} else if (remain_sec > 32400 /* 9 hours */) {
@ -2210,8 +2214,6 @@ ARDOUR_UI::update_clocks ()
void
ARDOUR_UI::start_clocking ()
{
std::cerr << "start clocking\n";
if (UIConfiguration::instance().get_no_strobe()) {
if (!_session) {
return;

View File

@ -275,8 +275,6 @@ public:
void reset_focus (Gtk::Widget*);
static PublicEditor* _instance;
/** Emitted frequently with the audible sample, false, and the edit point as
* parameters respectively.
*

View File

@ -17,7 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <fcntl.h> // O_WRONLY
#include <fcntl.h> // O_WRONLY
#include <glib/gstdio.h> // g_unlink()
#include "pbd/basename.h"
@ -50,26 +50,38 @@ using namespace ARDOUR;
static void
aaf_debug_callback (struct aafLog* log, void* ctxdata, int libid, int type, const char* srcfile, const char* srcfunc, int lineno, const char* msg, void* user)
{
const char *eol = "";
const char* eol = "";
if ( libid != LOG_SRC_ID_TRACE && libid != LOG_SRC_ID_DUMP ) {
switch ( type ) {
case VERB_SUCCESS: PBD::info << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
case VERB_ERROR: PBD::error << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
case VERB_WARNING: PBD::warning << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
// case VERB_DEBUG: PBD::debug << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
if (libid != LOG_SRC_ID_TRACE && libid != LOG_SRC_ID_DUMP) {
switch (type) {
case VERB_SUCCESS:
PBD::info << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
case VERB_ERROR:
PBD::error << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
case VERB_WARNING:
PBD::warning << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc);
break;
// case VERB_DEBUG: PBD::debug << string_compose ("[libaaf] %1:%2 in %3(): ", srcfile, lineno, srcfunc); break;
}
}
if ( libid != LOG_SRC_ID_DUMP ) {
if (libid != LOG_SRC_ID_DUMP) {
eol = "\n";
}
switch ( type ) {
case VERB_SUCCESS: PBD::info << msg << eol; break;
case VERB_ERROR: PBD::error << msg << eol; break;
case VERB_WARNING: PBD::warning << msg << eol; break;
// case VERB_DEBUG: PBD::debug << msg << eol; break;
switch (type) {
case VERB_SUCCESS:
PBD::info << msg << eol;
break;
case VERB_ERROR:
PBD::error << msg << eol;
break;
case VERB_WARNING:
PBD::warning << msg << eol;
break;
// case VERB_DEBUG: PBD::debug << msg << eol; break;
}
LOG_BUFFER_RESET (log);
@ -121,85 +133,95 @@ prepare_audio_track (aafiAudioTrack* aafTrack, Session* s)
}
static bool
import_sndfile_as_region (Session* s, struct aafiAudioEssencePointer* aafAudioEssencePtrList, SrcQuality quality, timepos_t& pos, SourceList& sources, ImportStatus& status, vector<std::shared_ptr<Region>>& regions)
import_sndfile_as_region (Session* s, struct aafiAudioEssencePointer* aafAudioEssencePtrList, SrcQuality quality, timepos_t& pos, SourceList** oneClipSources, ImportStatus& status, vector<std::shared_ptr<Region>>& regions)
{
/* Import the source */
status.clear ();
SourceList* sources = NULL;
status.current = 1;
status.total = 1;
status.freeze = false;
status.quality = quality;
status.replace_existing_source = false;
status.split_midi_channels = false;
status.import_markers = false;
status.done = false;
status.cancel = false;
if (aafAudioEssencePtrList->user) {
sources = (SourceList*)aafAudioEssencePtrList->user;
} else {
sources = new SourceList;
int channelCount = 0;
/* Import the source */
status.clear ();
aafiAudioEssencePointer *aafAudioEssencePtr = NULL;
AAFI_foreachEssencePointer (aafAudioEssencePtrList, aafAudioEssencePtr) {
if ( aafAudioEssencePtr->essenceFile->usable_file_path )
status.paths.push_back (aafAudioEssencePtr->essenceFile->usable_file_path);
else
status.paths.push_back (aafAudioEssencePtr->essenceFile->original_file_path);
status.current = 1;
status.total = 1;
status.freeze = false;
status.quality = quality;
status.replace_existing_source = false;
status.split_midi_channels = false;
status.import_markers = false;
status.done = false;
status.cancel = false;
channelCount++;
PBD::info << string_compose ("AAF: Preparing to import clip channel %1: %2\n", channelCount, aafAudioEssencePtr->essenceFile->unique_name);
int channelCount = 0;
aafiAudioEssencePointer* aafAudioEssencePtr = NULL;
AAFI_foreachEssencePointer (aafAudioEssencePtrList, aafAudioEssencePtr)
{
if (aafAudioEssencePtr->essenceFile->usable_file_path)
status.paths.push_back (aafAudioEssencePtr->essenceFile->usable_file_path);
else
status.paths.push_back (aafAudioEssencePtr->essenceFile->original_file_path);
channelCount++;
PBD::info << string_compose ("AAF: Preparing to import clip channel %1: %2\n", channelCount, aafAudioEssencePtr->essenceFile->unique_name);
}
s->import_files (status);
status.progress = 1.0;
sources->clear ();
/* FIXME: There is no way to tell if cancel button was pressed
* or if the file failed to import, just that one of these occurred.
* We want status.cancel to reflect the user's choice only
*/
if (status.cancel && status.current > 1) {
/* Succeeded to import file, assume user hit cancel */
return false;
} else if (status.cancel && status.current == 1) {
/* Failed to import file, assume user did not hit cancel */
status.cancel = false;
return false;
}
for (int i = 0; i < channelCount; i++) {
PropertyList proplist;
sources->push_back (status.sources.at (i));
proplist.add (ARDOUR::Properties::start, 0);
proplist.add (ARDOUR::Properties::length, timecnt_t ((*sources)[0]->length (), pos));
proplist.add (ARDOUR::Properties::name, aafAudioEssencePtrList->essenceFile->unique_name);
proplist.add (ARDOUR::Properties::layer, 0);
proplist.add (ARDOUR::Properties::whole_file, true);
proplist.add (ARDOUR::Properties::external, true);
RegionFactory::create (*sources, proplist);
}
/* build peakfiles */
for (SourceList::iterator x = sources->begin (); x != sources->end (); ++x) {
SourceFactory::setup_peakfile (*x, true);
}
aafAudioEssencePtrList->user = sources;
}
s->import_files (status);
status.progress = 1.0;
sources.clear ();
/* FIXME: There is no way to tell if cancel button was pressed
* or if the file failed to import, just that one of these occurred.
* We want status.cancel to reflect the user's choice only
*/
if (status.cancel && status.current > 1) {
/* Succeeded to import file, assume user hit cancel */
return false;
} else if (status.cancel && status.current == 1) {
/* Failed to import file, assume user did not hit cancel */
status.cancel = false;
return false;
}
for (int i = 0; i < channelCount; i++) {
sources.push_back (status.sources.at (i));
}
/* build peakfiles */
for (SourceList::iterator x = sources.begin (); x != sources.end (); ++x) {
SourceFactory::setup_peakfile (*x, true);
}
*oneClipSources = sources;
/* Put the source on a region */
std::shared_ptr<Region> region;
string region_name;
string region_name;
/* take all the sources we have and package them up as a region */
region_name = region_name_from_path (status.paths.front (), (sources.size () > 1), false);
region_name = region_name_from_path (status.paths.front (), (sources->size () > 1), false);
/* we checked in import_sndfiles() that there were not too many */
while (RegionFactory::region_by_name (region_name)) {
region_name = bump_name_once (region_name, '.');
}
PropertyList proplist;
proplist.add (ARDOUR::Properties::start, 0);
proplist.add (ARDOUR::Properties::length, timecnt_t (sources[0]->length (), pos));
proplist.add (ARDOUR::Properties::name, aafAudioEssencePtrList->essenceFile->unique_name);
proplist.add (ARDOUR::Properties::layer, 0);
proplist.add (ARDOUR::Properties::whole_file, true);
proplist.add (ARDOUR::Properties::external, true);
region = RegionFactory::create (sources, proplist);
regions.push_back (region);
return true;
}
@ -302,14 +324,14 @@ set_region_fade (aafiAudioClip* aafAudioClip, std::shared_ptr<Region> region, aa
samplecnt_t fade_len;
if (fadein != NULL) {
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e) (fadein->flags & AAFI_INTERPOL_MASK));
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e)(fadein->flags & AAFI_INTERPOL_MASK));
fade_len = aafi_convertUnit (fadein->len, aafAudioClip->track->edit_rate, samplerate);
std::dynamic_pointer_cast<AudioRegion> (region)->set_fade_in (fade_shape, fade_len);
}
if (fadeout != NULL) {
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e) (fadeout->flags & AAFI_INTERPOL_MASK));
fade_shape = aaf_fade_interpol_to_ardour_fade_shape ((aafiInterpolation_e)(fadeout->flags & AAFI_INTERPOL_MASK));
fade_len = aafi_convertUnit (fadeout->len, aafAudioClip->track->edit_rate, samplerate);
std::dynamic_pointer_cast<AudioRegion> (region)->set_fade_out (fade_shape, fade_len);
@ -437,26 +459,17 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_set_debug (aafi, VERB_DEBUG, 0, NULL, &aaf_debug_callback, this);
if (aafi_load_file (aafi, aaf.c_str ())) {
error << "AAF: Could not load AAF file." << endmsg;
aafi_release (&aafi);
return -1;
}
/* extract or set session name */
if (aafi->compositionName && aafi->compositionName[0] != 0x00) {
string compositionName = string(aafi->compositionName);
snapshot = laaf_util_clean_filename (&compositionName[0]);
} else {
snapshot = basename_nosuffix (aaf);
}
snapshot = legalize_for_universal_path (snapshot);
snapshot = legalize_for_universal_path (basename_nosuffix (aaf));
path = Glib::build_filename (target_dir, snapshot);
if (Glib::file_test (path, Glib::FILE_TEST_EXISTS)) {
error << string_compose (_("AAF: Destination '%1' already exists."), path) << endmsg;
error << string_compose (_ ("AAF: Destination '%1' already exists."), path) << endmsg;
snapshot = ""; // XXX?
path = "";
aafi_release (&aafi);
@ -465,10 +478,10 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
/* Create media cache */
GError* err = NULL;
char* td = g_dir_make_tmp ("aaf-cache-XXXXXX", &err);
char* td = g_dir_make_tmp ("aaf-cache-XXXXXX", &err);
if (!td) {
error << string_compose (_("AAF: Could not prepare media cache: %1"), err->message) << endmsg;
error << string_compose (_ ("AAF: Could not prepare media cache: %1"), err->message) << endmsg;
aafi_release (&aafi);
return -1;
}
@ -487,16 +500,16 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
samplerate_r.denominator = 1;
std::string restore_backend;
if (!AudioEngine::instance()->running ()) {
AudioEngine* e = AudioEngine::instance();
if (!AudioEngine::instance ()->running ()) {
AudioEngine* e = AudioEngine::instance ();
restore_backend = e->current_backend_name ();
e->set_backend ("None (Dummy)", "", "");
e->start ();
PluginManager::instance ().refresh (true);
attach_to_engine ();
}
if (!AudioEngine::instance()->running ()) {
PBD::error << _("AAF: Could not start [dummy] engine for AAF import .") << endmsg;
if (!AudioEngine::instance ()->running ()) {
PBD::error << _ ("AAF: Could not start [dummy] engine for AAF import .") << endmsg;
return -1;
}
@ -506,10 +519,10 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_release (&aafi);
PBD::remove_directory (media_cache_path);
if (!restore_backend.empty ()) {
AudioEngine::instance()->stop ();
AudioEngine::instance()->set_backend (restore_backend, "", "");
AudioEngine::instance ()->stop ();
AudioEngine::instance ()->set_backend (restore_backend, "", "");
}
error << _("AAF: Could not create new session for AAF import .") << endmsg;
error << _ ("AAF: Could not create new session for AAF import .") << endmsg;
return -1;
}
@ -547,15 +560,15 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
/* Import Sources */
SourceList oneClipSources;
SourceList* oneClipSources;
ARDOUR::ImportStatus import_status;
vector<std::shared_ptr<Region>> source_regions;
timepos_t pos = timepos_t::max (Temporal::AudioTime);
aafiAudioTrack* aafAudioTrack = NULL;
aafiTimelineItem* aafAudioItem = NULL;
aafiAudioClip* aafAudioClip = NULL;
aafiAudioEssencePointer *aafAudioEssencePtr = NULL;
aafiAudioTrack* aafAudioTrack = NULL;
aafiTimelineItem* aafAudioItem = NULL;
aafiAudioClip* aafAudioClip = NULL;
aafiAudioEssencePointer* aafAudioEssencePtr = NULL;
aafPosition_t sessionStart = aafi_convertUnit (aafi->compositionStart, aafi->compositionStart_editRate, &samplerate_r);
@ -572,19 +585,19 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
}
if (aafAudioClip->essencePointerList == NULL) {
error << _("AAF: Clip has no essence.") << endmsg;
error << _ ("AAF: Clip has no essence.") << endmsg;
continue;
}
int essenceError = 0;
char *essenceName = aafAudioClip->essencePointerList->essenceFile->name;
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr) {
int essenceError = 0;
char* essenceName = aafAudioClip->essencePointerList->essenceFile->name;
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr)
{
struct aafiAudioEssenceFile* audioEssenceFile = aafAudioEssencePtr->essenceFile;
if (!audioEssenceFile) {
PBD::error << string_compose (_("AAF: Could not create new region for clip '%1': Missing audio essence"), audioEssenceFile->unique_name) << endmsg;
PBD::error << string_compose (_ ("AAF: Could not create new region for clip '%1': Missing audio essence"), audioEssenceFile->unique_name) << endmsg;
essenceError++;
continue;
}
@ -607,27 +620,27 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
continue;
}
if (!import_sndfile_as_region (_session, aafAudioClip->essencePointerList, SrcBest, pos, oneClipSources, import_status, source_regions)) {
if (!import_sndfile_as_region (_session, aafAudioClip->essencePointerList, SrcBest, pos, &oneClipSources, import_status, source_regions)) {
PBD::error << string_compose ("AAF: Could not import '%1' to session.", essenceName) << endmsg;
continue;
}
else {
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr) {
} else {
AAFI_foreachEssencePointer (aafAudioClip->essencePointerList, aafAudioEssencePtr)
{
if (aafAudioEssencePtr->essenceFile->is_embedded) {
g_unlink (aafAudioEssencePtr->essenceFile->usable_file_path);
}
}
}
if (oneClipSources.size () == 0) {
error << string_compose (_("AAF: Could not create new region for clip '%1': Region has no source"), essenceName) << endmsg;
if (!oneClipSources || oneClipSources->size () == 0) {
error << string_compose (_ ("AAF: Could not create new region for clip '%1': Region has no source"), essenceName) << endmsg;
continue;
}
std::shared_ptr<Region> region = create_region (source_regions, aafAudioClip, oneClipSources, sessionStart, samplerate_r);
std::shared_ptr<Region> region = create_region (source_regions, aafAudioClip, *oneClipSources, sessionStart, samplerate_r);
if (!region) {
error << string_compose (_("AAF: Could not create new region for clip '%1'"), essenceName) << endmsg;
error << string_compose (_ ("AAF: Could not create new region for clip '%1'"), essenceName) << endmsg;
continue;
}
@ -643,11 +656,12 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
}
}
oneClipSources.clear ();
// oneClipSources.clear ();
aafiMarker* marker = NULL;
AAFI_foreachMarker (aafi, marker) {
AAFI_foreachMarker (aafi, marker)
{
aafPosition_t markerStart = sessionStart + aafi_convertUnit (marker->start, marker->edit_rate, &samplerate_r);
aafPosition_t markerEnd = sessionStart + aafi_convertUnit ((marker->start + marker->length), marker->edit_rate, &samplerate_r);
@ -691,8 +705,8 @@ ARDOUR_UI::new_session_from_aaf (string const& aaf, string const& target_dir, st
aafi_release (&aafi);
if (!restore_backend.empty ()) {
AudioEngine::instance()->stop ();
AudioEngine::instance()->set_backend (restore_backend, "", "");
AudioEngine::instance ()->stop ();
AudioEngine::instance ()->set_backend (restore_backend, "", "");
}
return 0;
}

View File

@ -64,6 +64,7 @@
#include "editing.h"
#include "enums_convert.h"
#include "actions.h"
#include "meter_patterns.h"
#include "meterbridge.h"
#include "luawindow.h"
#include "mixer_ui.h"
@ -500,6 +501,12 @@ ARDOUR_UI::install_actions ()
act = ActionManager::register_toggle_action (main_actions, X_("ToggleLatencyCompensation"), _("Disable Latency Compensation"), sigc::mem_fun(*this, &ARDOUR_UI::toggle_latency_switch));
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_toggle_action (main_actions, X_("ResetAllPeakDisplays"), _("Reset Mixer Meter Peaks"), []() { ArdourMeter::ResetAllPeakDisplays (); });
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_toggle_action (main_actions, X_("ResetMeterPeakHold"), _("Reset All Meter Peak Hold"), []() { ArdourMeter::ResetAllPeakDisplays (); ActionManager::get_action ("Recorder", "reset-input-peak-hold")->activate (); });
ActionManager::session_sensitive_actions.push_back (act);
act = ActionManager::register_action (main_actions, X_("MonitorMenu"), _("Monitor Section")); /* just the submenu item */
ActionManager::session_sensitive_actions.push_back (act);

View File

@ -122,7 +122,6 @@ ARDOUR_UI::create_xrun_marker (samplepos_t where)
void
ARDOUR_UI::halt_on_xrun_message ()
{
cerr << "HALT on xrun\n";
ArdourMessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up."));
msg.run ();
}

View File

@ -33,10 +33,12 @@
#include "ardour/audioregion.h"
#include "ardour/session_event.h"
#include "ardour/dB.h"
#include "ardour/region_fx_plugin.h"
#include "audio_region_editor.h"
#include "audio_region_view.h"
#include "gui_thread.h"
#include "public_editor.h"
#include "pbd/i18n.h"
@ -52,11 +54,13 @@ _peak_amplitude_thread (void* arg)
return 0;
}
AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r)
: RegionEditor (s, r)
, _audio_region (r)
AudioRegionEditor::AudioRegionEditor (Session* s, AudioRegionView* arv)
: RegionEditor (s, arv)
, _arv (arv)
, _audio_region (arv->audio_region ())
, gain_adjustment(accurate_coefficient_to_dB(fabsf (_audio_region->scale_amplitude())), -40.0, +40.0, 0.1, 1.0, 0)
, _polarity_toggle (_("Invert"))
, _show_on_touch (_("Show on Touch"))
, _peak_channel (false)
{
@ -87,14 +91,27 @@ AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r
_polarity_label.set_name ("AudioRegionEditorLabel");
_polarity_label.set_text (_("Polarity:"));
_polarity_label.set_alignment (1, 0.5);
_table.attach (_polarity_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_polarity_toggle, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
++_table_row;
_region_line_label.set_name ("AudioRegionEditorLabel");
_region_line_label.set_text (_("Region Line:"));
_region_line_label.set_alignment (1, 0.5);
_table.attach (_region_line_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_region_line, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
_table.attach (_show_on_touch, 2, 3, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
++_table_row;
gain_changed ();
refill_region_line ();
gain_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
_polarity_toggle.signal_toggled().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
_show_on_touch.signal_toggled().connect (sigc::mem_fun (*this, &AudioRegionEditor::show_on_touch_changed));
arv->region_line_changed.connect ((sigc::mem_fun (*this, &AudioRegionEditor::refill_region_line)));
_peak_amplitude.property_editable() = false;
_peak_amplitude.set_text (_("Calculating..."));
@ -105,6 +122,7 @@ AudioRegionEditor::AudioRegionEditor (Session* s, std::shared_ptr<AudioRegion> r
snprintf (name, 64, "peak amplitude-%p", this);
pthread_create_and_store (name, &_peak_amplitude_thread_handle, _peak_amplitude_thread, this);
signal_peak_thread ();
}
AudioRegionEditor::~AudioRegionEditor ()
@ -128,6 +146,14 @@ AudioRegionEditor::region_changed (const PBD::PropertyChange& what_changed)
signal_peak_thread ();
}
}
void
AudioRegionEditor::region_fx_changed ()
{
RegionEditor::region_fx_changed ();
refill_region_line ();
}
void
AudioRegionEditor::gain_changed ()
{
@ -189,3 +215,118 @@ AudioRegionEditor::peak_amplitude_found (double p)
_peak_amplitude.set_text (s.str ());
}
void
AudioRegionEditor::show_touched_automation (std::weak_ptr<PBD::Controllable> wac)
{
if (!_arv->set_region_fx_line (wac)) {
return;
}
switch (PublicEditor::instance ().current_mouse_mode ()) {
case Editing::MouseObject:
case Editing::MouseTimeFX:
case Editing::MouseGrid:
case Editing::MouseCut:
PublicEditor::instance ().set_mouse_mode (Editing::MouseDraw, false);
break;
default:
break;
}
}
void
AudioRegionEditor::show_on_touch_changed ()
{
if (!_show_on_touch.get_active ()) {
_ctrl_touched_connection.disconnect ();
return;
}
Controllable::ControlTouched.connect (_ctrl_touched_connection, invalidator (*this), boost::bind (&AudioRegionEditor::show_touched_automation, this, _1), gui_context ());
}
void
AudioRegionEditor::refill_region_line ()
{
using namespace Gtk::Menu_Helpers;
_region_line.clear_items ();
MenuList& rm_items (_region_line.items ());
int nth = 0;
PBD::ID rfx_id (0);
uint32_t param_id = 0;
string active_text = _("Gain Envelope");
_arv->get_region_fx_line (rfx_id, param_id);
_arv->set_ignore_line_change (true);
Gtk::RadioMenuItem::Group grp;
AudioRegionView* arv = _arv;
rm_items.push_back (RadioMenuElem (grp, _("Gain Envelope")));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&rm_items.back ());
cmi->set_active (rfx_id == 0 || param_id == UINT32_MAX);
cmi->signal_activate ().connect ([cmi, arv] () { if (cmi->get_active ()) {arv->set_region_gain_line (); }});
_audio_region->foreach_plugin ([&rm_items, arv, &nth, &grp, &active_text, rfx_id, param_id](std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return;
}
std::shared_ptr<Plugin> plugin = fx->plugin ();
Gtk::Menu* acm = manage (new Gtk::Menu);
MenuList& acm_items (acm->items ());
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
std::string label = plugin->describe_parameter (param);
if (label == X_("latency") || label == X_("hidden")) {
continue;
}
std::shared_ptr<ARDOUR::AutomationControl> c (std::dynamic_pointer_cast<ARDOUR::AutomationControl> (fx->control (param)));
if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) {
continue;
}
bool active = fx->id () == rfx_id && param_id == i;
acm_items.push_back (RadioMenuElem (grp, label));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&acm_items.back ());
cmi->set_active (active);
cmi->signal_activate ().connect ([cmi, arv, nth, i] () { if (cmi->get_active ()) {arv->set_region_fx_line (nth, i); }});
if (active) {
active_text = fx->name () + ": " + label;
}
}
if (!acm_items.empty ()) {
rm_items.push_back (MenuElem (fx->name (), *acm));
} else {
delete acm;
}
++nth;
});
if (rm_items.size () > 1) {
_show_on_touch.set_sensitive (true);
} else {
_show_on_touch.set_active (false);
_show_on_touch.set_sensitive (false);
}
_region_line.set_text (active_text);
_arv->set_ignore_line_change (false);
}
void
AudioRegionEditor::on_unmap ()
{
_show_on_touch.set_active (false);
ArdourDialog::on_unmap ();
}

View File

@ -37,6 +37,7 @@
#include <gtkmm/separator.h>
#include <gtkmm/spinbutton.h>
#include "widgets/ardour_dropdown.h"
#include "pbd/signals.h"
#include "pbd/crossthread.h"
@ -55,18 +56,25 @@ class AudioRegionView;
class AudioRegionEditor : public RegionEditor
{
public:
AudioRegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::AudioRegion>);
AudioRegionEditor (ARDOUR::Session*, AudioRegionView*);
~AudioRegionEditor ();
void peak_amplitude_thread ();
void on_unmap ();
private:
void region_changed (PBD::PropertyChange const &);
void region_fx_changed ();
void gain_changed ();
void gain_adjustment_changed ();
void refill_region_line ();
void show_on_touch_changed ();
void show_touched_automation (std::weak_ptr<PBD::Controllable>);
AudioRegionView* _arv;
std::shared_ptr<ARDOUR::AudioRegion> _audio_region;
Gtk::Label gain_label;
@ -79,6 +87,12 @@ private:
Gtk::Label _peak_amplitude_label;
Gtk::Entry _peak_amplitude;
Gtk::Label _region_line_label;
ArdourWidgets::ArdourDropdown _region_line;
Gtk::CheckButton _show_on_touch;
PBD::ScopedConnection _ctrl_touched_connection;
void signal_peak_thread ();
pthread_t _peak_amplitude_thread_handle;
void peak_amplitude_found (double);

View File

@ -36,6 +36,7 @@
#include "ardour/audioregion.h"
#include "ardour/audiosource.h"
#include "ardour/profile.h"
#include "ardour/region_fx_plugin.h"
#include "ardour/session.h"
#include "pbd/memento_command.h"
@ -112,8 +113,7 @@ static Cairo::RefPtr<Cairo::Pattern> create_pending_peak_pattern() {
return p;
}
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu,
uint32_t basic_color)
AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxisView &tv, std::shared_ptr<AudioRegion> r, double spu, uint32_t basic_color)
: RegionView (parent, tv, r, spu, basic_color)
, fade_in_handle(0)
, fade_out_handle(0)
@ -129,6 +129,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
, _amplitude_above_axis(1.0)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
}
@ -149,6 +152,9 @@ AudioRegionView::AudioRegionView (ArdourCanvas::Container *parent, RouteTimeAxis
, _amplitude_above_axis(1.0)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
}
@ -168,6 +174,9 @@ AudioRegionView::AudioRegionView (const AudioRegionView& other, std::shared_ptr<
, _amplitude_above_axis (other._amplitude_above_axis)
, trim_fade_in_drag_active(false)
, trim_fade_out_drag_active(false)
, _rfx_id (0)
, _rdx_param (UINT32_MAX)
, _ignore_line_change (false)
{
init (true);
}
@ -232,12 +241,7 @@ AudioRegionView::init (bool wfd)
set_fade_visibility (false);
}
const string line_name = _region->name() + ":gain";
gain_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
update_envelope_visibility ();
gain_line->reset ();
set_region_gain_line ();
/* streamview will call set_height() */
//set_height (trackview.current_height()); // XXX not correct for Layered mode, but set_height() will fix later.
@ -278,7 +282,7 @@ AudioRegionView::init (bool wfd)
setup_waveform_visibility ();
get_canvas_frame()->set_data ("linemerger", (LineMerger*) this);
gain_line->canvas_group().raise_to_top ();
_fx_line->canvas_group().raise_to_top ();
/* XXX sync mark drag? */
}
@ -606,15 +610,15 @@ AudioRegionView::set_height (gdouble height)
}
}
if (gain_line) {
if (_fx_line) {
if ((height / nchans) < NAME_HIGHLIGHT_THRESH) {
gain_line->hide ();
_fx_line->hide ();
} else {
update_envelope_visibility ();
}
gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE) - 2);
}
reset_fade_shapes ();
@ -1081,8 +1085,8 @@ AudioRegionView::set_samples_per_pixel (gdouble fpp)
}
}
if (gain_line) {
gain_line->reset ();
if (_fx_line) {
_fx_line->reset ();
}
reset_fade_shapes ();
@ -1101,12 +1105,7 @@ AudioRegionView::set_colors ()
{
RegionView::set_colors();
if (gain_line) {
gain_line->set_line_color (audio_region()->envelope_active() ?
UIConfiguration::instance().color ("gain line") :
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
}
set_fx_line_colors ();
set_waveform_colors ();
if (start_xfade_curve) {
@ -1148,8 +1147,8 @@ AudioRegionView::setup_waveform_visibility ()
void
AudioRegionView::temporarily_hide_envelope ()
{
if (gain_line) {
gain_line->hide ();
if (_fx_line) {
_fx_line->hide ();
}
}
@ -1159,21 +1158,121 @@ AudioRegionView::unhide_envelope ()
update_envelope_visibility ();
}
void
AudioRegionView::set_region_gain_line ()
{
if (_ignore_line_change) {
return;
}
const string line_name = _region->name() + ":gain";
_fx_line.reset (new AudioRegionGainLine (line_name, *this, *group, audio_region()->envelope()));
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->reset ();
_region_fx_connection.disconnect ();
bool changed = _rfx_id != PBD::ID (0) || _rdx_param != UINT32_MAX;
_rfx_id = PBD::ID (0);
_rdx_param = UINT32_MAX;
envelope_active_changed ();
if (changed) {
region_line_changed (); /* EMIT SIGNAL */
}
}
void
AudioRegionView::set_region_fx_line (std::shared_ptr<AutomationControl> ac, std::shared_ptr<RegionFxPlugin> rfx, uint32_t param_id)
{
const string line_name = _region->name () + ":" + rfx->describe_parameter (Evoral::Parameter (PluginAutomation, 0, param_id));
_fx_line.reset (new RegionFxLine (line_name, *this, *group, ac));
_fx_line->set_height ((uint32_t) rint (height() - NAME_HIGHLIGHT_SIZE) - 2);
_fx_line->reset ();
rfx->DropReferences.connect (_region_fx_connection, invalidator (*this), boost::bind (&AudioRegionView::set_region_gain_line, this), gui_context ());
bool changed = _rfx_id != rfx->id () || _rdx_param != param_id;
_rfx_id = rfx->id ();
_rdx_param = param_id;
envelope_active_changed ();
if (changed) {
region_line_changed (); /* EMIT SIGNAL */
}
}
bool
AudioRegionView::set_region_fx_line (uint32_t plugin_id, uint32_t param_id)
{
if (_ignore_line_change) {
return false;
}
std::shared_ptr<RegionFxPlugin> rfx = _region->nth_plugin (plugin_id);
if (rfx) {
std::shared_ptr<Evoral::Control> c = rfx->control (Evoral::Parameter (PluginAutomation, 0, param_id));
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (c);
if (ac) {
set_region_fx_line (ac, rfx, param_id);
return true;
}
}
return false;
}
bool
AudioRegionView::set_region_fx_line (std::weak_ptr<PBD::Controllable> wac)
{
if (_ignore_line_change) {
return false;
}
std::shared_ptr<AutomationControl> ac = std::dynamic_pointer_cast<AutomationControl> (wac.lock ());
if (!ac) {
return false;
}
bool found = false;
_region->foreach_plugin ([this, ac, &found](std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> rfx (wfx.lock ());
if (!rfx || found) {
return;
}
std::shared_ptr<Plugin> plugin = rfx->plugin ();
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
if (ac == std::dynamic_pointer_cast<ARDOUR::AutomationControl> (rfx->control (param))) {
set_region_fx_line (ac, rfx, i);
found = true;
break;
}
}
});
return found;
}
bool
AudioRegionView::get_region_fx_line (PBD::ID& id, uint32_t& param_id)
{
id = _rfx_id;
param_id = _rdx_param;
return _rdx_param != UINT32_MAX && _rfx_id != 0;
}
void
AudioRegionView::update_envelope_visibility ()
{
if (!gain_line) {
if (!_fx_line) {
return;
}
if (trackview.editor().current_mouse_mode() == Editing::MouseDraw || trackview.editor().current_mouse_mode() == Editing::MouseContent ) {
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
gain_line->canvas_group().raise_to_top ();
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::ControlPoints|AutomationLine::Line));
_fx_line->canvas_group().raise_to_top ();
} else if (UIConfiguration::instance().get_show_region_gain() || trackview.editor().current_mouse_mode() == Editing::MouseRange ) {
gain_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
gain_line->canvas_group().raise_to_top ();
_fx_line->set_visibility (AutomationLine::VisibleAspects(AutomationLine::Line));
_fx_line->canvas_group().raise_to_top ();
} else {
gain_line->set_visibility (AutomationLine::VisibleAspects(0));
_fx_line->set_visibility (AutomationLine::VisibleAspects(0));
}
}
@ -1374,7 +1473,7 @@ AudioRegionView::peaks_ready_handler (uint32_t which)
void
AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, bool with_guard_points)
{
if (!gain_line) {
if (!_fx_line) {
return;
}
@ -1386,18 +1485,17 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
samplecnt_t const sample_within_region = (samplecnt_t) floor (mx * samples_per_pixel);
if (!gain_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
/* no adjacent points */
return;
double y = my;
if (_fx_line->control_points_adjacent (sample_within_region, before_p, after_p)) {
/* y is in item frame */
double const bx = _fx_line->nth (before_p)->get_x();
double const ax = _fx_line->nth (after_p)->get_x();
double const click_ratio = (ax - mx) / (ax - bx);
y = ((_fx_line->nth (before_p)->get_y() * click_ratio) + (_fx_line->nth (after_p)->get_y() * (1 - click_ratio)));
}
/* y is in item frame */
double const bx = gain_line->nth (before_p)->get_x();
double const ax = gain_line->nth (after_p)->get_x();
double const click_ratio = (ax - mx) / (ax - bx);
double y = ((gain_line->nth (before_p)->get_y() * click_ratio) + (gain_line->nth (after_p)->get_y() * (1 - click_ratio)));
/* don't create points that can't be seen */
update_envelope_visibility ();
@ -1412,55 +1510,37 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev, b
/* compute vertical fractional position */
y = 1.0 - (y / (gain_line->height()));
y = 1.0 - (y / (_fx_line->height()));
/* map using gain line */
gain_line->view_to_model_coord_y (y);
_fx_line->view_to_model_coord_y (y);
/* XXX STATEFUL: can't convert to stateful diff until we
can represent automation data with it.
*/
XMLNode &before = audio_region()->envelope()->get_state();
MementoCommand<AudioRegion>* region_memento = 0;
if (!audio_region()->envelope_active()) {
XMLNode &region_before = audio_region()->get_state();
audio_region()->set_envelope_active(true);
XMLNode &region_after = audio_region()->get_state();
region_memento = new MementoCommand<AudioRegion>(*(audio_region().get()), &region_before, &region_after);
}
if (audio_region()->envelope()->editor_add (timepos_t (fx), y, with_guard_points)) {
XMLNode &after = audio_region()->envelope()->get_state();
XMLNode &before = _fx_line->the_list()->get_state();
if (_fx_line->the_list()->editor_add (timepos_t (fx), y, with_guard_points)) {
XMLNode &after = _fx_line->the_list()->get_state();
std::list<Selectable*> results;
trackview.editor().begin_reversible_command (_("add gain control point"));
if (region_memento) {
trackview.session()->add_command (region_memento);
}
_fx_line->enable_autoation ();
trackview.session()->add_command (new MementoCommand<AutomationList>(*audio_region()->envelope().get(), &before, &after));
trackview.session()->add_command (new MementoCommand<AutomationList>(*_fx_line->the_list(), &before, &after));
gain_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
_fx_line->get_selectables (region ()->position () + timecnt_t (fx), region ()->position () + timecnt_t (fx), 0.0, 1.0, results);
trackview.editor ().get_selection ().set (results);
trackview.editor ().commit_reversible_command ();
trackview.session ()->set_dirty ();
} else {
delete region_memento;
delete &before;
}
}
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());
}
GhostRegion*
AudioRegionView::add_ghost (TimeAxisView& tv)
{
@ -1557,10 +1637,6 @@ AudioRegionView::exited ()
trackview.editor().set_current_trimmable (std::shared_ptr<Trimmable>());
trackview.editor().set_current_movable (std::shared_ptr<Movable>());
// if (gain_line) {
// gain_line->remove_visibility (AutomationLine::ControlPoints);
// }
if (fade_in_handle) { fade_in_handle->hide(); }
if (fade_out_handle) { fade_out_handle->hide(); }
if (fade_in_trim_handle) { fade_in_trim_handle->hide(); }
@ -1572,12 +1648,8 @@ AudioRegionView::exited ()
void
AudioRegionView::envelope_active_changed ()
{
if (gain_line) {
gain_line->set_line_color (audio_region()->envelope_active() ?
UIConfiguration::instance().color ("gain line") :
UIConfiguration::instance().color_mod ("gain line inactive", "gain line inactive"));
update_envelope_visibility ();
}
set_fx_line_colors ();
update_envelope_visibility ();
}
void
@ -1595,6 +1667,22 @@ AudioRegionView::color_handler ()
}
void
AudioRegionView::set_fx_line_colors ()
{
if (!_fx_line) {
return;
}
if (_rdx_param != UINT32_MAX && _rfx_id != 0) {
_fx_line->set_line_color ("region automation line");
} else if (audio_region()->envelope_active()) {
_fx_line->set_line_color ("gain line");
} else {
_fx_line->set_line_color ("gain line inactive", "gain line inactive");
}
}
void
AudioRegionView::set_waveform_colors ()
{
@ -1696,7 +1784,7 @@ void
AudioRegionView::show_region_editor ()
{
if (editor == 0) {
editor = new AudioRegionEditor (trackview.session(), audio_region());
editor = new AudioRegionEditor (trackview.session(), this);
}
editor->present ();
@ -1858,7 +1946,7 @@ AudioRegionView::parameter_changed (string const & p)
MergeableLine*
AudioRegionView::make_merger ()
{
return new MergeableLine (gain_line, std::shared_ptr<AutomationControl>(),
return new MergeableLine (_fx_line, std::shared_ptr<AutomationControl>(),
[this](timepos_t const& t) { return timepos_t (_region->position().distance (t)); },
nullptr, nullptr);
}

View File

@ -50,9 +50,9 @@ namespace ARDOUR {
};
class AudioTimeAxisView;
class AudioRegionGainLine;
class GhostRegion;
class AutomationTimeAxisView;
class RegionFxLine;
class RouteTimeAxisView;
class AudioRegionView : public RegionView, public LineMerger
@ -91,12 +91,18 @@ public:
void temporarily_hide_envelope (); ///< Dangerous!
void unhide_envelope (); ///< Dangerous!
void set_region_gain_line ();
void set_ignore_line_change (bool v) { _ignore_line_change = v; };
bool set_region_fx_line (uint32_t, uint32_t);
bool set_region_fx_line (std::weak_ptr<PBD::Controllable>);
bool get_region_fx_line (PBD::ID&, uint32_t&);
void update_envelope_visibility ();
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
void remove_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event);
sigc::signal<void> region_line_changed;
std::shared_ptr<AudioRegionGainLine> get_gain_line() const { return gain_line; }
void add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *event, bool with_guard_points);
std::shared_ptr<RegionFxLine> fx_line() const { return _fx_line; }
void region_changed (const PBD::PropertyChange&);
void envelope_active_changed ();
@ -184,7 +190,7 @@ protected:
ArdourCanvas::Rectangle* end_xfade_rect;
bool _end_xfade_visible;
std::shared_ptr<AudioRegionGainLine> gain_line;
std::shared_ptr<RegionFxLine> _fx_line;
double _amplitude_above_axis;
@ -206,6 +212,7 @@ protected:
void set_colors ();
void set_waveform_colors ();
void set_fx_line_colors ();
void reset_width_dependent_items (double pixel_width);
void color_handler ();
@ -234,6 +241,14 @@ private:
bool trim_fade_in_drag_active;
bool trim_fade_out_drag_active;
void set_region_fx_line (std::shared_ptr<ARDOUR::AutomationControl>, std::shared_ptr<ARDOUR::RegionFxPlugin>, uint32_t);
PBD::ID _rfx_id;
uint32_t _rdx_param;
bool _ignore_line_change;
PBD::ScopedConnection _region_fx_connection;
};
#endif /* __gtk_ardour_audio_region_view_h__ */

View File

@ -470,8 +470,8 @@ AudioStreamView::set_selected_points (PointSelection& points)
{
for (list<RegionView *>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv && arv->get_gain_line ()) {
arv->get_gain_line ()->set_selected_points (points);
if (arv && arv->fx_line ()) {
arv->fx_line ()->set_selected_points (points);
}
}
}

View File

@ -87,11 +87,12 @@ using namespace Temporal;
AutomationLine::AutomationLine (const string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<AutomationList> al,
std::shared_ptr<AutomationList> al,
const ParameterDescriptor& desc)
: trackview (tv)
, _name (name)
, _height (0)
, _line_color ("automation line")
, _view_index_offset (0)
, alist (al)
, _visible (Line)
@ -264,14 +265,23 @@ AutomationLine::set_height (guint32 h)
}
void
AutomationLine::set_line_color (uint32_t color)
AutomationLine::set_line_color (string color_name, std::string color_mod)
{
_line_color = color;
_line_color = color_name;
_line_color_mod = color_mod;
uint32_t color = UIConfiguration::instance().color (color_name);
line->set_outline_color (color);
Gtkmm2ext::SVAModifier mod = UIConfiguration::instance().modifier ("automation line fill");
Gtkmm2ext::SVAModifier mod = UIConfiguration::instance().modifier (color_mod.empty () ? "automation line fill" : color_mod);
line->set_fill_color ((color & 0xffffff00) + mod.a()*255);
line->set_fill_color ((color & 0xffffff00) + mod.a() * 255);
}
uint32_t
AutomationLine::get_line_color() const
{
return UIConfiguration::instance().color (_line_color);
}
ControlPoint*
@ -996,7 +1006,7 @@ AutomationLine::set_selected_points (PointSelection const & points)
void
AutomationLine::set_colors ()
{
set_line_color (UIConfiguration::instance().color ("automation line"));
set_line_color (_line_color, _line_color_mod);
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->set_color ();
}

View File

@ -68,7 +68,7 @@ public:
AutomationLine (const std::string& name,
TimeAxisView& tv,
ArdourCanvas::Item& parent,
std::shared_ptr<ARDOUR::AutomationList> al,
std::shared_ptr<ARDOUR::AutomationList> al,
const ARDOUR::ParameterDescriptor& desc);
@ -94,6 +94,7 @@ public:
virtual void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode *);
virtual std::pair<float, float> drag_motion (Temporal::timecnt_t const &, float, bool, bool with_push, uint32_t& final_index);
virtual void end_drag (bool with_push, uint32_t final_index);
virtual void end_draw_merge () {}
ControlPoint* nth (uint32_t);
ControlPoint const * nth (uint32_t) const;
@ -103,8 +104,8 @@ public:
bool visible() const { return _visible != VisibleAspects(0); }
guint32 height() const { return _height; }
void set_line_color (uint32_t);
uint32_t get_line_color() const { return _line_color; }
void set_line_color (std::string color, std::string mod = "");
uint32_t get_line_color() const;
void set_visibility (VisibleAspects);
void add_visibility (VisibleAspects);
@ -173,7 +174,8 @@ protected:
std::string _name;
guint32 _height;
uint32_t _line_color;
std::string _line_color;
std::string _line_color_mod;
uint32_t _view_index_offset;
std::shared_ptr<ARDOUR::AutomationList> alist;
@ -247,6 +249,7 @@ private:
const ARDOUR::ParameterDescriptor _desc;
friend class AudioRegionGainLine;
friend class RegionFxLine;
};
#endif /* __ardour_automation_line_h__ */

View File

@ -350,7 +350,7 @@ AutomationTimeAxisView::add_contents (bool show_regions)
)
);
line->set_line_color (UIConfiguration::instance().color ("processor automation line"));
line->set_line_color ("processor automation line");
line->set_fill (true);
line->queue_reset ();
add_line (line);

View File

@ -343,6 +343,7 @@ Editor::Editor ()
, cd_mark_label (_("CD Markers"))
, section_mark_label (_("Arrangement"))
, cue_mark_label (_("Cue Markers"))
, scene_mark_label (_("Scenes"))
, videotl_label (_("Video Timeline"))
, videotl_group (0)
, _region_boundary_cache_dirty (true)
@ -473,6 +474,7 @@ Editor::Editor ()
, quantize_dialog (0)
, _main_menu_disabler (0)
, domain_bounce_info (nullptr)
, track_drag (nullptr)
{
/* we are a singleton */
@ -576,6 +578,13 @@ Editor::Editor ()
cue_mark_label.hide();
cue_mark_label.set_no_show_all();
scene_mark_label.set_name ("EditorRulerLabel");
scene_mark_label.set_size_request (-1, (int)timebar_height);
scene_mark_label.set_alignment (1.0, 0.5);
scene_mark_label.set_padding (5,0);
scene_mark_label.hide();
scene_mark_label.set_no_show_all();
videotl_bar_height = 4;
videotl_label.set_name ("EditorRulerLabel");
videotl_label.set_size_request (-1, (int)timebar_height * videotl_bar_height);
@ -640,7 +649,6 @@ Editor::Editor ()
_cursors = new MouseCursors;
_cursors->set_cursor_set (UIConfiguration::instance().get_icon_set());
cerr << "Set cursor set to " << UIConfiguration::instance().get_icon_set() << endl;
/* Push default cursor to ever-present bottom of cursor stack. */
push_canvas_cursor(_cursors->grabber);
@ -4282,6 +4290,11 @@ Editor::override_visible_track_count ()
bool
Editor::edit_controls_button_event (GdkEventButton* ev)
{
if (ev->type == GDK_BUTTON_RELEASE && track_dragging()) {
end_track_drag ();
return true;
}
if ((ev->type == GDK_2BUTTON_PRESS && ev->button == 1) || (ev->type == GDK_BUTTON_RELEASE && Keyboard::is_context_menu_event (ev))) {
ARDOUR_UI::instance()->add_route ();
} else if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) {
@ -6170,6 +6183,54 @@ struct TrackViewStripableSorter
}
};
static const int track_drag_spacer_height = 25;
void
Editor::maybe_move_tracks ()
{
for (auto & tv : track_views) {
if (!tv->marked_for_display () || (tv == track_drag->track)) {
continue;
}
/* find the track the mouse pointer is within, and if
* we're in the upper or lower half of it (depending on
* drag direction, move the spacer.
*/
if (track_drag->current >= tv->y_position() && track_drag->current < (tv->y_position() + tv->effective_height())) {
if (track_drag->bump_track == tv) {
/* already bumped for this track */
break;
}
if (track_drag->direction < 0) {
/* dragging up */
if (track_drag->current < (tv->y_position() + (tv->effective_height() / 2))) {
/* in top half of this track, move spacer */
track_drag->bump_track = tv;
move_selected_tracks (true);
}
} else if (track_drag->direction > 0) {
/* dragging down */
if (track_drag->current > (tv->y_position() + (tv->effective_height() / 2))) {
track_drag->bump_track = tv;
move_selected_tracks (false);
}
}
break;
}
}
}
bool
Editor::redisplay_track_views ()
{
@ -6186,21 +6247,24 @@ Editor::redisplay_track_views ()
track_views.sort (TrackViewStripableSorter ());
uint32_t position;
TrackViewList::const_iterator i;
if (track_drag) { // && track_drag->spacer) {
maybe_move_tracks ();
}
/* n will be the count of tracks plus children (updated by TimeAxisView::show_at),
* so we will use that to know where to put things.
*/
int n;
for (n = 0, position = 0, i = track_views.begin(); i != track_views.end(); ++i) {
TimeAxisView *tv = (*i);
int n = 0;
uint32_t position = 0;
for (auto & tv : track_views) {
if (tv->marked_for_display ()) {
position += tv->show_at (position, n, &edit_controls_vbox);
} else {
tv->hide ();
}
n++;
}
@ -7002,3 +7066,74 @@ Editor::default_time_domain () const
}
return BeatTime;
}
void
Editor::start_track_drag (TimeAxisView& tav, int y, Gtk::Widget& w)
{
track_drag = new TrackDrag (dynamic_cast<RouteTimeAxisView*> (&tav));
track_drag->drag_cursor = _cursors->move->gobj();
track_drag->predrag_cursor = gdk_window_get_cursor (edit_controls_vbox.get_window()->gobj());
gdk_window_set_cursor (edit_controls_vbox.get_toplevel()->get_window()->gobj(), track_drag->drag_cursor);
int xo, yo;
w.translate_coordinates (edit_controls_vbox, 0, y, xo, yo);
track_drag->have_predrag_cursor = true;
track_drag->bump_track = nullptr;
track_drag->previous = yo;
track_drag->start = yo;
}
void
Editor::mid_track_drag (GdkEventMotion* ev, Gtk::Widget& w)
{
int xo, yo;
w.translate_coordinates (edit_controls_vbox, ev->x, ev->y, xo, yo);
if (track_drag->first_move) {
if (!track_drag->track->selected()) {
set_selected_track (*track_drag->track, Selection::Set, false);
}
track_drag->first_move = false;
}
track_drag->current = yo;
if (track_drag->current > track_drag->previous) {
if (track_drag->direction != 1) {
track_drag->bump_track = nullptr;
track_drag->direction = 1;
}
} else if (track_drag->current < track_drag->previous) {
if (track_drag->direction != -1) {
track_drag->bump_track = nullptr;
track_drag->direction = -1;
}
}
if (track_drag->current == track_drag->previous) {
return;
}
redisplay_track_views ();
track_drag->previous = yo;
}
void
Editor::end_track_drag ()
{
if (track_drag->have_predrag_cursor) {
gdk_window_set_cursor (edit_controls_vbox.get_toplevel()->get_window()->gobj(), track_drag->predrag_cursor);
}
delete track_drag;
track_drag = nullptr;
}
bool
Editor::track_dragging() const
{
return (bool) track_drag;
}

View File

@ -939,6 +939,7 @@ private:
ArdourCanvas::Container* cd_marker_group;
ArdourCanvas::Container* section_marker_group;
ArdourCanvas::Container* cue_marker_group;
ArdourCanvas::Container* scene_marker_group;
/* parent for groups which themselves contain time markers */
ArdourCanvas::Container* _time_markers_group;
@ -992,6 +993,7 @@ private:
Glib::RefPtr<Gtk::ToggleAction> ruler_section_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_marker_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_cue_marker_action;
Glib::RefPtr<Gtk::ToggleAction> ruler_scene_marker_action;
bool no_ruler_shown_update;
Gtk::Widget* ruler_grabbed_widget;
@ -1083,6 +1085,7 @@ private:
ArdourCanvas::Rectangle* cd_marker_bar;
ArdourCanvas::Rectangle* section_marker_bar;
ArdourCanvas::Rectangle* cue_marker_bar;
ArdourCanvas::Rectangle* scene_marker_bar;
ArdourCanvas::Line* ruler_separator;
void toggle_cue_behavior ();
@ -1099,6 +1102,7 @@ private:
Gtk::Label cd_mark_label;
Gtk::Label section_mark_label;
Gtk::Label cue_mark_label;
Gtk::Label scene_mark_label;
/* videtimline related actions */
Gtk::Label videotl_label;
@ -1409,6 +1413,11 @@ private:
void insert_patch_change (bool from_context);
void fork_selected_regions ();
void fork_regions_from_unselected ();
void start_track_drag (TimeAxisView&, int y, Gtk::Widget& w);
void mid_track_drag (GdkEventMotion*, Gtk::Widget& e);
void end_track_drag ();
void maybe_move_tracks ();
bool track_dragging() const;
void do_insert_time ();
void insert_time (Temporal::timepos_t const &, Temporal::timecnt_t const &, Editing::InsertTimeOption, bool, bool, bool, bool);
@ -1593,6 +1602,7 @@ private:
void clear_xrun_markers ();
void clear_ranges ();
void clear_cues ();
void clear_scenes ();
void clear_locations ();
void unhide_markers ();
void unhide_ranges ();
@ -2593,6 +2603,35 @@ private:
friend class Drag;
friend class RegionCutDrag;
friend class RegionDrag;
struct TrackDrag {
RouteTimeAxisView* track;
GdkCursor* drag_cursor;
GdkCursor* predrag_cursor;
TimeAxisView* bump_track;
double start;
double current;
double previous;
bool have_predrag_cursor;
int direction;
bool first_move;
TrackDrag (RouteTimeAxisView* rtav)
: track (rtav)
, drag_cursor (nullptr)
, predrag_cursor (nullptr)
, bump_track (nullptr)
, start (-1.)
, current (0.)
, previous (0.)
, have_predrag_cursor (false)
, direction (0)
, first_move (true)
{}
};
TrackDrag* track_drag;
friend class RegionMoveDrag;
friend class TrimDrag;
friend class MappingTwistDrag;

View File

@ -697,6 +697,7 @@ Editor::register_actions ()
ruler_cd_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-cd-marker-ruler"), _("CD Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_section_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-arrangement-ruler"), _("Arrangement"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-marker-ruler"), _("Location Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_scene_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-scene-marker-ruler"), _("Scene Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ruler_cue_marker_action = Glib::RefPtr<ToggleAction>::cast_static (ActionManager::register_toggle_action (ruler_actions, X_("toggle-cue-marker-ruler"), _("Cue Markers"), sigc::mem_fun(*this, &Editor::toggle_ruler_visibility)));
ActionManager::register_action (editor_menu_actions, X_("VideoMonitorMenu"), _("Video Monitor"));
@ -727,6 +728,7 @@ Editor::register_actions ()
ruler_cd_marker_action->set_active (true);
ruler_marker_action->set_active (true);
ruler_cue_marker_action->set_active (true);
ruler_scene_marker_action->set_active (false);
ruler_video_action->set_active (false);
xjadeo_proc_action->set_active (false);
@ -892,7 +894,7 @@ Editor::register_midi_actions (Bindings* midi_bindings)
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-bar"), grid_type_strings[(int)GridTypeBar].c_str(), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), Editing::GridTypeBar)));
ActionManager::register_radio_action (length_actions, draw_length_group, X_("draw-length-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_length_chosen), DRAW_LEN_AUTO)));
Glib::RefPtr<ActionGroup> velocity_actions = ActionManager::create_action_group (midi_bindings, _("Draw Velocity"));
Glib::RefPtr<ActionGroup> velocity_actions = ActionManager::create_action_group (midi_bindings, X_("DrawVelocity"));
RadioAction::Group draw_velocity_group;
ActionManager::register_radio_action (velocity_actions, draw_velocity_group, X_("draw-velocity-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_velocity_chosen), DRAW_VEL_AUTO)));
for (int i = 1; i <= 127; i++) {
@ -903,7 +905,7 @@ Editor::register_midi_actions (Bindings* midi_bindings)
ActionManager::register_radio_action (velocity_actions, draw_velocity_group, buf, vel, (sigc::bind (sigc::mem_fun(*this, &Editor::draw_velocity_chosen), i)));
}
Glib::RefPtr<ActionGroup> channel_actions = ActionManager::create_action_group (midi_bindings, _("Draw Channel"));
Glib::RefPtr<ActionGroup> channel_actions = ActionManager::create_action_group (midi_bindings, X_("DrawChannel"));
RadioAction::Group draw_channel_group;
ActionManager::register_radio_action (channel_actions, draw_channel_group, X_("draw-channel-auto"), _("Auto"), (sigc::bind (sigc::mem_fun(*this, &Editor::draw_channel_chosen), DRAW_CHAN_AUTO)));
for (int i = 0; i <= 15; i++) {
@ -1186,7 +1188,7 @@ Editor::draw_velocity_action (int v)
action = buf;
}
act = ActionManager::get_action (_("Draw Velocity"), action);
act = ActionManager::get_action (X_("DrawVelocity"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;
@ -1210,7 +1212,7 @@ Editor::draw_channel_action (int c)
action = buf;
}
act = ActionManager::get_action (_("Draw Channel"), action);
act = ActionManager::get_action (X_("DrawChannel"), action);
if (act) {
RefPtr<RadioAction> ract = RefPtr<RadioAction>::cast_dynamic(act);
return ract;

View File

@ -173,6 +173,8 @@ Editor::initialize_canvas ()
CANVAS_DEBUG_NAME (section_marker_group, "Arranger marker group");
meter_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0));
CANVAS_DEBUG_NAME (meter_group, "meter group");
scene_marker_group = new ArdourCanvas::Container (_time_markers_group, ArdourCanvas::Duple (0.0, (timebar_height * 5.0) + 1.0));
CANVAS_DEBUG_NAME (scene_marker_group, "scene marker_group");
float timebar_thickness = timebar_height; //was 4
float timebar_top = (timebar_height - timebar_thickness)/2;
@ -207,6 +209,9 @@ Editor::initialize_canvas ()
cue_marker_bar = new ArdourCanvas::Rectangle (cue_marker_group, ArdourCanvas::Rect (0.0, timebar_top, ArdourCanvas::COORD_MAX, timebar_btm));
CANVAS_DEBUG_NAME (cue_marker_bar, "Cue Marker Bar");
scene_marker_bar = new ArdourCanvas::Rectangle (scene_marker_group, ArdourCanvas::Rect (0.0, timebar_top, ArdourCanvas::COORD_MAX, timebar_btm));
CANVAS_DEBUG_NAME (cue_marker_bar, "Scene Marker Bar");
ruler_separator = new ArdourCanvas::Line(_time_markers_group);
CANVAS_DEBUG_NAME (ruler_separator, "separator between ruler and main canvas");
ruler_separator->set (ArdourCanvas::Duple(0.0, 0.0), ArdourCanvas::Duple(ArdourCanvas::COORD_MAX, 0.0));
@ -256,6 +261,7 @@ Editor::initialize_canvas ()
cd_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), cd_marker_bar, CdMarkerBarItem, "cd marker bar"));
section_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), section_marker_bar, SectionMarkerBarItem, "arrangement marker bar"));
cue_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), cue_marker_bar, CueMarkerBarItem, "cd marker bar"));
scene_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), scene_marker_bar, SceneMarkerBarItem, "scene marker bar"));
videotl_group->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_videotl_bar_event), videotl_group));
range_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), range_marker_bar, RangeMarkerBarItem, "range marker bar"));
transport_marker_bar->Event.connect (sigc::bind (sigc::mem_fun (*this, &Editor::canvas_ruler_bar_event), transport_marker_bar, TransportMarkerBarItem, "transport marker bar"));
@ -1091,6 +1097,9 @@ Editor::color_handler()
section_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("arrangement marker bar", "marker bar"));
section_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
scene_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("arrangement marker bar", "marker bar"));
scene_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
cue_marker_bar->set_fill_color (UIConfiguration::instance().color_mod ("cd marker bar", "marker bar"));
cue_marker_bar->set_outline_color (UIConfiguration::instance().color ("marker bar separator"));
@ -1498,6 +1507,7 @@ Editor::which_canvas_cursor(ItemType type) const
case CdMarkerBarItem:
case SectionMarkerBarItem:
case CueMarkerBarItem:
case SceneMarkerBarItem:
case VideoBarItem:
case TransportMarkerBarItem:
case DropZoneItem:

View File

@ -707,11 +707,11 @@ bool
Editor::canvas_line_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationLine* al)
{
ItemType type;
AudioRegionGainLine* gl;
if ((gl = dynamic_cast<AudioRegionGainLine*> (al)) != 0) {
RegionFxLine* rfl;
if ((rfl = dynamic_cast<RegionFxLine*> (al)) != 0) {
type = GainLineItem;
if (event->type == GDK_BUTTON_PRESS) {
clicked_regionview = &gl->region_view ();
clicked_regionview = &rfl->region_view ();
}
} else {
type = AutomationLineItem;

View File

@ -5039,7 +5039,7 @@ LineDrag::finished (GdkEvent* event, bool movement_occurred)
AudioRegionView* arv;
if ((arv = dynamic_cast<AudioRegionView*> (_editor->clicked_regionview)) != 0) {
arv->add_gain_point_event (&arv->get_gain_line ()->grab_item (), event, false);
arv->add_gain_point_event (&arv->fx_line ()->grab_item (), event, false);
}
}
}
@ -6367,7 +6367,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list<RegionView*> cons
for (list<RegionView*>::const_iterator i = v.begin (); i != v.end (); ++i) {
if (AudioRegionView* audio_view = dynamic_cast<AudioRegionView*> (*i)) {
lines.push_back (audio_view->get_gain_line ());
lines.push_back (audio_view->fx_line ());
} else if (AutomationRegionView* automation_view = dynamic_cast<AutomationRegionView*> (*i)) {
lines.push_back (automation_view->line ());
_integral = true;
@ -6394,8 +6394,8 @@ AutomationRangeDrag::setup (list<std::shared_ptr<AutomationLine>> const& lines)
/* need a special detection for automation lanes (not region gain line) */
// TODO: if we implement automation regions, this check can probably be removed
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> ((*i).get ());
if (!argl) {
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> ((*i).get ());
if (!fxl) {
/* in automation lanes, the EFFECTIVE range should be considered 0->max_position (even if there is no line) */
r.first = Temporal::timepos_t ((*i)->the_list ()->time_domain ());
r.second = Temporal::timepos_t::max ((*i)->the_list ()->time_domain ());
@ -7267,7 +7267,7 @@ FreehandLineDrag<OrderedPointList,OrderedPoint>::motion (GdkEvent* ev, bool firs
dragging_line = new ArdourCanvas::PolyLine (parent ? parent : item());
dragging_line->set_ignore_events (true);
dragging_line->set_outline_width (2.0);
dragging_line->set_outline_color (UIConfiguration::instance().color ("automation line"));
dragging_line->set_outline_color (UIConfiguration::instance().color ("automation line")); // XXX -> get color from AutomationLine
dragging_line->raise_to_top ();
/* for freehand drawing, we only support left->right direction, for now. */

View File

@ -27,11 +27,13 @@ enum ItemType {
WaveItem,
PlayheadCursorItem,
MarkerItem,
SceneMarkerItem,
MarkerBarItem,
RangeMarkerBarItem,
CdMarkerBarItem,
SectionMarkerBarItem,
CueMarkerBarItem,
SceneMarkerBarItem,
VideoBarItem,
TransportMarkerBarItem,
SelectionItem,

View File

@ -145,6 +145,8 @@ Editor::add_new_location_internal (Location* location)
color = X_("location loop");
} else if (location->is_auto_punch()) {
color = X_("location punch");
} else if (location->is_scene()) {
color = X_("location scene");
} else {
color = X_("location range");
}
@ -161,6 +163,9 @@ Editor::add_new_location_internal (Location* location)
} else if (location->is_section()) {
lam->start = new ArdourMarker (*this, *section_marker_group, color, location->name(), marker_type (location), location->start());
group = section_marker_group;
} else if (location->is_scene()) {
lam->start = new ArdourMarker (*this, *scene_marker_group, color, location->name(), marker_type (location), location->start());
group = scene_marker_group;
} else {
lam->start = new ArdourMarker (*this, *marker_group, color, location->name(), marker_type (location), location->start());
group = marker_group;
@ -301,7 +306,10 @@ Editor::check_marker_label (ArdourMarker* m)
list<ArdourMarker*>::iterator prev = sorted.end ();
list<ArdourMarker*>::iterator next = i;
++next;
if (next != sorted.end()) {
++next;
}
/* Look to see if the previous marker is still behind `m' in time */
if (i != sorted.begin()) {
@ -309,7 +317,7 @@ Editor::check_marker_label (ArdourMarker* m)
prev = i;
--prev;
if ((*prev)->position() > m->position()) {
if ((*prev)->position() >= m->position()) {
/* This marker is no longer in the correct order with the previous one, so
* update all the markers in this group.
*/
@ -346,8 +354,11 @@ Editor::check_marker_label (ArdourMarker* m)
}
}
if (next != sorted.end()) {
while (next != sorted.end() && (*next)->position () == m->position ()) {
++next;
}
if (next != sorted.end()) {
/* Update just the available space between this marker and the next */
double const p = sample_to_pixel (m->position().distance ((*next)->position()).samples());
@ -368,6 +379,9 @@ Editor::check_marker_label (ArdourMarker* m)
struct MarkerComparator {
bool operator() (ArdourMarker const * a, ArdourMarker const * b) {
if (a->position() == b->position()) {
return a->label_on_left ();
}
return a->position() < b->position();
}
};
@ -415,14 +429,29 @@ Editor::update_marker_labels (ArdourCanvas::Item* group)
while (i != sorted.end()) {
if (prev != sorted.end()) {
double const p = sample_to_pixel ((*prev)->position().distance ((*i)->position()).samples());
list<ArdourMarker*>::iterator pi = prev;
while (pi != sorted.begin () && (*pi)->position () == (*i)->position()) {
--pi;
}
double p = sample_to_pixel ((*pi)->position().distance ((*i)->position()).samples());
if (p == 0) {
p = DBL_MAX;
}
if ((*prev)->label_on_left()) {
(*i)->set_left_label_limit (p);
} else {
(*i)->set_left_label_limit (p / 2);
}
} else {
(*i)->set_left_label_limit (DBL_MAX);
}
while (next != sorted.end() && (*next)->position () == (*i)->position ()) {
++next;
}
if (next != sorted.end()) {
@ -435,6 +464,8 @@ Editor::update_marker_labels (ArdourCanvas::Item* group)
}
++next;
} else {
(*i)->set_right_label_limit (DBL_MAX);
}
prev = i;
@ -514,6 +545,8 @@ void Editor::ensure_marker_updated (LocationMarkers* lam, Location* location)
{
if (location->is_cd_marker()) {
reparent_location_markers (lam, cd_marker_group);
} else if (location->is_scene()) {
reparent_location_markers (lam, scene_marker_group);
} else if (location->is_section()) {
reparent_location_markers (lam, section_marker_group);
} else if (location->is_cue_marker()) {

View File

@ -775,6 +775,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
}
return true;
case SceneMarkerItem:
_drags->set (new MarkerDrag (this, item), event);
return true;
case TempoMarkerItem:
if (ArdourKeyboard::indicates_constraint (event->button.state)) {
@ -1731,6 +1734,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
marker_context_menu (&event->button, item);
break;
case SceneMarkerItem:
marker_context_menu (&event->button, item);
break;
case TempoMarkerItem:
case MeterMarkerItem:
case BBTMarkerItem:
@ -2340,7 +2347,7 @@ Editor::can_remove_control_point (ArdourCanvas::Item* item)
}
AutomationLine& line = control_point->line ();
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
if (dynamic_cast<RegionFxLine*> (&line)) {
/* we shouldn't remove the first or last gain point in region gain lines */
if (line.is_last_point(*control_point) || line.is_first_point(*control_point)) {
return false;

View File

@ -2683,6 +2683,22 @@ Editor::clear_cues ()
}
}
void
Editor::clear_scenes ()
{
begin_reversible_command (_("clear locations"));
XMLNode &before = _session->locations()->get_state();
if (_session->locations()->clear_scene_markers (0, max_samplepos)) {
XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
commit_reversible_command ();
} else {
abort_reversible_command ();
}
}
void
Editor::clear_locations ()
{
@ -4833,7 +4849,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
bool erase = true;
if (dynamic_cast<AudioRegionGainLine*> (&line)) {
if (dynamic_cast<RegionFxLine*> (&line)) {
/* removing of first and last gain point in region gain lines is prohibited*/
if (line.is_last_point (*(*sel_point)) || line.is_first_point (*(*sel_point))) {
erase = false;

View File

@ -180,6 +180,7 @@ Editor::initialize_rulers ()
lab_children.push_back (Element(cd_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(cue_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(scene_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(section_mark_label, PACK_SHRINK, PACK_START));
lab_children.push_back (Element(videotl_label, PACK_SHRINK, PACK_START));
@ -257,6 +258,10 @@ Editor::popup_ruler_menu (timepos_t const & where, ItemType t)
}
break;
case SceneMarkerBarItem:
ruler_items.push_back (MenuElem (_("Delete all Scenes"), sigc::mem_fun (*this, &Editor::clear_scenes)));
break;
case TempoBarItem:
case TempoCurveItem:
ruler_items.push_back (MenuElem (_("Add New Tempo"), sigc::bind (sigc::mem_fun(*this, &Editor::mouse_add_new_tempo_event), where)));
@ -673,7 +678,26 @@ Editor::update_ruler_visibility ()
cue_mark_label.hide();
}
if (ruler_section_action->get_active()) {
if (ruler_scene_marker_action->get_active()) {
old_unit_pos = scene_marker_group->position().y;
if (tbpos != old_unit_pos) {
scene_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));
}
scene_marker_group->show();
scene_mark_label.show();
scene_marker_bar->set_outline(false);
tbpos += timebar_height;
tbgpos += timebar_height;
visible_timebars++;
update_marker_display();
} else {
scene_marker_group->hide ();
scene_mark_label.hide ();
}
if (!Profile->get_livetrax() && ruler_section_action->get_active()) {
old_unit_pos = section_marker_group->position().y;
if (tbpos != old_unit_pos) {
section_marker_group->move (ArdourCanvas::Duple (0.0, tbpos - old_unit_pos));

View File

@ -228,6 +228,10 @@ EditorSections::scroll_row_timeout ()
void
EditorSections::update_time_selection ()
{
if (!_session) {
return;
}
_view.get_selection ()->unselect_all ();
Selection& selection (PublicEditor::instance ().get_selection ());
@ -256,6 +260,10 @@ EditorSections::update_time_selection ()
void
EditorSections::selection_changed ()
{
if (!_session) {
return;
}
TreeView::Selection::ListHandle_Path rows = _view.get_selection ()->get_selected_rows ();
if (rows.empty ()) {
return;
@ -354,7 +362,14 @@ EditorSections::drag_motion (Glib::RefPtr<Gdk::DragContext> const& context, int
path.push_back (_model->children ().size () - 1);
}
context->drag_status (context->get_suggested_action (), time);
Gdk::DragAction suggested_action = context->get_suggested_action ();
/* default to move, unless the user hold ctrl */
if (context->get_actions () & Gdk::ACTION_MOVE) {
suggested_action = Gdk::ACTION_MOVE;
}
context->drag_status (suggested_action, time);
_view.set_drag_dest_row (path, pos);
_view.drag_highlight ();
@ -386,7 +401,7 @@ EditorSections::drag_data_received (Glib::RefPtr<Gdk::DragContext> const& contex
SectionOperation op = CopyPasteSection;
timepos_t to (0);
if ((context->get_suggested_action () == Gdk::ACTION_MOVE)) {
if ((context->get_selected_action () == Gdk::ACTION_MOVE)) {
op = CutPasteSection;
}

View File

@ -2398,6 +2398,20 @@ Editor::move_selected_tracks (bool up)
sl.sort (Stripable::Sorter());
/* Check if the selected tracks are already at the beginning or end of
* the ordering, depending on direction.
*/
for (auto & s : sl) {
if (s->is_selected()) {
if (up && (s->presentation_info().order() <= 1)) {
return;
} else if (!up && (s->presentation_info().order() >= sl.size() - 1)) {
return;
}
}
}
std::list<ViewStripable> view_stripables;
/* build a list that includes time axis view information */

View File

@ -152,11 +152,13 @@ setup_gtk_ardour_enums ()
REGISTER_ENUM (StreamItem);
REGISTER_ENUM (PlayheadCursorItem);
REGISTER_ENUM (MarkerItem);
REGISTER_ENUM (SceneMarkerItem);
REGISTER_ENUM (MarkerBarItem);
REGISTER_ENUM (RangeMarkerBarItem);
REGISTER_ENUM (CdMarkerBarItem);
REGISTER_ENUM (SectionMarkerBarItem);
REGISTER_ENUM (CueMarkerBarItem);
REGISTER_ENUM (SceneMarkerBarItem);
REGISTER_ENUM (VideoBarItem);
REGISTER_ENUM (TransportMarkerBarItem);
REGISTER_ENUM (SelectionItem);

View File

@ -477,7 +477,7 @@ ExportDialog::show_progress ()
if (!status->aborted()) {
hide();
if (!ARDOUR::Profile->get_mixbus()) {
if (!ARDOUR::Profile->get_mixbus () && !ARDOUR::Profile->get_livetrax ()) {
NagScreen* ns = NagScreen::maybe_nag (_("export"));
if (ns) {
ns->nag ();

View File

@ -70,7 +70,7 @@ ExportFormatDialog::ExportFormatDialog (FormatPtr format, bool new_dialog)
, silence_end_checkbox (_("Add silence at end:"))
, silence_end_clock ("silence_end", true, "", true, false, true)
, command_label (_("Command to run post-export\n(%f=file path, %d=directory, %b=basename, see tooltip for more):"), Gtk::ALIGN_START)
, command_label (_("Command to run post-export\n(%f=file path, %d=directory, %b=basename; see tooltip for more,\ndon't add quotes around arguments):"), Gtk::ALIGN_START)
, format_table (3, 4)
, compatibility_label (_("Compatibility"), Gtk::ALIGN_START)

View File

@ -45,6 +45,7 @@
#include "gtkmm2ext/utils.h"
#include "gtkmm2ext/gtk_ui.h"
#include "widgets/slider_controller.h"
#include "widgets/tooltips.h"
#include "pbd/fastlog.h"
@ -315,6 +316,11 @@ GainMeterBase::set_gain_astate (AutoState as)
}
}
CairoWidget&
GainMeterBase::get_gain_slider() const {
return *gain_slider;
}
void
GainMeterBase::setup_gain_adjustment ()
{
@ -676,7 +682,7 @@ void
GainMeterBase::update_gain_sensitive ()
{
bool x = !(_control->alist()->automation_state() & Play);
static_cast<ArdourWidgets::SliderController*>(gain_slider)->set_sensitive (x);
gain_slider->set_sensitive (x);
}
gint

View File

@ -48,7 +48,6 @@
#include "widgets/ardour_button.h"
#include "widgets/focus_entry.h"
#include "widgets/slider_controller.h"
#include "enums.h"
#include "level_meter.h"
@ -70,6 +69,10 @@ namespace Gtk {
class Menu;
}
namespace ArdourWidgets {
class SliderController;
}
enum MeterPointChangeTarget {
MeterPointChangeAll,
MeterPointChangeGroup,
@ -106,7 +109,7 @@ public:
std::shared_ptr<PBD::Controllable> get_controllable();
LevelMeterHBox& get_level_meter() const { return *level_meter; }
ArdourWidgets::SliderController& get_gain_slider() const { return *gain_slider; }
CairoWidget& get_gain_slider() const;
/** Emitted in the GUI thread when a button is pressed over the level meter;
* return true if the event is handled.

View File

@ -1015,7 +1015,10 @@ GenericPluginUI::build_control_ui (const Evoral::Parameter& param,
}
if (!_pi || mcontrol->flags () & Controllable::NotAutomatable) {
if (!_pi) {
control_ui->automate_button.set_no_show_all ();
control_ui->automate_button.hide ();
} else if (mcontrol->flags () & Controllable::NotAutomatable) {
control_ui->automate_button.set_sensitive (false);
set_tooltip(control_ui->automate_button, _("This control cannot be automated"));
} else {

View File

@ -19,7 +19,9 @@
#include "pbd/convert.h"
#include "pbd/enumwriter.h"
#include "ardour/profile.h"
#include "ardour/plugin_manager.h"
#include "gtkmm2ext/gui_thread.h"
#include "instrument_selector.h"
@ -47,12 +49,20 @@ InstrumentSelector::drop_plugin_ptr()
{
unset_model ();
clear ();
_instrument_list->clear ();
if (_instrument_list) {
_instrument_list->clear ();
}
}
void
InstrumentSelector::refill()
{
/* XXX conditional can be removed once livetrax has its own simple add
tracks dialog.
*/
if (Profile->get_livetrax()) {
return;
}
TreeModel::iterator iter = get_active();
std::string selected;
if (iter) {

View File

@ -42,6 +42,7 @@
#include "mixer_ui.h"
#include "plugin_selector.h"
#include "plugin_ui.h"
#include "plugin_window_proxy.h"
#include "ui_config.h"
#include "pbd/i18n.h"
@ -299,7 +300,7 @@ IOPluginWindow::IOPlugUI::IOPlugUI (std::shared_ptr<ARDOUR::IOPlug> iop)
_window_proxy = dynamic_cast<PluginWindowProxy*> (iop->window_proxy ());
assert (_window_proxy);
} else {
_window_proxy = new PluginWindowProxy (string_compose ("IOP-%1", _iop->id ()), _iop);
_window_proxy = new PluginWindowProxy (string_compose ("IOP-%1", _iop->id ()), "I/O", _iop);
const XMLNode* ui_xml = _iop->session ().extra_xml (X_("UI"));
if (ui_xml) {
@ -373,113 +374,6 @@ IOPluginWindow::IOPlugUI::button_resized (Gtk::Allocation& alloc)
_btn_ioplug.set_layout_ellipsize_width (alloc.get_width () * PANGO_SCALE);
}
/* ****************************************************************************/
IOPluginWindow::PluginWindowProxy::PluginWindowProxy (std::string const& name, std::weak_ptr<PlugInsertBase> plugin)
: WM::ProxyBase (name, std::string ())
, _pib (plugin)
, _is_custom (true)
, _want_custom (true)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return;
}
p->DropReferences.connect (_going_away_connection, MISSING_INVALIDATOR, boost::bind (&IOPluginWindow::PluginWindowProxy::plugin_going_away, this), gui_context ());
}
IOPluginWindow::PluginWindowProxy::~PluginWindowProxy ()
{
_window = 0;
}
Gtk::Window*
IOPluginWindow::PluginWindowProxy::get (bool create)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return 0;
}
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (!_window) {
if (!create) {
return 0;
}
_is_custom = _want_custom;
_window = new PluginUIWindow (p, false, _is_custom);
if (_window) {
std::shared_ptr<ARDOUR::IOPlug> iop = std::dynamic_pointer_cast<ARDOUR::IOPlug> (p);
assert (iop);
_window->set_title (iop->name ());
setup ();
_window->show_all ();
}
}
return _window;
}
void
IOPluginWindow::PluginWindowProxy::show_the_right_window ()
{
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (_window) {
_window->unset_transient_for ();
}
toggle ();
}
int
IOPluginWindow::PluginWindowProxy::set_state (const XMLNode& node, int)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end ()) {
std::string name;
if ((*i)->name () == X_("Window") && (*i)->get_property (X_("name"), name) && name == _name) {
break;
}
++i;
}
if (i != children.end ()) {
(*i)->get_property (X_("custom-ui"), _want_custom);
}
return ProxyBase::set_state (node, 0);
}
XMLNode&
IOPluginWindow::PluginWindowProxy::get_state () const
{
XMLNode* node;
node = &ProxyBase::get_state ();
node->set_property (X_("custom-ui"), _is_custom);
return *node;
}
void
IOPluginWindow::PluginWindowProxy::plugin_going_away ()
{
delete _window;
_window = 0;
WM::Manager::instance ().remove (this);
_going_away_connection.disconnect ();
delete this;
}
/* ****************************************************************************/
IOPluginWindow::IOButton::IOButton (std::shared_ptr<ARDOUR::IO> io, bool pre)
: _io (io)
, _pre (pre)

View File

@ -35,11 +35,11 @@ namespace ARDOUR
{
class IO;
class IOPlug;
class PlugInsertBase;
class Port;
}
class IOSelectorWindow;
class PluginWindowProxy;
class IOPluginWindow : public ArdourWindow
{
@ -48,39 +48,6 @@ public:
void set_session (ARDOUR::Session*);
class PluginWindowProxy : public WM::ProxyBase
{
public:
PluginWindowProxy (std::string const&, std::weak_ptr<ARDOUR::PlugInsertBase>);
~PluginWindowProxy ();
Gtk::Window* get (bool create = false);
void show_the_right_window ();
ARDOUR::SessionHandlePtr* session_handle ()
{
return 0;
}
void set_custom_ui_mode (bool use_custom)
{
_want_custom = use_custom;
}
int set_state (const XMLNode&, int);
XMLNode& get_state () const;
private:
void plugin_going_away ();
std::weak_ptr<ARDOUR::PlugInsertBase> _pib;
bool _is_custom;
bool _want_custom;
PBD::ScopedConnection _going_away_connection;
};
protected:
void on_show ();
void on_hide ();
@ -147,7 +114,7 @@ private:
IOButton _btn_output;
ArdourWidgets::ArdourButton _btn_ioplug;
PluginWindowProxy* _window_proxy;
std::shared_ptr<ARDOUR::IOPlug> _iop;
std::shared_ptr<ARDOUR::IOPlug> _iop;
PBD::ScopedConnection _going_away_connection;
};

View File

@ -37,8 +37,6 @@
#include "ardour/session_handle.h"
#include "widgets/fastmeter.h"
#include "widgets/focus_entry.h"
#include "widgets/slider_controller.h"
#include "enums.h"

View File

@ -42,6 +42,7 @@
#include "ardour_http.h"
#include "ardour_ui.h"
#include "audio_region_view.h"
#include "public_editor.h"
#include "region_selection.h"
#include "luadialog.h"
@ -826,6 +827,14 @@ LuaInstance::register_classes (lua_State* L, bool sandbox)
.endClass ()
.deriveClass <RegionView, TimeAxisViewItem> ("RegionView")
.addCast<AudioRegionView> ("to_audioregionview")
.addFunction ("show_region_editor", &RegionView::show_region_editor)
.addFunction ("hide_region_editor", &RegionView::hide_region_editor)
.endClass ()
.deriveClass <AudioRegionView, RegionView> ("RegionView")
.addFunction ("set_region_gain_line", &AudioRegionView::set_region_gain_line)
.addFunction ("set_region_fx_line", (bool (AudioRegionView::*)(uint32_t, uint32_t))&AudioRegionView::set_region_fx_line)
.endClass ()
.deriveClass <RouteUI, Selectable> ("RouteUI")

View File

@ -103,6 +103,8 @@ MergeableLine::merge_drawn_line (Editor& e, Session& s, Evoral::ControlList::Ord
e.begin_reversible_command (_("draw automation"));
s.add_command (new MementoCommand<ARDOUR::AutomationList> (*list.get (), &before, &after));
_line->end_draw_merge ();
_line->get_selectables (earliest, latest, 0.0, 1.0, results);
e.get_selection ().set (results);

View File

@ -2548,13 +2548,13 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
/* Add control points to selection. */
const ATracks& atracks = midi_view()->automation_tracks();
Selectables selectables;
editor.get_selection().clear_points();
timepos_t st (start);
timepos_t et (end);
for (ATracks::const_iterator a = atracks.begin(); a != atracks.end(); ++a) {
Selectables selectables;
a->second->get_selectables (st, et, gy0, gy1, selectables);
for (Selectables::const_iterator s = selectables.begin(); s != selectables.end(); ++s) {
ControlPoint* cp = dynamic_cast<ControlPoint*>(*s);
@ -4751,8 +4751,6 @@ MidiRegionView::note_to_y(uint8_t note) const
void
MidiRegionView::quantize_selected_notes ()
{
std::cerr << "QSN!\n";
RegionSelection rs;
rs.push_back (this);

View File

@ -338,9 +338,9 @@ MidiTracer::tracer (Parser&, MIDI::byte* msg, size_t len, samplecnt_t now)
case polypress:
if (show_hex) {
s += snprintf (&buf[s], bufsize, "%16s chn %2d %02x\n", "PolyPressure", (msg[0]&0xf)+1, (int) msg[1]);
s += snprintf (&buf[s], bufsize, "%16s chn %2d %02x %02x\n", "PolyPressure", (msg[0]&0xf)+1, (int) msg[1], msg[2]);
} else {
s += snprintf (&buf[s], bufsize, "%16s chn %2d %-3d\n", "PolyPressure", (msg[0]&0xf)+1, (int) msg[1]);
s += snprintf (&buf[s], bufsize, "%16s chn %2d %-3d %-3d\n", "PolyPressure", (msg[0]&0xf)+1, (int) msg[1], msg[2]);
}
break;
@ -362,9 +362,9 @@ MidiTracer::tracer (Parser&, MIDI::byte* msg, size_t len, samplecnt_t now)
case chanpress:
if (show_hex) {
s += snprintf (&buf[s], bufsize, "%16s chn %2d %02x/%-3d\n", "Channel Pressure", (msg[0]&0xf)+1, (int) msg[1], (int) msg[1]);
s += snprintf (&buf[s], bufsize, "%16s chn %2d %02x\n", "Channel Pressure", (msg[0]&0xf)+1, (int) msg[1]);
} else {
s += snprintf (&buf[s], bufsize, "%16s chn %2d %02x/%-3d\n", "Channel Pressure", (msg[0]&0xf)+1, (int) msg[1], (int) msg[1]);
s += snprintf (&buf[s], bufsize, "%16s chn %2d %-3d\n", "Channel Pressure", (msg[0]&0xf)+1, (int) msg[1]);
}
break;

View File

@ -378,6 +378,7 @@ MixerStrip::init ()
number_label.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::number_button_button_press), false);
name_button.set_fallthrough_to_parent (true);
name_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::name_button_button_press), false);
group_button.signal_button_press_event().connect (sigc::mem_fun(*this, &MixerStrip::select_route_group), false);
@ -1208,7 +1209,21 @@ MixerStrip::build_route_ops_menu ()
gboolean
MixerStrip::name_button_button_press (GdkEventButton* ev)
{
if (ev->button == 1 || ev->button == 3) {
if (ev->button == 1 && ev->type == GDK_BUTTON_PRESS) {
/* fall thru to mixer */
return false;
}
if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
route_rename ();
return true;
}
if (ev->button == 3 && ARDOUR::Profile->get_livetrax() && _route && _route->is_singleton ()) {
return true;
}
if (ev->button == 3) {
list_route_operations ();
if (ev->button == 1) {

View File

@ -112,6 +112,13 @@ using namespace std;
using PBD::atoi;
using PBD::Unwinder;
static const gchar *_plugin_list_mode_strings[] = {
N_("Favorite Plugins"),
N_("Recent Plugins"),
N_("Top-10 Plugins"),
0
};
Mixer_UI* Mixer_UI::_instance = 0;
Mixer_UI*
@ -126,7 +133,7 @@ Mixer_UI::instance ()
Mixer_UI::Mixer_UI ()
: Tabbable (_content, _("Mixer"), X_("mixer"))
, plugin_search_clear_button (Stock::CLEAR)
, plugin_search_clear_button (X_("Clear"))
, _mixer_scene_release (0)
, no_track_list_redisplay (false)
, in_group_row_change (false)
@ -146,6 +153,9 @@ Mixer_UI::Mixer_UI ()
, _strip_selection_change_without_scroll (false)
, _selection (*this, *this)
{
plugin_list_mode_strings = I18N (_plugin_list_mode_strings);
load_bindings ();
register_actions ();
Glib::RefPtr<ToggleAction> fb_act = ActionManager::get_toggle_action ("Mixer", "ToggleFoldbackStrip");
@ -268,14 +278,14 @@ Mixer_UI::Mixer_UI ()
favorite_plugins_model->signal_row_has_child_toggled().connect (sigc::mem_fun (*this, &Mixer_UI::sync_treeview_favorite_ui_state));
favorite_plugins_model->signal_row_deleted().connect (sigc::mem_fun (*this, &Mixer_UI::favorite_plugins_deleted));
favorite_plugins_mode_combo.append (_("Favorite Plugins"));
favorite_plugins_mode_combo.append (_("Recent Plugins"));
favorite_plugins_mode_combo.append (_("Top-10 Plugins"));
favorite_plugins_mode_combo.set_active_text (_("Favorite Plugins"));
favorite_plugins_mode_combo.signal_changed().connect (sigc::mem_fun (*this, &Mixer_UI::plugin_list_mode_changed));
favorite_plugins_mode_combo.AddMenuElem (Menu_Helpers::MenuElem (_("Favorite Plugins"), sigc::bind(sigc::mem_fun(*this, &Mixer_UI::set_plugin_list_mode), PLM_Favorite)));
favorite_plugins_mode_combo.AddMenuElem (Menu_Helpers::MenuElem (_("Recent Plugins"), sigc::bind(sigc::mem_fun(*this, &Mixer_UI::set_plugin_list_mode), PLM_Recent)));
favorite_plugins_mode_combo.AddMenuElem (Menu_Helpers::MenuElem (_("Top-10 Plugins"), sigc::bind(sigc::mem_fun(*this, &Mixer_UI::set_plugin_list_mode), PLM_TopHits)));
favorite_plugins_mode_combo.set_size_request(-1, 24);
set_plugin_list_mode(PLM_Favorite);
plugin_search_entry.signal_changed().connect (sigc::mem_fun (*this, &Mixer_UI::plugin_search_entry_changed));
plugin_search_clear_button.signal_clicked().connect (sigc::mem_fun (*this, &Mixer_UI::plugin_search_clear_button_clicked));
plugin_search_clear_button.signal_clicked.connect (sigc::mem_fun (*this, &Mixer_UI::plugin_search_clear_button_clicked));
favorite_plugins_scroller.add (favorite_plugins_display);
favorite_plugins_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
@ -2895,8 +2905,12 @@ Mixer_UI::parameter_changed (string const & p)
bool const s = _session ? _session->config.get_show_group_tabs () : true;
if (s) {
_group_tabs->show ();
vca_label_bar.show ();
Gtk::Requisition group_size = _group_tabs->size_request();
vca_label_bar.set_size_request (-1, group_size.height + 1);
} else {
_group_tabs->hide ();
vca_label_bar.hide ();
}
} else if (p == "default-narrow_ms") {
bool const s = UIConfiguration::instance().get_default_narrow_ms ();
@ -3124,22 +3138,10 @@ Mixer_UI::monitor_section_detached ()
act->set_sensitive (false);
}
Mixer_UI::PluginListMode
Mixer_UI::plugin_list_mode () const
{
if (favorite_plugins_mode_combo.get_active_text() == _("Top-10 Plugins")) {
return PLM_TopHits;
} else if (favorite_plugins_mode_combo.get_active_text() == _("Recent Plugins")) {
return PLM_Recent;
} else {
return PLM_Favorite;
}
}
void
Mixer_UI::store_current_favorite_order ()
{
if (plugin_list_mode () != PLM_Favorite || !plugin_search_entry.get_text ().empty()) {
if (plugin_list_mode != PLM_Favorite || !plugin_search_entry.get_text ().empty()) {
return;
}
@ -3165,9 +3167,16 @@ Mixer_UI::save_favorite_ui_state (const TreeModel::iterator& iter, const TreeMod
}
void
Mixer_UI::plugin_list_mode_changed ()
Mixer_UI::set_plugin_list_mode (PluginListMode plm)
{
if (plugin_list_mode () == PLM_Favorite) {
plugin_list_mode = plm;
string str = plugin_list_mode_strings[(int)plm];
if (str != favorite_plugins_mode_combo.get_text ()) {
favorite_plugins_mode_combo.set_text (str);
}
if (plugin_list_mode == PLM_Favorite) {
PBD::Unwinder<bool> uw (ignore_plugin_refill, true);
favorite_plugins_search_hbox.show ();
plugin_search_entry.set_text ("");
@ -3180,7 +3189,7 @@ Mixer_UI::plugin_list_mode_changed ()
void
Mixer_UI::plugin_search_entry_changed ()
{
if (plugin_list_mode () == PLM_Favorite) {
if (plugin_list_mode == PLM_Favorite) {
refill_favorite_plugins ();
}
}
@ -3195,7 +3204,7 @@ void
Mixer_UI::refiller (PluginInfoList& result, const PluginInfoList& plugs)
{
PluginManager& manager (PluginManager::instance());
PluginListMode plm = plugin_list_mode ();
PluginListMode plm = plugin_list_mode;
std::string searchstr = plugin_search_entry.get_text ();
setup_search_string (searchstr);
@ -3266,7 +3275,7 @@ Mixer_UI::refill_favorite_plugins ()
refiller (plugs, mgr.lv2_plugin_info ());
refiller (plugs, mgr.lua_plugin_info ());
switch (plugin_list_mode ()) {
switch (plugin_list_mode) {
default:
/* use favorites as-is */
break;
@ -3297,12 +3306,12 @@ Mixer_UI::maybe_refill_favorite_plugins (PluginListMode plm)
{
switch (plm) {
case PLM_Favorite:
if (plugin_list_mode () == PLM_Favorite) {
if (plugin_list_mode == PLM_Favorite) {
refill_favorite_plugins();
}
break;
default:
if (plugin_list_mode () != PLM_Favorite) {
if (plugin_list_mode != PLM_Favorite) {
refill_favorite_plugins();
}
break;
@ -3332,7 +3341,7 @@ void
Mixer_UI::sync_treeview_from_favorite_order ()
{
PBD::Unwinder<bool> uw (ignore_plugin_reorder, true);
switch (plugin_list_mode ()) {
switch (plugin_list_mode) {
case PLM_Favorite:
{
PluginUIOrderSorter cmp (favorite_ui_order);
@ -3596,14 +3605,14 @@ Mixer_UI::plugin_drag_motion (const Glib::RefPtr<Gdk::DragContext>& ctx, int x,
}
if (target == "GTK_TREE_MODEL_ROW") {
if (plugin_list_mode () == PLM_Favorite && plugin_search_entry.get_text ().empty()) {
if (plugin_list_mode == PLM_Favorite && plugin_search_entry.get_text ().empty()) {
/* re-order rows */
ctx->drag_status (Gdk::ACTION_MOVE, time);
return true;
}
} else if (target == "x-ardour/plugin.preset") {
ctx->drag_status (Gdk::ACTION_COPY, time);
//favorite_plugins_mode_combo.set_active_text (_("Favorite Plugins"));
//favorite_plugins_mode_combo.set_text (_("Favorite Plugins"));
return true;
}

View File

@ -54,6 +54,7 @@
#include "widgets/pane.h"
#include "widgets/tabbable.h"
#include "widgets/ardour_dropdown.h"
#include "axis_provider.h"
#include "enums.h"
@ -194,9 +195,9 @@ private:
Gtk::Frame favorite_plugins_frame;
Gtk::VBox favorite_plugins_vbox;
Gtk::HBox favorite_plugins_search_hbox;
Gtk::ComboBoxText favorite_plugins_mode_combo;
ArdourWidgets::ArdourDropdown favorite_plugins_mode_combo;
Gtk::Entry plugin_search_entry;
Gtk::Button plugin_search_clear_button;
ArdourWidgets::ArdourButton plugin_search_clear_button;
ArdourWidgets::VPane rhs_pane1;
ArdourWidgets::VPane rhs_pane2;
ArdourWidgets::HPane inner_pane;
@ -443,13 +444,15 @@ private:
PLM_Recent,
PLM_TopHits
};
enum PluginListMode plugin_list_mode;
void set_plugin_list_mode (PluginListMode plm);
std::vector<std::string> plugin_list_mode_strings;
void refiller (ARDOUR::PluginInfoList& result, const ARDOUR::PluginInfoList& plugs);
void refill_favorite_plugins ();
void maybe_refill_favorite_plugins (PluginListMode);
void store_current_favorite_order();
enum PluginListMode plugin_list_mode () const;
void plugin_list_mode_changed ();
void plugin_search_entry_changed ();
void plugin_search_clear_button_clicked ();
void favorite_plugins_deleted (const Gtk::TreeModel::Path&);

View File

@ -293,6 +293,14 @@ NoteBase::event_handler (GdkEvent* ev)
return false;
}
if (_region.get_time_axis_view ().layer_display () == Stacked) {
/* only allow edting notes in the topmost layer */
if (_region.region()->layer() != _region.region()->playlist()->top_layer ()) {
/* this stll allows the draw tool to work, and edit cursor is updated */
return false;
}
}
switch (ev->type) {
case GDK_ENTER_NOTIFY:
_region.note_entered (this);

View File

@ -45,6 +45,7 @@
#include "pbd/strsplit.h"
#include "widgets/frame.h"
#include "widgets/slider_controller.h"
#include "gui_thread.h"
#include "option_editor.h"
@ -678,6 +679,11 @@ FaderOption::add_to_page (OptionEditorPage* p)
add_widgets_to_page (p, _label, &_box);
}
Gtk::Widget&
FaderOption::tip_widget() {
return *_db_slider;
}
/*--------------------------*/
ClockOption::ClockOption (string const & i, string const & n, sigc::slot<std::string> g, sigc::slot<bool, std::string> s)
@ -1107,20 +1113,20 @@ OptionEditor::add_path_to_treeview (std::string const & pn, Gtk::Widget& widget)
}
/** Add a component to a given page.
* @param pn Page name (will be created if it doesn't already exist)
* @param page_name Page name (will be created if it doesn't already exist)
* @param o Component.
*/
void
OptionEditor::add_option (std::string const & pn, OptionEditorComponent* o)
OptionEditor::add_option (std::string const & page_name, OptionEditorComponent* o)
{
if (_pages.find (pn) == _pages.end()) {
OptionEditorPage* oep = new OptionEditorPage (_notebook, pn);
_pages[pn] = oep;
if (_pages.find (page_name) == _pages.end()) {
OptionEditorPage* oep = new OptionEditorPage (_notebook, page_name);
_pages[page_name] = oep;
add_path_to_treeview (pn, oep->box);
add_path_to_treeview (page_name, oep->box);
}
OptionEditorPage* p = _pages[pn];
OptionEditorPage* p = _pages[page_name];
p->components.push_back (o);
o->add_to_page (p);

View File

@ -39,8 +39,6 @@
#include "pbd/configuration.h"
#include "widgets/slider_controller.h"
#include "actions.h"
#include "ardour_window.h"
#include "audio_clock.h"
@ -64,6 +62,7 @@
namespace ArdourWidgets {
class Frame;
class HSliderController;
}
class OptionEditorPage;
@ -601,7 +600,7 @@ public:
void set_state_from_config ();
void add_to_page (OptionEditorPage *);
Gtk::Widget& tip_widget() { return *_db_slider; }
Gtk::Widget& tip_widget();
private:
void db_changed ();

View File

@ -1710,6 +1710,17 @@ PluginPinWidget::add_remove_port_clicked (bool add, ARDOUR::DataType dt)
ChanCount ins, outs, src;
_pi->configured_io (ins, outs);
src = _pi->natural_output_streams ();
if (src.get (dt) == 0) {
if (!add || ins.get (dt) < out.get (dt)) {
return;
}
int pn = out.get (dt);
assert (pn > 0);
ChanMapping map (_pi->thru_map ());
map.set (dt, pn - 1, pn - 1);
_pi->set_thru_map (map);
return;
}
for (uint32_t i = n_before; i < outs.get (dt); ++i) {
uint32_t pc = i / src.get (dt);
uint32_t pn = i % src.get (dt);

View File

@ -200,9 +200,6 @@ PluginUIWindow::PluginUIWindow (std::shared_ptr<PlugInsertBase> pib,
PluginUIWindow::~PluginUIWindow ()
{
#ifndef NDEBUG
cerr << "PluginWindow deleted for " << this << endl;
#endif
delete _pluginui;
if (the_plugin_window == this) {

View File

@ -0,0 +1,154 @@
/*
* Copyright (C) 2022 Robin Gareus <robin@gareus.org>
*
* 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 "ardour/plug_insert_base.h"
#include "ardour/plugin_manager.h"
#include "gui_thread.h"
#include "plugin_ui.h"
#include "plugin_window_proxy.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace Gtk;
using namespace Gtkmm2ext;
PluginWindowProxy::PluginWindowProxy (std::string const& name, std::string const& title, std::weak_ptr<PlugInsertBase> plugin)
: WM::ProxyBase (name, std::string ())
, _pib (plugin)
, _title (title)
, _is_custom (true)
, _want_custom (true)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return;
}
p->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&PluginWindowProxy::plugin_going_away, this), gui_context ());
}
PluginWindowProxy::~PluginWindowProxy ()
{
_window = 0;
}
Gtk::Window*
PluginWindowProxy::get (bool create)
{
std::shared_ptr<PlugInsertBase> p = _pib.lock ();
if (!p) {
return 0;
}
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (!_window) {
if (!create) {
return 0;
}
_is_custom = _want_custom;
_window = new PluginUIWindow (p, false, _is_custom);
if (_window) {
_window->set_title (generate_processor_title (p));
setup ();
_window->show_all ();
}
}
return _window;
}
void
PluginWindowProxy::show_the_right_window ()
{
if (_window && (_is_custom != _want_custom)) {
set_state_mask (WindowProxy::StateMask (state_mask () & ~WindowProxy::Size));
drop_window ();
}
if (_window) {
_window->unset_transient_for ();
}
toggle ();
}
int
PluginWindowProxy::set_state (const XMLNode& node, int)
{
XMLNodeList children = node.children ();
XMLNodeList::const_iterator i = children.begin ();
while (i != children.end ()) {
std::string name;
if ((*i)->name () == X_("Window") && (*i)->get_property (X_("name"), name) && name == _name) {
break;
}
++i;
}
if (i != children.end ()) {
(*i)->get_property (X_("custom-ui"), _want_custom);
}
return ProxyBase::set_state (node, 0);
}
XMLNode&
PluginWindowProxy::get_state () const
{
XMLNode* node;
node = &ProxyBase::get_state ();
node->set_property (X_("custom-ui"), _is_custom);
return *node;
}
void
PluginWindowProxy::plugin_going_away ()
{
delete _window;
_window = 0;
WM::Manager::instance ().remove (this);
drop_connections ();
delete this;
}
std::string
PluginWindowProxy::generate_processor_title (std::shared_ptr<PlugInsertBase> p)
{
std::string maker = p->plugin()->maker() ? p->plugin()->maker() : "";
std::string::size_type email_pos;
if ((email_pos = maker.find_first_of ('<')) != std::string::npos) {
maker = maker.substr (0, email_pos - 1);
}
if (maker.length() > 32) {
maker = maker.substr (0, 32);
maker += " ...";
}
std::string type = PluginManager::plugin_type_name (p->type ());
auto so = std::dynamic_pointer_cast<SessionObject> (p);
assert (so);
return string_compose(_("%1: %2 (by %3) [%4]"), _title, so->name(), maker, type);
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2022,2024 Robin Gareus <robin@gareus.org>
*
* 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 _gtkardour_plugin_window_proxy_h_
#define _gtkardour_plugin_window_proxy_h_
#include "ardour_window.h"
#include "window_manager.h"
#include "pbd/signals.h"
namespace Gtk
{
class Window;
}
namespace ARDOUR
{
class PlugInsertBase;
}
class PluginWindowProxy : public WM::ProxyBase, public PBD::ScopedConnectionList
{
public:
PluginWindowProxy (std::string const&, std::string const&, std::weak_ptr<ARDOUR::PlugInsertBase>);
~PluginWindowProxy ();
Gtk::Window* get (bool create = false);
void show_the_right_window ();
ARDOUR::SessionHandlePtr* session_handle ()
{
return 0;
}
void set_custom_ui_mode (bool use_custom)
{
_want_custom = use_custom;
}
int set_state (const XMLNode&, int);
XMLNode& get_state () const;
std::string generate_processor_title (std::shared_ptr<ARDOUR::PlugInsertBase>);
private:
void plugin_going_away ();
std::weak_ptr<ARDOUR::PlugInsertBase> _pib;
std::string _title;
bool _is_custom;
bool _want_custom;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -5774,7 +5774,7 @@ msgstr "Assistant de sonie"
#: editor_actions.cc:443 rc_option_editor.cc:3347
msgid "Split/Separate"
msgstr "Découper/Séparer"
msgstr "Découper/séparer"
#: editor_actions.cc:448
msgid "Fade Range Selection"
@ -6963,7 +6963,7 @@ msgid ""
"Master bus output gain control is disabled.\n"
"Visit preferences to enable it?"
msgstr ""
"Le contrôle de gain de sortie du bus maître est désactivé.\n"
"Le contrôle de gain de sortie du bus général est désactivé.\n"
"Visiter les préférences pour l'activer ?"
#: editor_export_audio.cc:167
@ -6980,14 +6980,14 @@ msgstr "L'analyse de la sonie nécessite une intervalle-de-session."
msgid "Loudness Analysis is only available for sessions with a master-bus"
msgstr ""
"L'analyse de la sonie n'est disponible que pour les sessions avec un bus-"
"maître"
"général"
#: editor_export_audio.cc:180
msgid ""
"Loudness Analysis is only available for sessions with a stereo master-bus"
msgstr ""
"L'analyse de la sonie n'est disponible que pour les sessions avec un bus-"
"maître stéréo"
"général stéréo"
#: editor_export_audio.cc:222
msgid "Confirm MIDI File Overwrite"
@ -9859,7 +9859,7 @@ msgstr "Créer un nouveau groupe à partir de..."
#: group_tabs.cc:347
msgid "Create New Group with Master From..."
msgstr "Créer un nouveau groupe avec un Master à partir de..."
msgstr "Créer un nouveau groupe avec un général à partir de..."
#: group_tabs.cc:374 route_group_menu.cc:88
msgid "Edit Group..."
@ -10388,13 +10388,13 @@ msgid ""
msgstr ""
"<b>Si coché</b> un processeur d'amplification est utilisé pour appliquer le "
"gain. Cela permet un positionnement personnalisé de l'étage de gain dans le "
"flux de signaux du bus maître, éventuellement suivi d'un limiteur pour se "
"flux de signaux du bus général, éventuellement suivi d'un limiteur pour se "
"conformer aux exigences en matière d'intensité sonore et de crête. En "
"fonction des réglages du limiteur ou du DSP après l'étage de gain, des "
"mesures répétées de l'intensité sonore peuvent produire des résultats "
"différents.\n"
"<b>Si décoché</b>, le gain est appliqué directement à la sortie du bus "
"maître. Cela permet un réglage efficace et fiable du volume."
"général. Cela permet un réglage efficace et fiable du volume."
#: loudness_dialog.cc:286
msgid "<b>Loudness Analysis</b>\n"
@ -10408,7 +10408,7 @@ msgid ""
"profile."
msgstr ""
"Cela permet à l'utilisateur d'analyser et de conformer la sonie du signal à "
"la sortie du bus maître de la session complète, comme s'il était exporté. "
"la sortie du bus général de la session complète, comme s'il était exporté. "
"Lorsque vous utilisez cette fonctionnalité, n'oubliez pas de désactiver la "
"normalisation dans le profil d'exportation de la session."
@ -11606,11 +11606,11 @@ msgstr "Sonie"
#: mixer_strip.cc:648
msgid "Master output volume"
msgstr "Volume de sortie maître"
msgstr "Volume de la sortie générale"
#: mixer_strip.cc:649
msgid "Measure loudness of the session, normalize master output volume"
msgstr "Mesure la sonie de la session, normalise le volume de sortie maître"
msgstr "Mesure la sonie de la session, normalise le volume de la sortie général"
#: mixer_strip.cc:684
msgid "Enable/Disable MIDI input"
@ -12068,13 +12068,12 @@ msgid "(Right-Click to Store)"
msgstr "(Clic-droit pour stocker)"
#: mixer_ui.cc:4415
#, fuzzy
msgid ""
"Disabling surround master will delete all existing surround panner state.\n"
"This cannot be undonoe. Proceed anyway?"
msgstr ""
"La désactivation de l'option \"surround master\" supprimera tous les états "
"existants de l'option \"surround panner\".\n"
"de panneau de surround existants.\n"
"Il n'est pas possible de revenir en arrière. Poursuivre quand même ?"
#: meter_strip.cc:171
@ -12476,7 +12475,7 @@ msgstr ""
"\n"
"Vous pouvez utiliser %1 pour enregistrer un orchestre, créer avec des "
"boucles audios/MIDI, éditer la prise vocale parfaite, mixer un évènement en "
"direct avec des effets , doubler une vidéo et masteriser vos morceaux pour "
"direct avec des effets, doubler une vidéo et masteriser vos pistes pour "
"une diffusion numérique. \n"
"\n"
"Quelques éléments doivent être configurés avant de commencer à utiliser le "
@ -14478,7 +14477,7 @@ msgstr "RàZ vers les recommandations par défaut"
#: rc_option_editor.cc:1110
msgid "GUI and Font scaling"
msgstr "Ajustement d'Interface et Police"
msgstr "Ajustement d'interface et de police "
#: rc_option_editor.cc:1134
msgid ""
@ -14523,12 +14522,14 @@ msgid "Waveform Clip Level (dBFS)"
msgstr "Niveau d'écrêtage de la forme d'onde (dBFS) "
#: rc_option_editor.cc:1206
# extraspace needed to get a space before the semicolon
msgid "Playback (seconds of buffering)"
msgstr "Lecture (secondes en mémoire)"
msgstr "Lecture (secondes en mémoire) "
#: rc_option_editor.cc:1210
# extraspace needed to get a space before the semicolon
msgid "Recording (seconds of buffering)"
msgstr "Enregistrement (secondes en mémoire)"
msgstr "Enregistrement (secondes en mémoire) "
#: rc_option_editor.cc:1219
msgid "Small sessions (4-16 tracks)"
@ -14818,8 +14819,9 @@ msgid "GUI Lock"
msgstr "Verrouillage de l'interface"
#: rc_option_editor.cc:2492
# extraspace needed to get a space before the semicolon
msgid "Lock timeout (seconds)"
msgstr "Délai de temporisation du verrouillage (secondes)"
msgstr "Délai de temporisation du verrouillage (secondes) "
#: rc_option_editor.cc:2500
msgid "Lock GUI after this many idle seconds (zero to never lock)"
@ -14828,8 +14830,9 @@ msgstr ""
"(zéro pour ne jamais verrouiller)"
#: rc_option_editor.cc:2505
# extraspace needed to get a space before the semicolon
msgid "System Screensaver Mode"
msgstr "Fonctionnement de l'écran de veille du système"
msgstr "Fonctionnement de l'écran de veille du système "
#: rc_option_editor.cc:2510
msgid "Never Inhibit"
@ -14864,8 +14867,9 @@ msgid "LED meter style"
msgstr "Style d'afficheur LED"
#: rc_option_editor.cc:2553
# extraspace needed to get a space before the semicolon
msgid "Icon Set"
msgstr "Jeu d'icônes"
msgstr "Jeu d'icônes "
#: rc_option_editor.cc:2564
msgid "Graphical User Interface"
@ -14961,16 +14965,19 @@ msgid "Show Selection Marker"
msgstr "Afficher les repères de sélection"
#: rc_option_editor.cc:2675
# extraspace needed to get a space before the semicolon
msgid "Waveforms color gradient depth"
msgstr "Profondeur de dégradé des couleurs de formes d'onde"
msgstr "Profondeur de dégradé des couleurs de formes d'onde "
#: rc_option_editor.cc:2686
# extraspace needed to get a space before the semicolon
msgid "Timeline item gradient depth"
msgstr "Profondeur de dégradé des éléments de la ligne de temps"
msgstr "Profondeur de dégradé des éléments de la ligne de temps "
#: rc_option_editor.cc:2696
# extraspace needed to get a space before the semicolon
msgid "Track name ellipsize mode"
msgstr "Mode elliptique du nom de la piste"
msgstr "Mode elliptique du nom de la piste "
#: rc_option_editor.cc:2700
msgid "Ellipsize start of name"
@ -14993,8 +15000,9 @@ msgstr ""
"têtes des pistes de l'éditeur"
#: rc_option_editor.cc:2709
# extraspace needed to get a space before the semicolon
msgid "Add a visual gap below Audio Regions"
msgstr "Ajouter un espace visuel sous les régions audio"
msgstr "Ajouter un espace visuel sous les régions audio "
#: rc_option_editor.cc:2718
msgid "Editor Meters"
@ -15030,8 +15038,9 @@ msgid "Use colors to show note velocity"
msgstr "Utiliser des couleurs pour afficher la vélocité des notes"
#: rc_option_editor.cc:2773
# extraspace needed to get a space before the semicolon
msgid "Display note names in MIDI track headers"
msgstr "Affichage des noms de notes dans les en-têtes de pistes MIDI"
msgstr "Affichage des noms de notes dans les en-têtes de pistes MIDI "
#: rc_option_editor.cc:2777
msgid "Always"
@ -15112,8 +15121,9 @@ msgstr ""
"Utiliser par défaut des tranches de console étroites pour les nouvelles voies"
#: rc_option_editor.cc:2878
# extraspace needed to get a space before the semicolon
msgid "Limit inline-mixer-strip controls per plugin"
msgstr "Limiter les contrôles en-ligne dans le mixeur par greffon"
msgstr "Limiter les contrôles en-ligne dans le mixeur par greffon "
#: rc_option_editor.cc:2882 rc_option_editor.cc:4940
msgid "Unlimited"
@ -15168,7 +15178,7 @@ msgstr "Afficher la section info du moniteur"
#: rc_option_editor.cc:2938
msgid "Display Cue Rec/Play Controls"
msgstr "Afficher enr. Cue/Controle lecture"
msgstr "Afficher enr. Cue/Contrôles de lecture"
#: rc_option_editor.cc:2946
msgid "Display Navigation Timeline"
@ -15176,7 +15186,7 @@ msgstr "Afficher la navigation chronologique"
#: rc_option_editor.cc:2954
msgid "Display Master Level Meter"
msgstr "Afficher l'indicateur du niveau Master"
msgstr "Afficher l'indicateur du niveau général"
#: rc_option_editor.cc:2961
msgid "Display Action-Buttons"
@ -15188,7 +15198,7 @@ msgstr "Apparence/Taille et échelle"
#: rc_option_editor.cc:2971
msgid "User Interface Size and Scale"
msgstr "Taille et echelle de l'interface utilisateur"
msgstr "Taille et échelle de l'interface utilisateur"
#: rc_option_editor.cc:2979 rc_option_editor.cc:2980 rc_option_editor.cc:2981
#: rc_option_editor.cc:2993 rc_option_editor.cc:3005 rc_option_editor.cc:3018
@ -15444,8 +15454,9 @@ msgid "Show cue markers in regions"
msgstr "Afficherer les repères cue dans les régions"
#: rc_option_editor.cc:3184
# extraspace needed to get a space before the semicolon
msgid "Show gain envelopes in audio regions"
msgstr "Afficher les enveloppes de gain dans les régions audio"
msgstr "Afficher les enveloppes de gain dans les régions audio "
#: rc_option_editor.cc:3185
msgid "in all modes"
@ -15482,9 +15493,10 @@ msgstr ""
"bords"
#: rc_option_editor.cc:3243
# extraspace needed to get a space before the semicolon
msgid "Auto-scroll speed when dragging playhead"
msgstr ""
"Vitesse de défilement automatique lors du glissement de la tête de lecture"
"Vitesse de défilement automatique lors du glissement de la tête de lecture "
#: rc_option_editor.cc:3247
msgid "5%"
@ -15503,9 +15515,10 @@ msgid "50%"
msgstr "50%"
#: rc_option_editor.cc:3257
# extraspace needed to get a space before the semicolon
msgid "Limit zoom & summary view beyond session extents to"
msgstr ""
"Limiter le zoom et l'affichage du résumé au-delà des limites de la session"
"Limiter le zoom et l'affichage du résumé au-delà des limites de la session "
#: rc_option_editor.cc:3261
msgid "1 minute"
@ -15573,12 +15586,14 @@ msgstr ""
"au toucher\" est utilisée."
#: rc_option_editor.cc:3304
# extraspace needed to get a space before the semicolon
msgid "Default fade shape"
msgstr "Forme du fondu par défaut"
msgstr "Forme du fondu par défaut "
#: rc_option_editor.cc:3323
# extraspace needed to get a space before the semicolon
msgid "Regions in edit groups are edited together"
msgstr "Les régions des groupes d'édition sont éditées ensemble"
msgstr "Les régions des groupes d'édition sont éditées ensemble "
#: rc_option_editor.cc:3328
msgid "whenever they overlap in time"
@ -15597,8 +15612,9 @@ msgid "if they have identical length, position and layer"
msgstr "s'ils ont une longueur, une position et une couche identiques"
#: rc_option_editor.cc:3338
# extraspace needed to get a space before the semicolon
msgid "Layering model"
msgstr "Type d'empilage"
msgstr "Type d'empilage "
#: rc_option_editor.cc:3343
msgid "later is higher"
@ -15609,8 +15625,9 @@ msgid "manual layering"
msgstr "manuel"
#: rc_option_editor.cc:3351
# extraspace needed to get a space before the semicolon
msgid "After a Separate operation, in Range mode"
msgstr "Après une opération de Séparation, en mode Intervalle"
msgstr "Après une opération de séparation, en mode Intervalle "
#: rc_option_editor.cc:3355
msgid "Clear the Range Selection"
@ -15625,8 +15642,9 @@ msgid "Select the regions under the range."
msgstr "Sélectionner les régions dans l'intervalle."
#: rc_option_editor.cc:3363
# extraspace needed to get a space before the semicolon
msgid "After a Split operation, in Object mode"
msgstr "Après une opération de Séparation, en mode Édition"
msgstr "Après une opération de Séparation, en mode Édition "
#: rc_option_editor.cc:3368
msgid "Clear the Region Selection"
@ -15670,12 +15688,14 @@ msgid "General Snap options:"
msgstr "Options générales de l'aimant :"
#: rc_option_editor.cc:3387
# extraspace needed to get a space before the semicolon
msgid "Snap Threshold (pixels)"
msgstr "Seuil de l'aimant (pixels)"
msgstr "Seuil de l'aimant (pixels) "
#: rc_option_editor.cc:3397
# extraspace needed to get a space before the semicolon
msgid "Approximate Grid/Ruler granularity (pixels)"
msgstr "Granularité approximative de la grille/règle (pixels)"
msgstr "Granularité approximative de la grille/règle (pixels) "
#: rc_option_editor.cc:3407
msgid "Show \"snapped cursor\""
@ -15705,8 +15725,9 @@ msgid "Snap Target Mode:"
msgstr "Mode cibles aimantées :"
#: rc_option_editor.cc:3449
# extraspace needed to get a space before the semicolon
msgid "When the Grid is enabled, snap to"
msgstr "Lorsque la grille est activée, aimanter dessus"
msgstr "Lorsque la grille est activée, aimanter dessus "
#: rc_option_editor.cc:3454
msgid "Snap Targets"
@ -15738,7 +15759,7 @@ msgstr "Éditeur/Touches spéciales"
#: rc_option_editor.cc:3500
msgid "Keyboard Modifiers"
msgstr "Touches Spéciales"
msgstr "Touches spéciales"
#: rc_option_editor.cc:3511
msgid "Allow non quarter-note pulse"
@ -15756,8 +15777,9 @@ msgstr ""
"minute"
#: rc_option_editor.cc:3524
# extraspace needed to get a space before the semicolon
msgid "Initial program change"
msgstr "Modifier le programme initial (IPC)"
msgstr "Modifier le programme initial (IPC) "
#: rc_option_editor.cc:3530
msgid "Editing"
@ -15780,8 +15802,9 @@ msgid "Sound MIDI notes as they are selected in the editor"
msgstr "Jouer les notes MIDI lorsqu'elles sont sélectionnées dans l'éditeur"
#: rc_option_editor.cc:3562
# extraspace needed to get a space before the semicolon
msgid "Virtual Keyboard Layout"
msgstr "Agencement du clavier virtuel"
msgstr "Agencement du clavier virtuel "
#: rc_option_editor.cc:3567
msgid "Mouse-only (no keyboard)"
@ -15820,16 +15843,19 @@ msgid "legal characters for MIDI note names|ABCDEFG#1234567890"
msgstr "ABCDEFG#1234567890"
#: rc_option_editor.cc:3581
# extraspace needed to get a space before the semicolon
msgid "Default lower visible MIDI note"
msgstr "Note MIDI inférieure visible par défaut"
msgstr "Note MIDI inférieure visible par défaut "
#: rc_option_editor.cc:3586
# extraspace needed to get a space before the semicolon
msgid "Default upper visible MIDI note"
msgstr "Note MIDI superieure visible par défaut"
msgstr "Note MIDI superieure visible par défaut "
#: rc_option_editor.cc:3591
# extraspace needed to get a space before the semicolon
msgid "Maximum note height"
msgstr "Hauteur maximum de note"
msgstr "Hauteur maximum de note "
#: rc_option_editor.cc:3600
msgid "MIDI Port Options"
@ -15841,7 +15867,7 @@ msgstr "L'entrée MIDI suit la sélection de piste MIDI"
#: rc_option_editor.cc:3610 rc_option_editor.cc:3611
msgid "MIDI/MIDI Port Config"
msgstr "Configuration de Port MIDI/MIDI"
msgstr "MIDI/Configuration de Port MIDI"
#: rc_option_editor.cc:3621
msgid "Prompt for new marker names"
@ -15892,9 +15918,10 @@ msgid ""
"<b>When disabled</b> master record will be disabled when the transport "
"transitions to stop."
msgstr ""
"<b>Si coché</b>, le rouge (master record) restera engagé en stoppant le "
"défilement.\n"
"<b>Si décoché</b>, le rouge sera désengagé en stoppant le défilement."
"<b>Si coché</b>, l'enregistrement général restera engagé lorsque le "
"transport passe à l'arrêt.\n"
"<b>Si décoché</b>, l'enregistrement général sera désengagé lorsque le "
"transport passe à l'arrêt.\n"
#: rc_option_editor.cc:3655
msgid "Reset default speed on stop"
@ -15979,8 +16006,9 @@ msgstr ""
"après les opérations de rembobinage/débobinage."
#: rc_option_editor.cc:3711
# extraspace needed to get a space before the semicolon
msgid "Preroll"
msgstr "Pré-roll"
msgstr "Pré-roll "
#: rc_option_editor.cc:3716
msgid ""
@ -16055,8 +16083,9 @@ msgstr ""
"stoppe puis annule la lecture en boucle"
#: rc_option_editor.cc:3748
# extraspace needed to get a space before the semicolon
msgid "Loop Fades"
msgstr "Fondus de boucle"
msgstr "Fondus de boucle "
#: rc_option_editor.cc:3752
msgid "No fades at loop boundaries"
@ -16118,12 +16147,13 @@ msgid "Respond to MMC commands"
msgstr "Réception des commandes MMC"
#: rc_option_editor.cc:3800
# extraspace needed to get a space before the semicolon
msgid "Inbound MMC device ID"
msgstr "Identifiant de l'appareil MMC en entrée"
msgstr "Identifiant de l'appareil MMC en entrée "
#: rc_option_editor.cc:3809
msgid "Show Transport Masters Window"
msgstr "Afficher la fenêtre du gestionnaire de transport"
msgstr "Afficher la fenêtre du transport général"
#: rc_option_editor.cc:3814
msgid "Match session video frame rate to external timecode"
@ -16221,8 +16251,9 @@ msgstr ""
"(tête) est immobile"
#: rc_option_editor.cc:3865
# extraspace needed to get a space before the semicolon
msgid "LTC generator level [dBFS]"
msgstr "Niveau [dBFS] du générateur LTC"
msgstr "Niveau [dBFS] du générateur LTC "
#: rc_option_editor.cc:3873
msgid ""
@ -16242,7 +16273,7 @@ msgstr "Activer le générateur MTC"
#: rc_option_editor.cc:3892
msgid "Max MTC varispeed (%)"
msgstr ""
msgstr "Varispeed MTC maxi (%s) "
#: rc_option_editor.cc:3897
msgid "Percentage either side of normal transport speed to transmit MTC."
@ -16255,8 +16286,9 @@ msgid "Send MMC commands"
msgstr "Envoi des commandes MMC"
#: rc_option_editor.cc:3913
# extraspace needed to get a space before the semicolon
msgid "Outbound MMC device ID"
msgstr "Identifiant de l'appareil MMC en sortie"
msgstr "Identifiant de l'appareil MMC en sortie "
#: rc_option_editor.cc:3919
msgid "MIDI Beat Clock (Mclk) Generator"
@ -16416,8 +16448,9 @@ msgstr ""
"graphique de greffon visibles est illimité"
#: rc_option_editor.cc:4038
# extraspace needed to get a space before the semicolon
msgid "Closing a Plugin GUI Window"
msgstr "Fermeture de la fenêtre d'interface graphique d'un greffon"
msgstr "Fermeture de la fenêtre d'interface graphique d'un greffon "
#: rc_option_editor.cc:4042
msgid "only hides the window"
@ -16642,22 +16675,22 @@ msgid "Plugin recent list length"
msgstr "Longueur de la liste des greffons récents"
#: rc_option_editor.cc:4310
# extraspace needed to get a space before the semicolon
msgid "Record monitoring handled by"
msgstr "Écoute de contrôle de l'enregistrement géré par"
msgstr "Écoute de contrôle de l'enregistrement géré par "
#: rc_option_editor.cc:4328
msgid "Auto Input does 'talkback'"
msgstr "Toujours écouter l'entrée des pistes"
#: rc_option_editor.cc:4334
#, fuzzy
msgid ""
"<b>When enabled</b>, and Transport -> Auto-Input is enabled, %1 will always "
"monitor audio inputs when transport is stopped, even if tracks aren't armed."
msgstr ""
"<b>Si coché</b>, et le bouton Entrée-auto allumé, %1 écoutera toujours "
"l'entrée des pistes audio à l'arrêt du défilement, même si les pistes ne "
"sont pas armées."
"<b>Si coché</b>, et que le bouton Transport -> Entrée-auto est activé, %1 "
"écoutera toujours les entrées audio lorsque le transport est arrêté, même "
"si les pistes ne sont pas armées."
#: rc_option_editor.cc:4341
msgid "Solo controls are Listen controls"
@ -16676,12 +16709,14 @@ msgid "Soloing overrides muting"
msgstr "Solo surplante muet"
#: rc_option_editor.cc:4375
# extraspace needed to get a space before the semicolon
msgid "Solo-in-place mute cut (dB)"
msgstr "Diminution (en dB) des pistes NON solo-en-place"
msgstr "Diminution (en dB) des pistes NON solo-en-place "
#: rc_option_editor.cc:4382
# extraspace needed to get a space before the semicolon
msgid "Listen Position"
msgstr "Position d'écoute"
msgstr "Position d'écoute "
#: rc_option_editor.cc:4387
msgid "after-fader (AFL)"
@ -16692,8 +16727,9 @@ msgid "pre-fader (PFL)"
msgstr "pré-atténuateur (PFL)"
#: rc_option_editor.cc:4394
# extraspace needed to get a space before the semicolon
msgid "PFL signals come from"
msgstr "Les signaux PFL sont prélevés"
msgstr "Les signaux PFL sont prélevés "
#: rc_option_editor.cc:4399
msgid "before pre-fader processors"
@ -16704,8 +16740,9 @@ msgid "pre-fader but after pre-fader processors"
msgstr "après les traitements pré-atténuateur"
#: rc_option_editor.cc:4406
# extraspace needed to get a space before the semicolon
msgid "AFL signals come from"
msgstr "Les signaux AFL sont prélevés"
msgstr "Les signaux AFL sont prélevés "
#: rc_option_editor.cc:4411
msgid "immediately post-fader"
@ -16721,11 +16758,12 @@ msgstr "Général"
#: rc_option_editor.cc:4422
msgid "Enable master-bus output gain control"
msgstr "Activer le contrôle de gain de sortie du bus maître"
msgstr "Activer le contrôle de gain de sortie du bus général"
#: rc_option_editor.cc:4429
# extraspace needed to get a space before the semicolon
msgid "I/O Resampler (vari-speed) quality"
msgstr "Qualité de rééchantillonage E/S (vari-speed)"
msgstr "Qualité de rééchantillonage E/S (vari-speed) "
#: rc_option_editor.cc:4434
msgid "Off (no vari-speed)"
@ -16832,7 +16870,7 @@ msgstr "Connexions piste et bus"
#: rc_option_editor.cc:4520
msgid "Auto-connect main output (master or monitor) bus to physical ports"
msgstr ""
"Connexion automatique du bus de sortie principal (master ou écoute de "
"Connexion automatique du bus de sortie principal (général ou écoute de "
"contrôle) aux ports physiques"
#: rc_option_editor.cc:4526
@ -16845,11 +16883,12 @@ msgstr ""
"<b>Si coché</b>, le bus de sortie principal est auto-connecté aux N premiers "
"ports physiques. Si la session comporte une section d'écoute de contrôle, "
"son bus de sortie est connecté aux ports matériels d'écoute, sinon c'est la "
"sortie du bus Master qui est directement utilisée pour la lecture."
"sortie du bus général qui est directement utilisée pour la lecture."
#: rc_option_editor.cc:4532
# extraspace needed to get a space before the semicolon
msgid "Connect track inputs"
msgstr "Connecter les entrées des pistes"
msgstr "Connecter les entrées des pistes "
#: rc_option_editor.cc:4537
msgid "automatically to physical inputs"
@ -16860,8 +16899,9 @@ msgid "manually"
msgstr "manuellement"
#: rc_option_editor.cc:4544
# extraspace needed to get a space before the semicolon
msgid "Connect track and bus outputs"
msgstr "Connecter les sorties de pistes et bus"
msgstr "Connecter les sorties de pistes et bus "
#: rc_option_editor.cc:4549
msgid "automatically to physical outputs"
@ -16900,8 +16940,9 @@ msgid "Meterbridge meters"
msgstr "Bandeau de mesure"
#: rc_option_editor.cc:4603
# extraspace needed to get a space before the semicolon
msgid "Peak hold time"
msgstr "Durée de maintien de crête"
msgstr "Durée de maintien de crête "
#: rc_option_editor.cc:4609
msgid "short"
@ -16916,8 +16957,9 @@ msgid "long"
msgstr "long"
#: rc_option_editor.cc:4617
# extraspace needed to get a space before the semicolon
msgid "DPM fall-off"
msgstr "Chute du pic"
msgstr "Chute du pic "
#: rc_option_editor.cc:4623
msgid "slowest [6.6dB/sec]"
@ -16944,8 +16986,9 @@ msgid "very fast [32dB/sec]"
msgstr "très rapide [32dB/sec]"
#: rc_option_editor.cc:4634
# extraspace needed to get a space before the semicolon
msgid "Meter line-up level; 0dBu"
msgstr "Niveau ligne, 0 dBu"
msgstr "Niveau ligne, 0 dBu "
#: rc_option_editor.cc:4639 rc_option_editor.cc:4655
msgid "-24dBFS (SMPTE US: 4dBu = -20dBFS)"
@ -16973,16 +17016,18 @@ msgstr ""
"et VU-mètre."
#: rc_option_editor.cc:4650
# extraspace needed to get a space before the semicolon
msgid "IEC1/DIN Meter line-up level; 0dBu"
msgstr "Niveau ligne IEC1/DIN, 0 dBu"
msgstr "Niveau ligne IEC1/DIN, 0 dBu "
#: rc_option_editor.cc:4660
msgid "Reference level for IEC1/DIN meter."
msgstr "Niveau de référence pour les indicateurs IEC1/DIN."
#: rc_option_editor.cc:4666
# extraspace needed to get a space before the semicolon
msgid "VU Meter standard"
msgstr "VU-mètre standard"
msgstr "VU-mètre standard "
#: rc_option_editor.cc:4671
msgid "0VU = -2dBu (France)"
@ -17001,8 +17046,9 @@ msgid "0VU = +8dBu"
msgstr "0VU = +8dBu"
#: rc_option_editor.cc:4679
# extraspace needed to get a space before the semicolon
msgid "Peak indicator threshold [dBFS]"
msgstr "Seuil de l'indicateur de pic [dBFS]"
msgstr "Seuil de l'indicateur de pic [dBFS] "
#: rc_option_editor.cc:4687
msgid ""
@ -17022,19 +17068,22 @@ msgid ""
"this will be when a new session is created."
msgstr ""
"Ces réglages s'appliquent aux pistes et bus nouvellement créés. Pour le bus "
"Master, ce sera à la création d'une nouvelle session."
"général, ce sera à la création d'une nouvelle session."
#: rc_option_editor.cc:4698
# extraspace needed to get a space before the semicolon
msgid "Default Meter Type for Master Bus"
msgstr "Type d'indicateur par défaut du bus Master"
msgstr "Type d'indicateur par défaut du bus général "
#: rc_option_editor.cc:4716
# extraspace needed to get a space before the semicolon
msgid "Default meter type for busses"
msgstr "Type d'indicateur par défaut des bus"
msgstr "Type d'indicateur par défaut des bus "
#: rc_option_editor.cc:4734
# extraspace needed to get a space before the semicolon
msgid "Default meter type for tracks"
msgstr "Type d'indicateur par défaut des pistes"
msgstr "Type d'indicateur par défaut des pistes "
#: rc_option_editor.cc:4750
msgid "Region Analysis"
@ -17057,8 +17106,9 @@ msgid "DSP CPU Utilization"
msgstr "Utilisation processeur par les traitements audio"
#: rc_option_editor.cc:4770
# extraspace needed to get a space before the semicolon
msgid "Signal processing uses"
msgstr "Le traitement du signal utilise"
msgstr "Le traitement du signal utilise "
#: rc_option_editor.cc:4775
msgid "all but one processor"
@ -17079,8 +17129,9 @@ msgid "This setting will only take effect when %1 is restarted."
msgstr "Cette option ne sera prise en compte qu'après un redémarrage d'%1."
#: rc_option_editor.cc:4792
# extraspace needed to get a space before the semicolon
msgid "Power Management, CPU DMA latency"
msgstr "Gestion de l'énergie, latence DMA du CPU"
msgstr "Gestion de l'énergie, latence DMA du CPU "
#: rc_option_editor.cc:4823
msgid "Lowest (prevent CPU sleep states)"
@ -17113,8 +17164,9 @@ msgid "Use DC bias to protect against denormals"
msgstr "Utiliser un courant polarisé (DC) pour éviter les dénormalisations"
#: rc_option_editor.cc:4853
# extraspace needed to get a space before the semicolon
msgid "Processor handling"
msgstr "Gestion du traitement"
msgstr "Gestion du traitement "
#: rc_option_editor.cc:4859
msgid "no processor handling"
@ -17147,8 +17199,9 @@ msgid "Memory Usage"
msgstr "Utilisation de la mémoire"
#: rc_option_editor.cc:4901
# extraspace needed to get a space before the semicolon
msgid "Waveform image cache size (megabytes)"
msgstr "Taille du cache d'images de signal (Mb)"
msgstr "Taille du cache d'images de signal (Mb) "
#: rc_option_editor.cc:4909
msgid ""
@ -17159,20 +17212,23 @@ msgstr ""
"de signal, ce qui peut impacter les performances graphiques."
#: rc_option_editor.cc:4917
# extraspace needed to get a space before the semicolon
msgid "Thinning factor (larger value => less data)"
msgstr "Facteur d'espacement (plus => moins de données)"
msgstr "Facteur d'espacement (plus => moins de données) "
#: rc_option_editor.cc:4926
# extraspace needed to get a space before the semicolon
msgid "Automation sampling interval (milliseconds)"
msgstr "Intervalle des points d'automation (msec)"
msgstr "Intervalle des points d'automation (msec) "
#: rc_option_editor.cc:4932
msgid "Automatables"
msgstr "Automatisables"
#: rc_option_editor.cc:4936
# extraspace needed to get a space before the semicolon
msgid "Limit automatable parameters per plugin"
msgstr "Limiter les paramètres d'automation par greffon"
msgstr "Limiter les paramètres d'automation par greffon "
#: rc_option_editor.cc:4943
msgid "256 parameters"
@ -17657,7 +17713,6 @@ msgid "Record enable"
msgstr "Armement"
#: route_group_dialog.cc:53
#, fuzzy
msgid "Surround Send enable"
msgstr "Activation du départ Surround"
@ -18004,7 +18059,6 @@ msgid "Main Outs"
msgstr "Sorties principales"
#: route_ui.cc:1479
#, fuzzy
msgid "Surround Send"
msgstr "Départ Surround"
@ -18901,7 +18955,7 @@ msgstr "Afficher les bus"
#: session_option_editor.cc:306
msgid "Include Master Bus"
msgstr "Inclure le bus Master"
msgstr "Inclure le bus général"
#: session_option_editor.cc:311
msgid "Button Area"
@ -19372,7 +19426,7 @@ msgstr "<b>Noms de pistes MIDI :</b>"
#: sfdb_ui.cc:1961
msgid "<b>Audio conversion quality:</b>"
msgstr "<b>Qualité de conversion ausio :</b>"
msgstr "<b>Qualité de conversion audio :</b>"
#: sfdb_ui.cc:1982 sfdb_ui.cc:2101
msgid "Best"
@ -19446,7 +19500,6 @@ msgid "> %+2d st"
msgstr "> %+2d st"
#: simple_export_dialog.cc:47
#, fuzzy
msgid "Surround Master Export"
msgstr "Exportation Surround Master"
@ -21717,7 +21770,7 @@ msgstr "Audio :"
#: export_video_dialog.cc:132
msgid "Master Bus"
msgstr "Bus master"
msgstr "Bus général"
#: export_video_dialog.cc:142
msgid "(default for codec)"
@ -21838,7 +21891,7 @@ msgstr ""
#: export_video_dialog.cc:608
msgid "Export Video: No Master Out Ports to Connect for Audio Export"
msgstr ""
"Export vidéo : aucun port de sortie principal auquel se connecter pour "
"Export vidéo : aucun port de sortie générale auquel se connecter pour "
"l'export audio"
#: export_video_dialog.cc:655
@ -22617,9 +22670,6 @@ msgstr "Fichier vidéo d'entrée"
#~ "\n"
#~ "Nous allons configurer le logiciel avant que vous ne l'utilisiez.</span> "
#~ msgid "GUI and Font scaling:"
#~ msgstr "Ajustement d'interface et de police : "
#~ msgid ""
#~ "Each project that you work on with %1 has its own folder.\n"
#~ "These can require a lot of disk space if you are recording audio.\n"
@ -23094,10 +23144,6 @@ msgstr "Fichier vidéo d'entrée"
#~ msgid "Transcoding Video.."
#~ msgstr "Transcodage vidéo.."
#, fuzzy
#~ msgid "Scale Video (W x H):"
#~ msgstr "Taille de vidéo (L x H) :"
#~ msgid "Retain Aspect"
#~ msgstr "Conserver l'aspect"
@ -23113,9 +23159,6 @@ msgstr "Fichier vidéo d'entrée"
#~ msgid "Codec Optimizations:"
#~ msgstr "Optimisations du codec :"
#~ msgid "Deinterlace"
#~ msgstr "Désentrelacer"
#~ msgid "Use [2] B-frames (MPEG 2 or 4 only)"
#~ msgstr "Choisir [2] B-frames (MPEG 2 ou 4 uniquement)"
@ -23469,26 +23512,6 @@ msgstr "Fichier vidéo d'entrée"
#~ "la boucle quand %1 atteint la fin, ce qui peut souvent causer un léger "
#~ "clic ou délai."
#~ msgid ""
#~ "Rules for closing, minimizing, maximizing, and stay-on-top can vary with "
#~ "each version of your OS, and the preferences that you've set in your OS.\n"
#~ "\n"
#~ "You can adjust the options, below, to change how %1's windows and dialogs "
#~ "behave.\n"
#~ "\n"
#~ "These settings will only take effect after %1 is restarted.\n"
#~ "\t"
#~ msgstr ""
#~ "Les règles pour fermer, minimiser, maximiser, and rester au-dessus "
#~ "varient selon la version de votre SO, et les préférences que vous avez "
#~ "réglées dans votre SO.\n"
#~ "\n"
#~ "Vous pouvez ajuster les options, ci-dessous, pour modifier le "
#~ "comportement des fenêtres et boites de dialogue d'%1.\n"
#~ "\n"
#~ "Ces réglages ne prendront effet qu'après un redémarrage d'%1.\n"
#~ "\t"
#~ msgid "destructive-xfade-seconds"
#~ msgstr "Secondes-de-fondu-destructif"

View File

@ -462,7 +462,9 @@ PortGroupList::gather (ARDOUR::Session* session, ARDOUR::DataType type, bool inp
if (type == DataType::AUDIO || type == DataType::NIL) {
if (!inputs) {
program->add_bundle (session->the_auditioner()->output()->bundle());
if (session->the_auditioner()) {
program->add_bundle (session->the_auditioner()->output()->bundle());
}
if (session->click_io()) {
program->add_bundle (session->click_io()->bundle());
}

View File

@ -588,6 +588,11 @@ public:
virtual void set_tempo_curve_range (double& max, double& min) const = 0;
virtual void start_track_drag (TimeAxisView&, int y, Gtk::Widget&) = 0;
virtual void mid_track_drag (GdkEventMotion*, Gtk::Widget&) = 0;
virtual void end_track_drag () = 0;
virtual bool track_dragging() const = 0;
/// Singleton instance, set up by Editor::Editor()
static PublicEditor* _instance;

View File

@ -4906,6 +4906,27 @@ These settings will only take effect after %1 is restarted.\n\
add_option (_("Performance"), new BufferingOptions (_rc_config));
if (hwcpus > 1) {
ComboOption<int32_t>* procs = new ComboOption<int32_t> (
"io-thread-count",
_("Disk I/O threads"),
sigc::mem_fun (*_rc_config, &RCConfiguration::get_io_thread_count),
sigc::mem_fun (*_rc_config, &RCConfiguration::set_io_thread_count)
);
procs->add (-2, _("all but two processor"));
procs->add (-1, _("all but one processor"));
procs->add (0, _("all available processors"));
for (uint32_t i = 1; i <= hwcpus; ++i) {
procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
}
procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
add_option (_("Performance"), procs);
}
/* Image cache size */
add_option (_("Performance"), new OptionEditorHeading (_("Memory Usage")));

View File

@ -340,20 +340,23 @@ RemainInfoBox::render (Cairo::RefPtr<Cairo::Context> const& cr, cairo_rectangle_
float remain_sec = samples / (float)sample_rate;
char buf[32];
bool at_least = FLAC == _session->config.get_native_file_header_format ();
const char* prefix = at_least ? u8"\u2265" : ""; // Greater-Than or Equal To
if (remain_sec > 86400) {
_layout_value->set_text (_(">24h"));
} else if (remain_sec > 32400 /* 9 hours */) {
snprintf (buf, sizeof (buf), "%.0f", remain_sec / 3600.f);
snprintf (buf, sizeof (buf), "%s%.0f", prefix, remain_sec / 3600.f);
_layout_value->set_text (std::string (buf) + S_("hours|h"));
} else if (remain_sec > 5940 /* 99 mins */) {
snprintf (buf, sizeof (buf), "%.1f", remain_sec / 3600.f);
snprintf (buf, sizeof (buf), "%s%.1f", prefix, remain_sec / 3600.f);
_layout_value->set_text (std::string (buf) + S_("hours|h"));
} else if (remain_sec > 60*3 /* 3 mins */) {
snprintf (buf, sizeof (buf), "%.0f", remain_sec / 60.f);
snprintf (buf, sizeof (buf), "%s%.0f", prefix, remain_sec / 60.f);
_layout_value->set_text (std::string (buf) + S_("minutes|m"));
} else {
Gtkmm2ext::set_source_rgb_a (cr, UIConfiguration::instance ().color ("alert:red"), .7);
snprintf (buf, sizeof (buf), "%.0f", remain_sec / 60.f);
snprintf (buf, sizeof (buf), "%s%.0f", prefix, remain_sec / 60.f);
_layout_value->set_text (std::string (buf) + S_("minutes|m"));
}
}

View File

@ -28,18 +28,31 @@
#include "pbd/memento_command.h"
#include "pbd/stateful_diff_command.h"
#include "pbd/unwind.h"
#include "gtkmm2ext/dndtreeview.h"
#include "widgets/tooltips.h"
#include "ardour/plugin_manager.h"
#include "ardour/region.h"
#include "ardour/region_fx_plugin.h"
#include "ardour/session.h"
#include "ardour/source.h"
#include "ardour_message.h"
#include "ardour_ui.h"
#include "clock_group.h"
#include "main_clock.h"
#include "context_menu_helper.h"
#include "gui_thread.h"
#include "keyboard.h"
#include "main_clock.h"
#include "mixer_ui.h"
#include "new_plugin_preset_dialog.h"
#include "region_editor.h"
#include "region_view.h"
#include "plugin_selector.h"
#include "plugin_window_proxy.h"
#include "public_editor.h"
#include "pbd/i18n.h"
@ -49,11 +62,11 @@ using namespace PBD;
using namespace std;
using namespace Gtkmm2ext;
RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
RegionEditor::RegionEditor (Session* s, RegionView* rv)
: ArdourDialog (_("Region"))
, _table (9, 2)
, _table (9, 3)
, _table_row (0)
, _region (r)
, _region (rv->region ())
, name_label (_("Name:"))
, audition_button (_("Audition"))
, _clock_group (new ClockGroup)
@ -64,11 +77,12 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
, sync_offset_absolute_clock (X_("regionsyncoffsetabsolute"), true, "", true, false)
/* XXX cannot file start yet */
, start_clock (X_("regionstart"), true, "", false, false)
, _region_fx_box (_region)
, _sources (1)
{
set_session (s);
switch (r->time_domain()) {
switch (_region->time_domain()) {
case Temporal::AudioTime:
/* XXX check length of region and choose samples or minsec */
_clock_group->set_clock_mode (AudioClock::MinSec);
@ -113,6 +127,8 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
start_label.set_name ("RegionEditorLabel");
start_label.set_text (_("File start:"));
_sources_label.set_name ("RegionEditorLabel");
region_fx_label.set_text (_("Region Effects"));
region_fx_label.set_name ("RegionEditorLabel");
if (_region->sources().size() > 1) {
_sources_label.set_text (_("Sources:"));
@ -170,6 +186,9 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
_table.attach (_sources, 1, 2, _table_row, _table_row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::FILL);
++_table_row;
_table.attach (region_fx_label, 2, 3, 0, 1, Gtk::FILL, Gtk::FILL);
_table.attach (_region_fx_box, 2, 3, 1, _table_row + 2, Gtk::FILL, Gtk::FILL);
get_vbox()->pack_start (_table, true, true);
add_button (Gtk::Stock::CLOSE, Gtk::RESPONSE_ACCEPT);
@ -190,6 +209,9 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
assert (t);
t->property_ellipsize() = Pango::ELLIPSIZE_END;
region_fx_label.set_no_show_all ();
_region_fx_box.set_no_show_all ();
show_all();
name_changed ();
@ -203,9 +225,16 @@ RegionEditor::RegionEditor (Session* s, std::shared_ptr<Region> r)
bounds_changed (change);
_region->PropertyChanged.connect (state_connection, invalidator (*this), boost::bind (&RegionEditor::region_changed, this, _1), gui_context());
_region->RegionFxChanged.connect (region_connection, invalidator (*this), boost::bind (&RegionEditor::region_fx_changed, this), gui_context ());
spin_arrow_grab = false;
/* for now only audio region effects are supported */
if (std::dynamic_pointer_cast<AudioRegion> (_region)) {
region_fx_label.show ();
_region_fx_box.show ();
}
connect_editor_events ();
}
@ -238,6 +267,12 @@ RegionEditor::region_changed (const PBD::PropertyChange& what_changed)
}
}
void
RegionEditor::region_fx_changed ()
{
_region_fx_box.redisplay_plugins ();
}
gint
RegionEditor::bpressed (GdkEventButton* ev, Gtk::SpinButton* /*but*/, void (RegionEditor::*/*pmf*/)())
{
@ -469,3 +504,541 @@ RegionEditor::handle_response (int)
{
hide ();
}
/* ****************************************************************************/
static std::list<Gtk::TargetEntry>
drop_targets ()
{
std::list<Gtk::TargetEntry> tmp;
tmp.push_back (Gtk::TargetEntry ("x-ardour/region-fx", Gtk::TARGET_SAME_APP)); // re-order
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.info", Gtk::TARGET_SAME_APP)); // from plugin-manager
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.favorite", Gtk::TARGET_SAME_APP)); // from sidebar
return tmp;
}
static std::list<Gtk::TargetEntry>
drag_targets ()
{
std::list<Gtk::TargetEntry> tmp;
tmp.push_back (Gtk::TargetEntry ("x-ardour/region-fx", Gtk::TARGET_SAME_APP)); // re-order
tmp.push_back (Gtk::TargetEntry ("x-ardour/plugin.preset", Gtk::TARGET_SAME_APP)); // to sidebar (optional preset)
return tmp;
}
RegionEditor::RegionFxBox::RegionFxBox (std::shared_ptr<ARDOUR::Region> r)
: _region (r)
, _display (drop_targets ())
, _no_redisplay (false)
, _placement (-1)
{
_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
_scroller.set_name ("ProcessorScroller");
_scroller.add (_display);
pack_start (_scroller, true, true);
_display.set_can_focus ();
_display.set_name ("ProcessorList");
_display.set_data ("regionfxbox", this);
_display.set_size_request (104, -1); // TODO UI scale
_display.set_spacing (0);
_display.ButtonPress.connect (sigc::mem_fun (*this, &RegionFxBox::fxe_button_press_event));
_display.ButtonRelease.connect (sigc::mem_fun (*this, &RegionFxBox::fxe_button_release_event));
_display.Reordered.connect (sigc::mem_fun (*this, &RegionFxBox::reordered));
_display.DropFromAnotherBox.connect (sigc::mem_fun (*this, &RegionFxBox::object_drop));
_display.DropFromExternal.connect (sigc::mem_fun (*this, &RegionFxBox::plugin_drop));
_display.signal_key_press_event ().connect (sigc::mem_fun (*this, &RegionFxBox::on_key_press), false);
_scroller.show ();
_display.show ();
redisplay_plugins ();
}
bool
RegionEditor::RegionFxBox::use_plugins (SelectedPlugins const& plugins)
{
int errors = 0;
{
PBD::Unwinder<bool> uw (_no_redisplay, true);
for (auto const& p : plugins) {
std::shared_ptr<RegionFxPlugin> pos;
if (_placement >= 0) {
pos = _region->nth_plugin (_placement++);
}
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), pos)) {
++errors;
}
}
}
redisplay_plugins ();
if (errors) {
notify_plugin_load_fail (errors);
}
return false;
}
void
RegionEditor::RegionFxBox::redisplay_plugins ()
{
if (_no_redisplay) {
return;
}
_display.clear ();
_region->foreach_plugin (sigc::mem_fun (*this, &RegionFxBox::add_fx_to_display));
}
void
RegionEditor::RegionFxBox::add_fx_to_display (std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return;
}
RegionFxEntry* e = new RegionFxEntry (fx);
_display.add_child (e, drag_targets ());
}
bool
RegionEditor::RegionFxBox::fxe_button_press_event (GdkEventButton* ev, RegionFxEntry* child)
{
if (child) {
std::weak_ptr<RegionFxPlugin> wfx (std::weak_ptr<RegionFxPlugin> (child->region_fx_plugin ()));
if (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS)) {
if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) {
show_plugin_gui (wfx, false);
} else {
show_plugin_gui (wfx, true);
}
return true;
}
if (Keyboard::is_context_menu_event (ev)) {
using namespace Gtk::Menu_Helpers;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
Gtk::Menu* m = ARDOUR_UI_UTILS::shared_popup_menu ();
MenuList& items = m->items ();
items.push_back (MenuElem (_("New Plugin")));
Gtk::MenuItem& npm = items.back ();
npm.set_submenu (*ps->plugin_menu ());
std::shared_ptr<Plugin> plugin = child->region_fx_plugin ()->plugin ();
items.push_back (SeparatorElem ());
items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, true)));
items.back ().set_sensitive (plugin->has_editor ());
items.push_back (MenuElem (_("Edit with generic controls..."), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::show_plugin_gui), wfx, false)));
Gtk::Menu* automation_menu = manage (new Gtk::Menu);
MenuList& ac_items (automation_menu->items ());
for (size_t i = 0; i < plugin->parameter_count (); ++i) {
if (!plugin->parameter_is_control (i) || !plugin->parameter_is_input (i)) {
continue;
}
const Evoral::Parameter param (PluginAutomation, 0, i);
std::string label = plugin->describe_parameter (param);
if (label == X_("latency") || label == X_("hidden")) {
continue;
}
std::shared_ptr<ARDOUR::AutomationControl> c (std::dynamic_pointer_cast<ARDOUR::AutomationControl> (child->region_fx_plugin ()->control (param)));
if (c && c->flags () & (Controllable::HiddenControl | Controllable::NotAutomatable)) {
continue;
}
std::weak_ptr<ARDOUR::AutomationControl> wac (c);
bool play = c->automation_state () == Play;
ac_items.push_back (CheckMenuElem (label));
Gtk::CheckMenuItem* cmi = static_cast<Gtk::CheckMenuItem*> (&ac_items.back ());
cmi->set_active (play);
cmi->signal_activate ().connect ([wac, play] () {
std::shared_ptr<ARDOUR::AutomationControl> ac = wac.lock ();
if (ac) {
ac->set_automation_state (play ? ARDOUR::Off : Play);
}
});
}
if (!ac_items.empty ()) {
items.push_back (SeparatorElem ());
items.push_back (MenuElem ("Automation Enable", *automation_menu));
} else {
delete automation_menu;
}
items.push_back (SeparatorElem ());
items.push_back (MenuElem (_("Delete"), sigc::bind (sigc::mem_fun (*this, &RegionFxBox::queue_delete_region_fx), wfx)));
m->signal_unmap ().connect ([this, &npm] () { npm.remove_submenu (); _display.remove_placeholder (); });
m->popup (ev->button, ev->time);
int x, y;
_display.get_pointer (x, y);
_placement = _display.add_placeholder (y);
return true;
}
return false;
}
if (Keyboard::is_context_menu_event (ev)) {
_placement = -1;
using namespace Gtk::Menu_Helpers;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
Gtk::Menu* m = ARDOUR_UI_UTILS::shared_popup_menu ();
MenuList& items = m->items ();
items.push_back (MenuElem (_("New Plugin")));
Gtk::MenuItem& npm = items.back ();
npm.set_submenu (*ps->plugin_menu ());
m->signal_unmap ().connect ([&npm] () { npm.remove_submenu (); });
m->popup (ev->button, ev->time);
return true;
} else if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
_placement = -1;
PluginSelector* ps = Mixer_UI::instance ()->plugin_selector ();
ps->set_interested_object (*this);
ps->show_manager ();
return true;
}
return false;
}
bool
RegionEditor::RegionFxBox::fxe_button_release_event (GdkEventButton* ev, RegionFxEntry* child)
{
if (child && Keyboard::is_delete_event (ev)) {
queue_delete_region_fx (std::weak_ptr<RegionFxPlugin> (child->region_fx_plugin ()));
}
return false;
}
bool
RegionEditor::RegionFxBox::on_key_press (GdkEventKey* ev)
{
switch (ev->keyval) {
case GDK_KEY_Delete:
break;
case GDK_KEY_BackSpace:
break;
default:
return false;
}
for (auto const& i : _display.selection (true)) {
queue_delete_region_fx (std::weak_ptr<RegionFxPlugin> (i->region_fx_plugin ()));
}
return true;
}
void
RegionEditor::RegionFxBox::reordered ()
{
Region::RegionFxList fxl;
for (auto const& i : _display.children ()) {
fxl.push_back (i->region_fx_plugin ());
}
_region->reorder_plugins (fxl);
}
void
RegionEditor::RegionFxBox::queue_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin> wfx)
{
Glib::signal_idle ().connect (sigc::bind (sigc::mem_fun (*this, &RegionFxBox::idle_delete_region_fx), wfx));
}
bool
RegionEditor::RegionFxBox::idle_delete_region_fx (std::weak_ptr<RegionFxPlugin> wfx)
{
std::shared_ptr<RegionFxPlugin> fx (wfx.lock ());
if (!fx) {
return false;
}
_region->remove_plugin (fx);
return false;
}
void
RegionEditor::RegionFxBox::notify_plugin_load_fail (uint32_t cnt)
{
assert (cnt > 0);
ArdourMessageDialog (_("Failed to load Region Effect Plugin"), false, Gtk::MESSAGE_ERROR).run ();
}
std::shared_ptr<RegionFxPlugin>
RegionEditor::RegionFxBox::find_drop_position (RegionFxEntry* pos)
{
std::shared_ptr<RegionFxPlugin> rv;
if (pos) {
rv = pos->region_fx_plugin ();
if (!rv) {
rv = _display.children ().front ()->region_fx_plugin ();
}
}
return rv;
}
void
RegionEditor::RegionFxBox::plugin_drop (Gtk::SelectionData const& data, RegionFxEntry* pos, Glib::RefPtr<Gdk::DragContext> const& context)
{
uint32_t errors = 0;
std::shared_ptr<RegionFxPlugin> at = find_drop_position (pos);
if (data.get_target () == "x-ardour/plugin.info") {
const void* d = data.get_data ();
const Gtkmm2ext::DnDTreeView<ARDOUR::PluginInfoPtr>* tv = reinterpret_cast<const Gtkmm2ext::DnDTreeView<ARDOUR::PluginInfoPtr>*> (d);
PluginInfoList nfos;
Gtk::TreeView* source;
tv->get_object_drag_data (nfos, &source);
for (auto const& i : nfos) {
PluginPtr p = (i)->load (_region->session ());
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), at)) {
++errors;
}
}
} else if (data.get_target () == "x-ardour/plugin.favorite") {
const void* d = data.get_data ();
const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>* tv = reinterpret_cast<const Gtkmm2ext::DnDTreeView<ARDOUR::PluginPresetPtr>*> (d);
PluginPresetList nfos;
Gtk::TreeView* source;
tv->get_object_drag_data (nfos, &source);
for (auto const& i : nfos) {
PluginPresetPtr ppp (i);
PluginInfoPtr pip = ppp->_pip;
PluginPtr p = pip->load (_region->session ());
if (!p) {
continue;
}
if (ppp->_preset.valid) {
p->load_preset (ppp->_preset);
}
if (!_region->add_plugin (std::shared_ptr<RegionFxPlugin> (new RegionFxPlugin (_region->session (), _region->time_domain (), p)), at)) {
++errors;
}
}
}
if (errors) {
notify_plugin_load_fail (errors);
}
}
void
RegionEditor::RegionFxBox::delete_dragged_plugins (Region::RegionFxList const& fxl)
{
{
PBD::Unwinder<bool> uw (_no_redisplay, true);
for (auto const& fx : fxl) {
_region->remove_plugin (fx);
}
}
redisplay_plugins ();
}
void
RegionEditor::RegionFxBox::object_drop (Gtkmm2ext::DnDVBox<RegionFxEntry>* source, RegionFxEntry* pos, Glib::RefPtr<Gdk::DragContext> const& context)
{
if (Gdk::ACTION_LINK == context->get_selected_action ()) {
std::list<RegionFxEntry*> children = source->selection ();
assert (children.size () == 1);
RegionFxEntry* other = *children.begin ();
assert (other->can_copy_state (pos));
std::shared_ptr<ARDOUR::RegionFxPlugin> othr = other->region_fx_plugin ();
std::shared_ptr<ARDOUR::RegionFxPlugin> self = pos->region_fx_plugin ();
PBD::ID id = self->id ();
XMLNode& state = othr->get_state ();
state.remove_property ("count");
/* Controllable and automation IDs should not be copied */
PBD::Stateful::ForceIDRegeneration force_ids;
self->set_state (state, Stateful::current_state_version);
self->update_id (id);
return;
}
std::shared_ptr<RegionFxPlugin> at = find_drop_position (pos);
uint32_t errors = 0;
Region::RegionFxList fxl;
for (auto const& i : source->selection (true)) {
fxl.push_back (i->region_fx_plugin ());
}
for (auto const& i : fxl) {
XMLNode& state = i->get_state ();
state.remove_property ("count");
PBD::Stateful::ForceIDRegeneration force_ids;
std::shared_ptr<RegionFxPlugin> rfx (new RegionFxPlugin (_region->session (), _region->time_domain ()));
rfx->set_state (state, Stateful::current_state_version);
if (!_region->add_plugin (rfx, at)) {
++errors;
}
delete &state;
}
if ((context->get_suggested_action () == Gdk::ACTION_MOVE) && source) {
RegionFxBox* other = reinterpret_cast<RegionFxBox*> (source->get_data ("regionfxbox"));
if (other) {
other->delete_dragged_plugins (fxl);
}
}
if (errors) {
notify_plugin_load_fail (errors);
}
}
void
RegionEditor::RegionFxBox::show_plugin_gui (std::weak_ptr<RegionFxPlugin> wfx, bool custom_ui)
{
std::shared_ptr<RegionFxPlugin> rfx (wfx.lock ());
if (!rfx) {
return;
}
PluginWindowProxy* pwp;
if (rfx->window_proxy ()) {
pwp = dynamic_cast<PluginWindowProxy*> (rfx->window_proxy ());
} else {
pwp = new PluginWindowProxy (string_compose ("RFX-%1", rfx->id ()), _region->name (), rfx);
const XMLNode* ui_xml = rfx->session ().extra_xml (X_("UI"));
if (ui_xml) {
pwp->set_state (*ui_xml, 0);
}
rfx->set_window_proxy (pwp);
WM::Manager::instance ().register_window (pwp);
RegionView* rv = PublicEditor::instance ().regionview_from_region (_region);
rv->RegionViewGoingAway.connect_same_thread (*pwp, [pwp] (RegionView*) { pwp->hide (); });
}
pwp->set_custom_ui_mode (custom_ui);
pwp->show_the_right_window ();
Gtk::Window* tlw = PublicEditor::instance ().current_toplevel ();
if (tlw) {
pwp->set_transient_for (*tlw);
}
}
/* ****************************************************************************/
RegionEditor::RegionFxEntry::RegionFxEntry (std::shared_ptr<RegionFxPlugin> rfx)
: _fx_btn (ArdourWidgets::ArdourButton::default_elements)
, _rfx (rfx)
{
_box.pack_start (_fx_btn, true, true);
_plugin_preset_pointer = PluginPresetPtr (new PluginPreset (rfx->plugin ()->get_info ()));
_fx_btn.set_fallthrough_to_parent (true);
_fx_btn.set_text (name ());
_fx_btn.set_active (true);
_fx_btn.set_name ("processor postfader");
if (rfx->plugin ()->has_editor ()) {
set_tooltip (_fx_btn, string_compose (_("<b>%1</b>\nDouble-click to show GUI.\n%2+double-click to show generic GUI."), name (), Keyboard::secondary_modifier_name ()));
} else {
set_tooltip (_fx_btn, string_compose (_("<b>%1</b>\nDouble-click to show generic GUI."), name ()));
}
_box.show ();
_fx_btn.show ();
}
std::string
RegionEditor::RegionFxEntry::name () const
{
return _rfx->name ();
}
bool
RegionEditor::RegionFxEntry::can_copy_state (Gtkmm2ext::DnDVBoxChild* o) const
{
RegionFxEntry* other = dynamic_cast<RegionFxEntry*> (o);
if (!other) {
return false;
}
std::shared_ptr<ARDOUR::RegionFxPlugin> othr = other->region_fx_plugin ();
std::shared_ptr<ARDOUR::RegionFxPlugin> self = region_fx_plugin ();
if (self->type () != othr->type ()) {
return false;
}
std::shared_ptr<Plugin> my_p = self->plugin ();
std::shared_ptr<Plugin> ot_p = othr->plugin ();
return my_p->unique_id () == ot_p->unique_id ();
}
void
RegionEditor::RegionFxEntry::set_visual_state (Gtkmm2ext::VisualState s, bool yn)
{
if (yn) {
_fx_btn.set_visual_state (Gtkmm2ext::VisualState (_fx_btn.visual_state () | s));
} else {
_fx_btn.set_visual_state (Gtkmm2ext::VisualState (_fx_btn.visual_state () & ~s));
}
}
bool
RegionEditor::RegionFxEntry::drag_data_get (Glib::RefPtr<Gdk::DragContext> const, Gtk::SelectionData& data)
{
/* compare to ProcessorEntry::drag_data_get */
if (data.get_target () != "x-ardour/plugin.preset") {
return false;
}
std::shared_ptr<Plugin> plugin = _rfx->plugin ();
assert (plugin);
PluginManager& manager (PluginManager::instance ());
bool fav = manager.get_status (_plugin_preset_pointer->_pip) == PluginManager::Favorite;
NewPluginPresetDialog d (plugin, string_compose (_("New Favorite Preset for \"%1\""), _plugin_preset_pointer->_pip->name), !fav);
_plugin_preset_pointer->_preset.valid = false;
switch (d.run ()) {
default:
case Gtk::RESPONSE_CANCEL:
data.set (data.get_target (), 8, NULL, 0);
return true;
break;
case Gtk::RESPONSE_NO:
break;
case Gtk::RESPONSE_ACCEPT:
if (d.name ().empty ()) {
break;
}
if (d.replace ()) {
plugin->remove_preset (d.name ());
}
Plugin::PresetRecord const r = plugin->save_preset (d.name ());
if (!r.uri.empty ()) {
_plugin_preset_pointer->_preset.uri = r.uri;
_plugin_preset_pointer->_preset.label = r.label;
_plugin_preset_pointer->_preset.user = r.user;
_plugin_preset_pointer->_preset.valid = r.valid;
}
}
data.set (data.get_target (), 8, (const guchar*)&_plugin_preset_pointer, sizeof (PluginPresetPtr));
return true;
}

View File

@ -27,6 +27,7 @@
#include <gtkmm/label.h>
#include <gtkmm/entry.h>
#include <gtkmm/box.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/togglebutton.h>
#include <gtkmm/button.h>
#include <gtkmm/arrow.h>
@ -36,34 +37,100 @@
#include <gtkmm/separator.h>
#include <gtkmm/spinbutton.h>
#include <gtkmm/listviewtext.h>
#include <gtkmm/scrolledwindow.h>
#include "gtkmm2ext/dndtreeview.h"
#include "gtkmm2ext/dndvbox.h"
#include "pbd/signals.h"
#include "audio_clock.h"
#include "ardour_dialog.h"
#include "plugin_interest.h"
#include "region_editor.h"
namespace ARDOUR {
class Region;
class Session;
class RegionFxPlugin;
}
class RegionView;
class ClockGroup;
class RegionEditor : public ArdourDialog
{
public:
RegionEditor (ARDOUR::Session*, std::shared_ptr<ARDOUR::Region>);
RegionEditor (ARDOUR::Session*, RegionView*);
virtual ~RegionEditor ();
protected:
virtual void region_changed (const PBD::PropertyChange&);
virtual void region_fx_changed ();
Gtk::Table _table;
int _table_row;
private:
class RegionFxEntry : public Gtkmm2ext::DnDVBoxChild, public sigc::trackable
{
public:
RegionFxEntry (std::shared_ptr<ARDOUR::RegionFxPlugin>);
Gtk::EventBox& action_widget () { return _fx_btn; }
Gtk::Widget& widget () { return _box; }
std::string drag_text () const { return name (); }
bool is_selectable() const { return true; }
bool can_copy_state (Gtkmm2ext::DnDVBoxChild*) const;
void set_visual_state (Gtkmm2ext::VisualState, bool);
bool drag_data_get (Glib::RefPtr<Gdk::DragContext> const, Gtk::SelectionData &);
std::shared_ptr<ARDOUR::RegionFxPlugin> region_fx_plugin () const { return _rfx; }
private:
std::string name () const;
Gtk::VBox _box;
ArdourWidgets::ArdourButton _fx_btn;
std::shared_ptr<ARDOUR::RegionFxPlugin> _rfx;
ARDOUR::PluginPresetPtr _plugin_preset_pointer;
};
class RegionFxBox : public Gtk::VBox, public PluginInterestedObject //, public ARDOUR::SessionHandlePtr
{
public:
RegionFxBox (std::shared_ptr<ARDOUR::Region>);
void redisplay_plugins ();
private:
void add_fx_to_display (std::weak_ptr<ARDOUR::RegionFxPlugin>);
void show_plugin_gui (std::weak_ptr<ARDOUR::RegionFxPlugin>, bool custom_ui = true);
void queue_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin>);
bool idle_delete_region_fx (std::weak_ptr<ARDOUR::RegionFxPlugin>);
void notify_plugin_load_fail (uint32_t cnt = 1);
bool on_key_press (GdkEventKey*);
/* PluginInterestedObject */
bool use_plugins (SelectedPlugins const&);
/* DNDVbox signal handlers */
bool fxe_button_press_event (GdkEventButton*, RegionFxEntry*);
bool fxe_button_release_event (GdkEventButton*, RegionFxEntry*);
void reordered ();
void plugin_drop (Gtk::SelectionData const&, RegionFxEntry*, Glib::RefPtr<Gdk::DragContext> const&);
void object_drop (Gtkmm2ext::DnDVBox<RegionFxEntry>*, RegionFxEntry*, Glib::RefPtr<Gdk::DragContext> const&);
void delete_dragged_plugins (std::list<std::shared_ptr<ARDOUR::RegionFxPlugin>> const&);
std::shared_ptr<ARDOUR::RegionFxPlugin> find_drop_position (RegionFxEntry*);
std::shared_ptr<ARDOUR::Region> _region;
Gtkmm2ext::DnDVBox<RegionFxEntry> _display;
Gtk::ScrolledWindow _scroller;
Gtk::EventBox _base;
bool _no_redisplay;
int _placement;
};
std::shared_ptr<ARDOUR::Region> _region;
void connect_editor_events ();
@ -78,6 +145,7 @@ private:
Gtk::Label sync_relative_label;
Gtk::Label sync_absolute_label;
Gtk::Label start_label;
Gtk::Label region_fx_label;
ClockGroup* _clock_group;
@ -88,8 +156,11 @@ private:
AudioClock sync_offset_absolute_clock; ///< sync offset relative to the start of the timeline
AudioClock start_clock;
RegionFxBox _region_fx_box;
PBD::ScopedConnection state_connection;
PBD::ScopedConnection audition_connection;
PBD::ScopedConnection region_connection;
void bounds_changed (const PBD::PropertyChange&);
void name_changed ();

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
*
* 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 "ardour/automation_control.h"
#include "audio_region_view.h"
#include "gui_thread.h"
#include "region_fx_line.h"
#include "pbd/i18n.h"
using namespace ARDOUR;
RegionFxLine::RegionFxLine (std::string const& name, RegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<AutomationList> l, ParameterDescriptor const& d)
: AutomationLine (name, r.get_time_axis_view(), parent, l, d)
, _rv (r)
{
init ();
}
RegionFxLine::RegionFxLine (std::string const& name, RegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationControl> ac)
: AutomationLine (name, r.get_time_axis_view(), parent, ac->alist (), ac->desc ())
, _rv (r)
, _ac (ac)
{
init ();
}
void
RegionFxLine::init ()
{
_rv.region()->PropertyChanged.connect (_region_changed_connection, invalidator (*this), boost::bind (&RegionFxLine::region_changed, this, _1), gui_context());
group->raise_to_top ();
group->set_y_position (2);
}
Temporal::timepos_t
RegionFxLine::get_origin() const
{
return _rv.region()->position();
}
void
RegionFxLine::enable_autoation ()
{
std::shared_ptr<AutomationControl> ac = _ac.lock ();
if (ac) {
ac->set_automation_state (Play);
}
}
void
RegionFxLine::end_drag (bool with_push, uint32_t final_index)
{
enable_autoation ();
AutomationLine::end_drag (with_push, final_index);
}
void
RegionFxLine::end_draw_merge ()
{
enable_autoation ();
AutomationLine::end_draw_merge ();
}
void
RegionFxLine::region_changed (PBD::PropertyChange const& what_changed)
{
PBD::PropertyChange interesting_stuff;
interesting_stuff.add (ARDOUR::Properties::start);
interesting_stuff.add (ARDOUR::Properties::length);
if (what_changed.contains (interesting_stuff)) {
reset ();
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2024 Robin Gareus <robin@gareus.org>
*
* 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 __ardour_gtk_region_fx_line_h__
#define __ardour_gtk_region_fx_line_h__
#include "automation_line.h"
class RegionView;
class RegionFxLine : public AutomationLine
{
public:
RegionFxLine (std::string const&, RegionView&, ArdourCanvas::Container&, std::shared_ptr<ARDOUR::AutomationList>, ARDOUR::ParameterDescriptor const&);
RegionFxLine (std::string const&, RegionView&, ArdourCanvas::Container&, std::shared_ptr<ARDOUR::AutomationControl>);
Temporal::timepos_t get_origin() const;
RegionView& region_view () { return _rv; }
void end_drag (bool with_push, uint32_t final_index);
void end_draw_merge ();
virtual void enable_autoation ();
private:
void init ();
void region_changed (PBD::PropertyChange const&);
RegionView& _rv;
std::weak_ptr<ARDOUR::AutomationControl> _ac;
PBD::ScopedConnection _region_changed_connection;
};
#endif

View File

@ -35,45 +35,52 @@
#include "time_axis_view.h"
#include "editor.h"
#include "gui_thread.h"
#include "pbd/i18n.h"
using namespace std;
using namespace ARDOUR;
using namespace PBD;
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, std::shared_ptr<AutomationList> l)
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter())
, rv (r)
: RegionFxLine (name, r, parent, l, l->parameter ())
, arv (r)
{
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
assert(l->parameter().type() == EnvelopeAutomation);
r.region()->PropertyChanged.connect (_region_changed_connection, invalidator (*this), boost::bind (&AudioRegionGainLine::region_changed, this, _1), gui_context());
group->raise_to_top ();
group->set_y_position (2);
terminal_points_can_slide = false;
}
timepos_t
AudioRegionGainLine::get_origin() const
{
return rv.region()->position();
}
void
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
{
AutomationLine::start_drag_single (cp, x, fraction);
RegionFxLine::start_drag_single (cp, x, fraction);
// XXX Stateful need to capture automation curve data
if (!rv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), &rv.audio_region()->get_state(), 0));
rv.audio_region()->set_envelope_active(false);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
void
AudioRegionGainLine::start_drag_line (uint32_t i1, uint32_t i2, float fraction)
{
RegionFxLine::start_drag_line (i1, i2, fraction);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
void
AudioRegionGainLine::start_drag_multiple (list<ControlPoint*> cp, float fraction, XMLNode* state)
{
RegionFxLine::start_drag_multiple (cp, fraction, state);
if (!arv.audio_region()->envelope_active()) {
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &arv.audio_region()->get_state(), 0));
arv.audio_region()->set_envelope_active(false);
}
}
@ -84,10 +91,10 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
if (!rv.audio_region()->envelope_active()) {
rv.audio_region()->clear_changes ();
rv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new StatefulDiffCommand (rv.audio_region()));
if (!arv.audio_region()->envelope_active()) {
arv.audio_region()->clear_changes ();
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new PBD::StatefulDiffCommand (arv.audio_region()));
}
trackview.editor ().get_selection ().clear_points ();
@ -101,23 +108,27 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
void
AudioRegionGainLine::end_drag (bool with_push, uint32_t final_index)
{
if (!rv.audio_region()->envelope_active()) {
rv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(rv.audio_region().get()), 0, &rv.audio_region()->get_state()));
if (!arv.audio_region()->envelope_active()) {
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), 0, &arv.audio_region()->get_state()));
}
AutomationLine::end_drag (with_push, final_index);
RegionFxLine::end_drag (with_push, final_index);
}
void
AudioRegionGainLine::region_changed (const PropertyChange& what_changed)
AudioRegionGainLine::end_draw_merge ()
{
PropertyChange interesting_stuff;
enable_autoation ();
RegionFxLine::end_draw_merge ();
}
interesting_stuff.add (ARDOUR::Properties::start);
interesting_stuff.add (ARDOUR::Properties::length);
if (what_changed.contains (interesting_stuff)) {
reset ();
void
AudioRegionGainLine::enable_autoation ()
{
if (!arv.audio_region()->envelope_active()) {
XMLNode& before = arv.audio_region()->get_state();
arv.audio_region()->set_envelope_active(true);
trackview.session()->add_command(new MementoCommand<AudioRegion>(*(arv.audio_region().get()), &before, &arv.audio_region()->get_state()));
}
}

View File

@ -27,8 +27,7 @@
#include "ardour/ardour.h"
#include "automation_line.h"
#include "region_fx_line.h"
namespace ARDOUR {
class Session;
@ -37,23 +36,21 @@ namespace ARDOUR {
class TimeAxisView;
class AudioRegionView;
class AudioRegionGainLine : public AutomationLine
class AudioRegionGainLine : public RegionFxLine
{
public:
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, std::shared_ptr<ARDOUR::AutomationList>);
Temporal::timepos_t get_origin() const;
void start_drag_single (ControlPoint*, double, float);
void start_drag_line (uint32_t, uint32_t, float);
void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode*);
void end_drag (bool with_push, uint32_t final_index);
void end_draw_merge ();
void enable_autoation ();
void remove_point (ControlPoint&);
AudioRegionView& region_view () { return rv; }
private:
PBD::ScopedConnection _region_changed_connection;
void region_changed (const PBD::PropertyChange& what_changed);
AudioRegionView& rv;
AudioRegionView& arv;
};
#endif /* __ardour_gtk_region_gain_line_h__ */

View File

@ -237,6 +237,7 @@ RegionView::init (bool wfd)
//set_height (trackview.current_height());
_region->PropertyChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_changed, this, _1), gui_context());
_region->RegionFxChanged.connect (*this, invalidator (*this), boost::bind (&RegionView::region_renamed, this), gui_context());
/* derived class calls set_colors () including RegionView::set_colors() in ::init() */
//set_colors ();
@ -749,7 +750,7 @@ void
RegionView::show_region_editor ()
{
if (!editor) {
editor = new RegionEditor (trackview.session(), region());
editor = new RegionEditor (trackview.session(), this);
}
editor->present ();
@ -791,6 +792,9 @@ RegionView::make_name () const
if (_region->muted()) {
str = std::string(u8"\U0001F507") + str; // SPEAKER WITH CANCELLATION STROKE
}
if (_region->has_region_fx()) {
str = str + " (Fx)";
}
return str;
}

View File

@ -172,9 +172,10 @@ RouteProcessorSelection::set (AxisView* r)
if (!shp.session()) {
return;
}
PresentationInfo::ChangeSuspender cs;
shp.session()->selection().clear_stripables ();
add (r, true);
StripableList sl;
sl.push_back (r->stripable());
shp.session()->selection().set (sl);
}
bool

View File

@ -1176,11 +1176,11 @@ Selection::get_state () const
continue;
}
AudioRegionGainLine* argl = dynamic_cast<AudioRegionGainLine*> (&(*i)->line());
if (argl) {
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> (&(*i)->line());
if (fxl) {
XMLNode* r = node->add_child (X_("ControlPoint"));
r->set_property (X_("type"), "region");
r->set_property (X_("region-id"), argl->region_view ().region ()->id ());
r->set_property (X_("region-id"), fxl->region_view ().region ()->id ());
r->set_property (X_("view-index"), (*i)->view_index());
}
@ -1324,35 +1324,6 @@ Selection::set_state (XMLNode const & node, int)
if (!cps.empty()) {
add (cps);
}
} else if (prop_type->value () == "region") {
PBD::ID region_id;
uint32_t view_index;
if (!(*i)->get_property (X_("region-id"), region_id) ||
!(*i)->get_property (X_("view-index"), view_index)) {
continue;
}
RegionSelection rs;
editor->get_regionviews_by_id (region_id, rs);
if (!rs.empty ()) {
vector <ControlPoint *> cps;
for (RegionSelection::iterator rsi = rs.begin(); rsi != rs.end(); ++rsi) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*rsi);
if (arv) {
std::shared_ptr<AudioRegionGainLine> gl = arv->get_gain_line ();
ControlPoint* cp = gl->nth(view_index);
if (cp) {
cps.push_back (cp);
cp->show();
}
}
}
if (!cps.empty()) {
add (cps);
}
}
}
} else if ((*i)->name() == X_("TimelineRange")) {

View File

@ -286,8 +286,10 @@ SoundFileBox::set_session(Session* s)
auditioner_connections.drop_connections();
} else {
auditioner_connections.drop_connections();
_session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
_session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
if (_session->the_auditioner()) {
_session->AuditionActive.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_active, this, _1), gui_context());
_session->the_auditioner()->AuditionProgress.connect(auditioner_connections, invalidator (*this), boost::bind (&SoundFileBox::audition_progress, this, _1, _2), gui_context());
}
}
}
@ -310,15 +312,19 @@ SoundFileBox::audition_progress(ARDOUR::samplecnt_t pos, ARDOUR::samplecnt_t len
}
bool
SoundFileBox::seek_button_press(GdkEventButton*) {
SoundFileBox::seek_button_press (GdkEventButton*)
{
_seeking = true;
return false; // pass on to slider
}
bool
SoundFileBox::seek_button_release(GdkEventButton*) {
SoundFileBox::seek_button_release (GdkEventButton*)
{
_seeking = false;
_session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
if (_session->the_auditioner()) {
_session->the_auditioner()->seek_to_percent(seek_slider.get_value() / 10.0);
}
seek_slider.set_sensitive (false);
return false; // pass on to slider
}
@ -991,18 +997,20 @@ SoundFileBrowser::add_gain_meter ()
{
delete gm;
gm = new GainMeter (_session, 250);
std::shared_ptr<Route> r = _session->the_auditioner ();
gm->set_controls (r, r->shared_peak_meter(), r->amp(), r->gain_control());
gm->set_fader_name (X_("GainFader"));
if (r) {
gm = new GainMeter (_session, 250);
meter_packer.set_border_width (12);
meter_packer.pack_start (*gm, false, true);
hpacker.pack_end (meter_packer, false, false);
meter_packer.show_all ();
start_metering ();
gm->set_controls (r, r->shared_peak_meter(), r->amp(), r->gain_control());
gm->set_fader_name (X_("GainFader"));
meter_packer.set_border_width (12);
meter_packer.pack_start (*gm, false, true);
hpacker.pack_end (meter_packer, false, false);
meter_packer.show_all ();
start_metering ();
}
}
void
@ -2126,7 +2134,9 @@ SoundFileOmega::where_combo_changed()
void
SoundFileOmega::instrument_combo_changed()
{
_session->the_auditioner()->set_audition_synth_info( instrument_combo.selected_instrument() );
if (_session->the_auditioner()) {
_session->the_auditioner()->set_audition_synth_info( instrument_combo.selected_instrument() );
}
}
MidiTrackNameSource

View File

@ -345,7 +345,7 @@ SimpleExportDialog::start_export ()
if (_post_export_combo.get_active_row_number () == 0) {
PBD::open_folder (folder ());
}
if (!ARDOUR::Profile->get_mixbus ()) {
if (!ARDOUR::Profile->get_mixbus () && !ARDOUR::Profile->get_livetrax ()) {
NagScreen* ns = NagScreen::maybe_nag (_("Export"));
if (ns) {
ns->nag ();

View File

@ -44,11 +44,6 @@ namespace ARDOUR {
class Location;
}
namespace ArdourWidgets {
class ArdourButton;
class HSliderController;
}
class TriggerPropertiesBox;
class RegionPropertiesBox;
class RegionOperationsBox;

View File

@ -622,7 +622,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
|| (!within && (*i)->region()->coverage (start, end) != Temporal::OverlapNone)) {
if (_trackview.editor().internal_editing()) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
if (arv && arv->get_gain_line ()) {
if (arv && arv->fx_line ()) {
/* Note: AutomationLine::get_selectables() uses trackview.current_height (),
* disregarding Stacked layer display height
*/
@ -630,7 +630,7 @@ StreamView::get_selectables (timepos_t const & start, timepos_t const & end, dou
double const y = (*i)->get_canvas_group ()->position().y;
double t = 1.0 - std::min (1.0, std::max (0., (top - _trackview.y_position () - y) / c));
double b = 1.0 - std::min (1.0, std::max (0., (bottom - _trackview.y_position () - y) / c));
arv->get_gain_line()->get_selectables (start, end, b, t, results);
arv->fx_line()->get_selectables (start, end, b, t, results);
}
} else {
results.push_back (*i);

View File

@ -365,6 +365,7 @@
<ColorAlias name="recording rect" alias="alert:ruddy"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:foregroundest"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -356,6 +356,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -320,7 +320,7 @@
<ColorAlias name="pluginui toggle: fill" alias="widget:bg"/>
<ColorAlias name="pluginui toggle: fill active" alias="widget:blue"/>
<ColorAlias name="preference highlight" alias="alert:yellow"/>
<ColorAlias name="processor automation line" alias="theme:bg1"/>
<ColorAlias name="processor automation line" alias="alert:green"/>
<ColorAlias name="processor auxfeedback: fill" alias="theme:contrasting alt"/>
<ColorAlias name="processor auxfeedback: led active" alias="alert:green"/>
<ColorAlias name="processor control button: fill" alias="neutral:background"/>
@ -359,6 +359,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -358,6 +358,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -358,6 +358,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -356,6 +356,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:background2"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -357,6 +357,7 @@
<ColorAlias name="recording note" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform fill" alias="neutral:foregroundest"/>
<ColorAlias name="recording waveform outline" alias="neutral:foregroundest"/>
<ColorAlias name="region automation line" alias="alert:blue"/>
<ColorAlias name="region list automatic" alias="theme:contrasting less"/>
<ColorAlias name="region list missing source" alias="alert:red"/>
<ColorAlias name="region list whole file" alias="neutral:foreground"/>

View File

@ -438,7 +438,13 @@ TimeAxisView::controls_ebox_button_press (GdkEventButton* event)
_ebox_release_can_act = true;
if (maybe_set_cursor (event->y) > 0) {
_resize_drag_start = event->y_root;
} else {
if (event->button == 1) {
_editor.start_track_drag (*this, event->y, controls_ebox);
}
}
return true;
@ -453,6 +459,12 @@ TimeAxisView::idle_resize (int32_t h)
bool
TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
{
if (_editor.track_dragging()) {
_editor.mid_track_drag (ev, controls_ebox);
gdk_event_request_motions (ev);
return true;
}
if (_resize_drag_start >= 0) {
/* (ab)use the DragManager to do autoscrolling - basically we
@ -468,13 +480,15 @@ TimeAxisView::controls_ebox_motion (GdkEventMotion* ev)
_editor.add_to_idle_resize (this, delta);
_resize_drag_start = ev->y_root;
_did_resize = true;
gdk_event_request_motions (ev);
return true;
} else {
/* not dragging but ... */
maybe_set_cursor (ev->y);
}
gdk_event_request_motions(ev);
return true;
gdk_event_request_motions (ev);
return false;
}
bool
@ -518,23 +532,27 @@ TimeAxisView::maybe_set_cursor (int y)
bool
TimeAxisView::controls_ebox_button_release (GdkEventButton* ev)
{
if (_resize_drag_start >= 0) {
if (_have_preresize_cursor) {
gdk_window_set_cursor (controls_ebox.get_window()->gobj(), _preresize_cursor);
_preresize_cursor = 0;
_have_preresize_cursor = false;
}
_editor.stop_canvas_autoscroll ();
_resize_drag_start = -1;
if (_did_resize) {
_did_resize = false;
// don't change selection
return true;
}
if (_editor.track_dragging()) {
_editor.end_track_drag ();
} else {
if (_resize_drag_start >= 0) {
if (_have_preresize_cursor) {
gdk_window_set_cursor (controls_ebox.get_window()->gobj(), _preresize_cursor);
_preresize_cursor = 0;
_have_preresize_cursor = false;
}
_editor.stop_canvas_autoscroll ();
_resize_drag_start = -1;
if (_did_resize) {
_did_resize = false;
// don't change selection
return true;
}
}
if (!_ebox_release_can_act) {
return true;
if (!_ebox_release_can_act) {
return true;
}
}
switch (ev->button) {

View File

@ -124,7 +124,9 @@ TransportMastersWidget::~TransportMastersWidget ()
void
TransportMastersWidget::set_transport_master (std::shared_ptr<TransportMaster> tm)
{
_session->request_sync_source (tm);
if (_session) {
_session->request_sync_source (tm);
}
}
void

View File

@ -20,13 +20,13 @@
#define __ardour_gtk_trigger_ui_h__
#include "gtkmm/colorselection.h"
#include "gtkmm/entry.h"
#include "gtkmm2ext/actions.h"
#include "gtkmm2ext/bindings.h"
#include "ardour/triggerbox.h"
#include "widgets/ardour_button.h"
#include "widgets/slider_controller.h"
#include "widgets/frame.h"
namespace Gtk

View File

@ -26,6 +26,8 @@
#include "ardour/session.h"
#include "gtkmm2ext/utils.h"
#include "widgets/slider_controller.h"
#include "widgets/tooltips.h"
#include "ardour_ui.h"

View File

@ -30,7 +30,6 @@
#include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
#include "widgets/ardour_knob.h"
#include "widgets/slider_controller.h"
#include "ardour_window.h"
#include "pianokeyboard.h"
@ -39,6 +38,10 @@ namespace ARDOUR {
class Session;
}
namespace ArdourWidgets {
class VSliderController;
}
class VKBDControl : public PBD::Controllable
{
public:

View File

@ -219,6 +219,7 @@ gtk2_ardour_sources = [
'plugin_ui.cc',
'plugin_dspload_ui.cc',
'plugin_dspload_window.cc',
'plugin_window_proxy.cc',
'port_group.cc',
'port_insert_ui.cc',
'port_matrix.cc',
@ -240,6 +241,7 @@ gtk2_ardour_sources = [
'recorder_group_tabs.cc',
'recorder_ui.cc',
'region_editor.cc',
'region_fx_line.cc',
'region_gain_line.cc',
'region_layering_order_editor.cc',
'region_list_base.cc',
@ -857,17 +859,19 @@ def build(bld):
# always build all versions of the menu definitions
# so that we can try them out with different program builds.
for program in [ 'ardour']:
obj = bld(features = 'command-output')
obj.command = 'cpp'
obj.command_is_external = True
obj.no_inputs = True
obj.argv = menus_argv
obj.dep_vars = ['PTFORMAT', 'MIXBUS', 'WINDOWS', 'debug']
obj.stdin = program + '.menus.in'
obj.stdout = program + '.menus'
bld.install_files (bld.env['CONFDIR'], program + '.menus')
obj = bld(features = 'command-output')
obj.command = 'cpp'
obj.command_is_external = True
obj.no_inputs = True
obj.argv = menus_argv
obj.dep_vars = ['PTFORMAT', 'MIXBUS', 'WINDOWS', 'debug']
if bld.is_defined('LIVETRAX'):
obj.stdin = 'livetrax.menus.in'
else:
obj.stdin = 'ardour.menus.in'
obj.stdout = 'ardour.menus'
bld.install_files (bld.env['CONFDIR'], 'ardour.menus')
# Freedesktop
freedesktop_subst_dict = {

View File

@ -1951,8 +1951,8 @@ retrieveProperty (AAF_Data* aafd, aafObject* Obj, aafPropertyDef* Def, aafProper
Prop->sf = p->_storedForm;
/*
TODO Prop->len / Prop->val ---> retrieveStrongReference() retrieveStrongReferenceSet() retrieveStrongReferenceVector()
only used to retrieve node name ? There could be a better approach.
TODO Prop->len / Prop->val ---> retrieveStrongReference() retrieveStrongReferenceSet() retrieveStrongReferenceVector()
only used to retrieve node name ? There could be a better approach.
*/
Prop->len = p->_length;
@ -2127,18 +2127,18 @@ getNodeProperties (AAF_Data* aafd, cfbNode* Node)
*/
/*
uint32_t prop_sz = sizeof(aafPropertyIndexHeader_t);
uint32_t prop_sz = sizeof(aafPropertyIndexHeader_t);
uint32_t i = 0;
uint32_t i = 0;
for ( i = 0; i < ((aafPropertyIndexHeader_t*)stream)->_entryCount; i++ )
prop_sz += (((aafPropertyIndexEntry_t*)(stream+((sizeof(aafPropertyIndexEntry_t)*i)+sizeof(aafPropertyIndexHeader_t))))->_length) + sizeof(aafPropertyIndexEntry_t);
for ( i = 0; i < ((aafPropertyIndexHeader_t*)stream)->_entryCount; i++ )
prop_sz += (((aafPropertyIndexEntry_t*)(stream+((sizeof(aafPropertyIndexEntry_t)*i)+sizeof(aafPropertyIndexHeader_t))))->_length) + sizeof(aafPropertyIndexEntry_t);
if ( prop_sz != stream_sz )
warning( L"Stream length (%lu Bytes) does not match property length (%u Bytes).",
stream_sz,
prop_sz );
*/
if ( prop_sz != stream_sz )
warning( L"Stream length (%lu Bytes) does not match property length (%u Bytes).",
stream_sz,
prop_sz );
*/
return stream;
}

View File

@ -131,7 +131,7 @@ aaf_dump_TaggedValueSet (AAF_Data* aafd, aafObject* ObjCollection, const char* p
ANSI_COLOR_DARKGREY (log),
(name) ? name : "<unknown>",
ANSI_COLOR_RESET (log),
(name) ? (size_t) (34 - (int)strlen (name)) : (size_t) (34 - strlen ("<unknown>")), " ",
(name) ? (size_t)(34 - (int)strlen (name)) : (size_t)(34 - strlen ("<unknown>")), " ",
ANSI_COLOR_DARKGREY (log),
aaft_TypeIDToText (&indirect->TypeDef),
ANSI_COLOR_RESET (log),

View File

@ -888,3 +888,44 @@ externalAudioDataReaderCallback (unsigned char* buf, size_t offset, size_t reqle
return byteRead;
}
aafiAudioEssencePointer*
aafi_audioEssencePointer_exists_before (AAF_Iface* aafi, aafiAudioEssencePointer* audioEssencePointerList)
{
aafiAudioTrack* at = NULL;
aafiTimelineItem* ai = NULL;
aafiAudioClip* ac = NULL;
aafiAudioEssencePointer* aep1 = NULL;
aafiAudioEssencePointer* aep2 = NULL;
AAFI_foreachAudioTrack (aafi, at)
{
AAFI_foreachTrackItem (at, ai)
{
if (ai->type != AAFI_AUDIO_CLIP) {
continue;
}
ac = (aafiAudioClip*)ai->data;
aep1 = audioEssencePointerList;
int found = 1;
AAFI_foreachEssencePointer (ac->essencePointerList, aep2)
{
if (!aep1 || aep1->essenceFile != aep2->essenceFile || aep1->essenceChannel != aep2->essenceChannel) {
found = 0;
break;
}
aep1 = aep1->next;
}
if (found && aep1 == NULL) {
return ac->essencePointerList;
}
}
}
return NULL;
}

View File

@ -3166,12 +3166,23 @@ aafi_retrieveData (AAF_Iface* aafi)
AAFI_foreachTrackItem (audioTrack, audioItem)
{
if (audioItem->type == AAFI_TRANS) {
if (audioItem->type != AAFI_AUDIO_CLIP) {
continue;
}
audioClip = (aafiAudioClip*)audioItem->data;
audioClip->channels = aafi_getAudioEssencePointerChannelCount (audioClip->essencePointerList);
/*
* we check if any previous clip is using the exact same essence pointer,
* to avoid duplication and allow to detect when multiple clips are using
* the same essence.
*/
aafiAudioEssencePointer* prev = aafi_audioEssencePointer_exists_before (aafi, audioClip->essencePointerList);
if (prev) {
audioClip->essencePointerList = prev;
}
}
}

View File

@ -214,6 +214,12 @@ aafi_release (AAF_Iface** aafi)
aafi_freeAudioTracks (&(*aafi)->Audio->Tracks);
aafi_freeAudioEssences (&(*aafi)->Audio->essenceFiles);
aafiAudioEssencePointer* essencePointer = (*aafi)->Audio->essencePointerList;
while (essencePointer) {
essencePointer = aafi_freeAudioEssencePointer (essencePointer);
}
free ((*aafi)->Audio);
}
@ -358,7 +364,7 @@ aafi_convertUnit (aafPosition_t value, aafRational_t* valueEditRate, aafRational
return 0;
}
return (aafPosition_t) ((double)value * (destEditRateFloat / valueEditRateFloat));
return (aafPosition_t)((double)value * (destEditRateFloat / valueEditRateFloat));
}
uint64_t
@ -391,7 +397,7 @@ aafi_convertUnitUint64 (aafPosition_t value, aafRational_t* valueEditRate, aafRa
return 0;
}
return (uint64_t) ((double)value * (destEditRateFloat / valueEditRateFloat));
return (uint64_t)((double)value * (destEditRateFloat / valueEditRateFloat));
}
int
@ -506,8 +512,8 @@ aafi_applyGainOffset (AAF_Iface* aafi, aafiAudioGain** gain, aafiAudioGain* offs
* is the same accross all gains in file. Thus, we devide both gain numbers
* by offset denominator, so we fit inside uint32_t.
*/
(*gain)->value[i].numerator = (int32_t) (((int64_t) (*gain)->value[i].numerator * (int64_t)offset->value[0].numerator) / (int64_t)offset->value[0].denominator);
(*gain)->value[i].denominator = (int32_t) (((int64_t) (*gain)->value[i].denominator * (int64_t)offset->value[0].denominator) / (int64_t)offset->value[0].denominator);
(*gain)->value[i].numerator = (int32_t)(((int64_t)(*gain)->value[i].numerator * (int64_t)offset->value[0].numerator) / (int64_t)offset->value[0].denominator);
(*gain)->value[i].denominator = (int32_t)(((int64_t)(*gain)->value[i].denominator * (int64_t)offset->value[0].denominator) / (int64_t)offset->value[0].denominator);
// debug( "Setting (*gain)->value[%i] = %i/%i * %i/%i",
// i,
// (*gain)->value[i].numerator,
@ -798,11 +804,11 @@ aafi_newAudioEssencePointer (AAF_Iface* aafi, aafiAudioEssencePointer** list, aa
last->next = essencePointer;
} else {
*list = essencePointer;
essencePointer->aafiNext = aafi->Audio->essencePointerList;
aafi->Audio->essencePointerList = essencePointer;
}
essencePointer->aafiNext = aafi->Audio->essencePointerList;
aafi->Audio->essencePointerList = essencePointer;
return *list;
}
@ -985,8 +991,6 @@ aafi_freeAudioClip (aafiAudioClip* audioClip)
aafi_freeAudioGain (audioClip->automation);
aafi_freeMetadata (&(audioClip->metadata));
aafi_freeAudioEssencePointer (audioClip->essencePointerList);
free (audioClip);
}
@ -1042,16 +1046,14 @@ aafi_freeMetadata (aafiMetaData** CommentList)
*CommentList = NULL;
}
void
aafiAudioEssencePointer*
aafi_freeAudioEssencePointer (aafiAudioEssencePointer* essencePointer)
{
aafiAudioEssencePointer* next = NULL;
aafiAudioEssencePointer* next = essencePointer->aafiNext;
while (essencePointer) {
next = essencePointer->next;
free (essencePointer);
essencePointer = next;
}
free (essencePointer);
return next;
}
void

View File

@ -1912,19 +1912,19 @@ aaft_PIDToText (AAF_Data* aafd, aafPID_t pid)
return "PID_BWFImportDescriptor_UnknownBWFChunks";
/* the following is marked as "dynamic" in ref implementation :
* AAF/ref-impl/include/ref-api/AAFTypes.h
*
* case PID_MPEGVideoDescriptor_SingleSequence:
* case PID_MPEGVideoDescriptor_ConstantBPictureCount:
* case PID_MPEGVideoDescriptor_CodedContentScanning:
* case PID_MPEGVideoDescriptor_LowDelay:
* case PID_MPEGVideoDescriptor_ClosedGOP:
* case PID_MPEGVideoDescriptor_IdenticalGOP:
* case PID_MPEGVideoDescriptor_MaxGOP:
* case PID_MPEGVideoDescriptor_MaxBPictureCount:
* case PID_MPEGVideoDescriptor_BitRate:
* case PID_MPEGVideoDescriptor_ProfileAndLevel:
*/
* AAF/ref-impl/include/ref-api/AAFTypes.h
*
* case PID_MPEGVideoDescriptor_SingleSequence:
* case PID_MPEGVideoDescriptor_ConstantBPictureCount:
* case PID_MPEGVideoDescriptor_CodedContentScanning:
* case PID_MPEGVideoDescriptor_LowDelay:
* case PID_MPEGVideoDescriptor_ClosedGOP:
* case PID_MPEGVideoDescriptor_IdenticalGOP:
* case PID_MPEGVideoDescriptor_MaxGOP:
* case PID_MPEGVideoDescriptor_MaxBPictureCount:
* case PID_MPEGVideoDescriptor_BitRate:
* case PID_MPEGVideoDescriptor_ProfileAndLevel:
*/
case PID_ClassDefinition_ParentClass:
return "PID_ClassDefinition_ParentClass";

View File

@ -729,7 +729,7 @@ cfb_getStream (CFB_Data* cfbd, cfbNode* node, unsigned char** stream, uint64_t*
return 0;
}
cpy_sz = ((stream_len - offset) < (uint64_t) (1 << cfbd->hdr->_uMiniSectorShift)) ? (stream_len - offset) : (uint64_t) (1 << cfbd->hdr->_uMiniSectorShift);
cpy_sz = ((stream_len - offset) < (uint64_t)(1 << cfbd->hdr->_uMiniSectorShift)) ? (stream_len - offset) : (uint64_t)(1 << cfbd->hdr->_uMiniSectorShift);
memcpy (*stream + offset, buf, cpy_sz);
@ -740,7 +740,7 @@ cfb_getStream (CFB_Data* cfbd, cfbNode* node, unsigned char** stream, uint64_t*
} else {
CFB_foreachSectorInChain (cfbd, buf, id)
{
cpy_sz = ((stream_len - offset) < (uint64_t) (1 << cfbd->hdr->_uSectorShift)) ? (stream_len - offset) : (uint64_t) (1 << cfbd->hdr->_uSectorShift);
cpy_sz = ((stream_len - offset) < (uint64_t)(1 << cfbd->hdr->_uSectorShift)) ? (stream_len - offset) : (uint64_t)(1 << cfbd->hdr->_uSectorShift);
memcpy (*stream + offset, buf, cpy_sz);
@ -1073,7 +1073,7 @@ cfb_retrieveMiniFAT (CFB_Data* cfbd)
* its ID (a.k.a SID) :
*
* ```
cfbNode *node = CFB_Data.nodes[ID];
cfbNode *node = CFB_Data.nodes[ID];
* ```
*
* @param cfbd Pointer to the CFB_Data structure.

View File

@ -92,16 +92,16 @@ typedef SSIZE_T ssize_t;
(uri->scheme_t != URI_SCHEME_T_FILE && \
!(uri->opts & URI_OPT_IGNORE_FRAGMENT))
#define URI_SET_STR(str, start, end) \
\
str = malloc (sizeof (char) * (uint32_t) ((end - start) + 1)); \
\
if (!str) { \
error ("Out of memory"); \
goto err; \
} \
\
snprintf (str, (uint32_t) (end - start) + 1, "%s", start);
#define URI_SET_STR(str, start, end) \
\
str = malloc (sizeof (char) * (uint32_t)((end - start) + 1)); \
\
if (!str) { \
error ("Out of memory"); \
goto err; \
} \
\
snprintf (str, (uint32_t)(end - start) + 1, "%s", start);
static char*
uriDecodeString (char* src, char* dst);
@ -787,7 +787,7 @@ uriIsIPv6 (const char* s, size_t size, char** err)
if (!IS_DIGIT (*(s + i))) {
loopback = -1;
} else {
loopback += (*(s + i) - '0'); //atoi(*(s+i));
loopback += (*(s + i) - '0'); // atoi(*(s+i));
}
}

View File

@ -556,19 +556,19 @@ typedef struct _aafData {
*/
#define aafUIDCmp(auid1, auid2) \
((auid1) != NULL && \
((auid2)) != NULL && \
(auid1)->Data1 == (auid2)->Data1 && \
(auid1)->Data2 == (auid2)->Data2 && \
(auid1)->Data3 == (auid2)->Data3 && \
(auid1)->Data4[0] == (auid2)->Data4[0] && \
(auid1)->Data4[1] == (auid2)->Data4[1] && \
(auid1)->Data4[2] == (auid2)->Data4[2] && \
(auid1)->Data4[3] == (auid2)->Data4[3] && \
(auid1)->Data4[4] == (auid2)->Data4[4] && \
(auid1)->Data4[5] == (auid2)->Data4[5] && \
(auid1)->Data4[6] == (auid2)->Data4[6] && \
(auid1)->Data4[7] == (auid2)->Data4[7])
((auid1) != NULL && \
(auid2) != NULL && \
(auid1)->Data1 == (auid2)->Data1 && \
(auid1)->Data2 == (auid2)->Data2 && \
(auid1)->Data3 == (auid2)->Data3 && \
(auid1)->Data4[0] == (auid2)->Data4[0] && \
(auid1)->Data4[1] == (auid2)->Data4[1] && \
(auid1)->Data4[2] == (auid2)->Data4[2] && \
(auid1)->Data4[3] == (auid2)->Data4[3] && \
(auid1)->Data4[4] == (auid2)->Data4[4] && \
(auid1)->Data4[5] == (auid2)->Data4[5] && \
(auid1)->Data4[6] == (auid2)->Data4[6] && \
(auid1)->Data4[7] == (auid2)->Data4[7])
/**
* Compares two aafMobID_t, returns 1 if equal or 0 otherwise.
@ -601,7 +601,7 @@ typedef struct _aafData {
*/
#define aafRationalToint64(r) \
(((r).denominator == 0) ? 0 : (int64_t) ((r).numerator / (r).denominator))
(((r).denominator == 0) ? 0 : (int64_t)((r).numerator / (r).denominator))
/**
* Loops through each aafPropertyIndexEntry_t of a "properties" node stream.

View File

@ -55,6 +55,9 @@ aafi_parse_audio_essence (AAF_Iface* aafi, aafiAudioEssenceFile* audioEssenceFil
int
aafi_build_unique_audio_essence_name (AAF_Iface* aafi, aafiAudioEssenceFile* audioEssenceFile);
aafiAudioEssencePointer*
aafi_audioEssencePointer_exists_before (AAF_Iface* aafi, aafiAudioEssencePointer* audioEssencePointerList);
/**
* @}
*/

View File

@ -468,11 +468,11 @@ typedef struct aafiAudioClip {
*/
/*
* set with CompoMob's SourceClip::StartTime. In the case of an OperationGroup(AudioChannelCombiner),
* There is one SourceClip per audio channel. So even though it's very unlikely, there could possibly
* be one essence_offset per channel.
* Value is in edit unit, edit rate definition is aafiAudioTrack->edit_rate
*/
* set with CompoMob's SourceClip::StartTime. In the case of an OperationGroup(AudioChannelCombiner),
* There is one SourceClip per audio channel. So even though it's very unlikely, there could possibly
* be one essence_offset per channel.
* Value is in edit unit, edit rate definition is aafiAudioTrack->edit_rate
*/
aafPosition_t essence_offset;
aafiMetaData* metadata;
@ -1060,7 +1060,7 @@ aafi_freeMarkers (aafiMarker** aafi);
void
aafi_freeMetadata (aafiMetaData** CommentList);
void
aafiAudioEssencePointer*
aafi_freeAudioEssencePointer (aafiAudioEssencePointer* audioEssenceGroupEntry);
void

View File

@ -57,33 +57,33 @@ typedef enum aafStoredForm_e {
typedef int32_t AAFTypeCategory_t;
typedef enum _eAAFTypeCategory_e
{
AAFTypeCatUnknown = 0, // can only occur in damaged files
AAFTypeCatInt = 1, // any integral type
AAFTypeCatCharacter = 2, // any character type
AAFTypeCatStrongObjRef = 3, // strong object reference
AAFTypeCatWeakObjRef = 4, // weak object reference
AAFTypeCatRename = 5, // renamed type
AAFTypeCatEnum = 6, // enumerated type
AAFTypeCatFixedArray = 7, // fixed-size array
AAFTypeCatVariableArray = 8, // variably-sized array
AAFTypeCatSet = 9, // set of strong object references or
// set of weak object references
AAFTypeCatRecord = 10, // a structured type
AAFTypeCatStream = 11, // potentially huge amount of data
AAFTypeCatString = 12, // null-terminated variably-sized
// array of characters
AAFTypeCatExtEnum = 13, // extendible enumerated type
AAFTypeCatIndirect = 14, // type must be determined at runtime
AAFTypeCatOpaque = 15, // type can be determined at runtime
AAFTypeCatEncrypted = 16 // type can be determined at runtime
// but bits are encrypted
AAFTypeCatUnknown = 0, // can only occur in damaged files
AAFTypeCatInt = 1, // any integral type
AAFTypeCatCharacter = 2, // any character type
AAFTypeCatStrongObjRef = 3, // strong object reference
AAFTypeCatWeakObjRef = 4, // weak object reference
AAFTypeCatRename = 5, // renamed type
AAFTypeCatEnum = 6, // enumerated type
AAFTypeCatFixedArray = 7, // fixed-size array
AAFTypeCatVariableArray = 8, // variably-sized array
AAFTypeCatSet = 9, // set of strong object references or
// set of weak object references
AAFTypeCatRecord = 10, // a structured type
AAFTypeCatStream = 11, // potentially huge amount of data
AAFTypeCatString = 12, // null-terminated variably-sized
// array of characters
AAFTypeCatExtEnum = 13, // extendible enumerated type
AAFTypeCatIndirect = 14, // type must be determined at runtime
AAFTypeCatOpaque = 15, // type can be determined at runtime
AAFTypeCatEncrypted = 16 // type can be determined at runtime
// but bits are encrypted
} AAFTypeCategory_e;
*/
/*
* :: Types Definition
* see Git nevali/aaf/ref-impl/include/ref-api/AAFTypes.h
*/
*/
typedef unsigned char aafByte_t;
@ -369,7 +369,7 @@ typedef struct _aafRGBAComponent_t {
} aafRGBAComponent_t;
//typedef aafRGBAComponent_t aafRGBALayout[8];
// typedef aafRGBAComponent_t aafRGBALayout[8];
/**
* This structure map the first bytes in a **properties** stream
@ -521,7 +521,7 @@ typedef struct aafStrongRefSetEntry_t {
* of the first aafStrongRefSetEntry_t is used to
* form the name of the first element in the set and so
* on. The #_localKey is an insertion key.
*/
*/
uint32_t _localKey;
@ -588,7 +588,7 @@ typedef struct aafStrongRefVectorEntry_t {
* of the first aafStrongRefVectorEntry_t is used to
* form the name of the first element in the vector and so
* on. The #_localKey is an insertion key.
*/
*/
uint32_t _localKey;
@ -679,15 +679,15 @@ typedef struct _WeakReferenceIndexHeader {
/*
typedef struct _aafIndirect_t
{
int type;
size_t size;
aafByte_t *data;
int type;
size_t size;
aafByte_t *data;
} aafIndirect_t;
typedef struct _AAF_TaggedValueClass
{
aafString_t Name;
aafIndirect_t Value;
aafString_t Name;
aafIndirect_t Value;
} AAF_ObjTaggedValue;
*/

Some files were not shown because too many files have changed in this diff Show More