Age | Commit message (Collapse) | Author |
|
|
|
This does not merge MIDI data, but trims MIDI regions at rec-stop like
non-layered audio-recording does.
|
|
There are no float <=> string conversions in MidiDiskstream state methods,
these guards must have been to protect conversions in Diskstream state methods
which are now using PBD::to_string/string_to via XMLNode so no longer need
guarding.
|
|
|
|
|
|
* Start recording at preroll, trim region to skip preroll at rec-stop
* Keep old punch-in rec-at-preroll API for tape-tracks (later)
|
|
* rename: indicate that recording happens after preroll, punch-in
* move API into libardour: rec+roll (no separate setup, seek, roll APIs)
|
|
|
|
|
|
I'm not sure if this is really the best way to do event types (should it
just be a completely static enum in evoral, or completely dynamic and
provided by the type map, or a mix like currently?), but previously the
event type was frequently set to either total garbage, or parameter
types, which are a different thing.
This fixes all those cases, and makes Evoral::EventType an enum so the
compiler will warn about implicit conversions from int.
|
|
It is slightly questionable whether type specific methods like
velocity() belong on Event at all, these may be better off as free
functions. However the code currently uses them as methods in many
places, and it seems like a step in the right direction, since, for
example, we might some day have events that have a velocity but aren't
stored as MIDI messages (e.g. if Ardour uses an internal musical model
that is more expressive).
In any case, the former inheritance and plethora of sloppy casts is
definitely not the right thing.
|
|
This can occur when the MIDI readahead time is too low and events get
pushed into the MidiRingBuffer after the corresponding read. In this
case, skip_to() gets called (as it does before every read) and the
events are silently dropped.
This is a Very Bad Thing(TM), so warn about it. I am not sure which
other scenarios can skip events that aren't problematic, but there's
probably some. A more sophisticated detection/reporting (or maybe even
dynamic reconfiguration) scheme would be nice here, but some false
positive messages are at least better than silently failing to play
notes and the like.
|
|
- Evoral::Beats operator!= would prevent an increment
of start_beats by intervals of less than a tick,
so its possible that other subtle problems
existed due to this kind of thing.
|
|
seamless looping (if using)
|
|
playback buffer, and do not use port offset to shift data in time either (it should be correct)
|
|
|
|
|
|
|
|
well, now...
- Midi-Ports have a midi-buffer.
- Midi-Tracks have a midi-buffer.
- Midi-tracks have a diskstream.
- Midi-diskstream has a midi-ring-buffer.
- Midi-tracks have a delivery
- The delivery can get a reference to the actual backend-ports
- The delivery calls the Midi-Port's flush() buffer to send out queued events
at the end of a cycle
all clear ? :)
- when splitting the process-cycle: only the Ports are informed.
all other objects see a "normal" short process cycle starting at "0".
The offset needs to be applied early on, so that internally routed buffers
push the event at the correct time when combining the buffer with
immediate and async events.
Luckily Port::port_offset() is a static member, available to all, objects,
which allows to bridge the conceptual gap between the diskstream and
the delivery.
There's a snag:
When there's a note-on directly at the beginning of the loop it coincides
with the panic message sent when looping.
The panic comes before note events, so it *should* be good.
Also the final note-offs (state tracker end of loop/region) are sent
1 sample too early (smells like an off-by-one), and are hence dropped.
(no matter we send a panic right after it).
It should really be at the same time, just before the panic.
|
|
|
|
|
|
Paul Davis was responsible for introducing almost all of this.
|
|
When refilling playback buffer, try to fill it completely, or at least
using the next-lowest power-of-2 as the amount to read. When locating,
where we use do_refill_with_alloc(), only partially fill the buffer.
Work not yet finished, but possibly promising.
|
|
|
|
mechanism away from a 64bit integer and toward std::bitset.
Clean up a few minor related PBD::DEBUG issues along the way
|
|
This moves MIDI channel filtering into a reusable class and moves filtering to
the source, rather than modifying the buffer afterwards. This is necessary so
that the playlist trackers reflect the emitted notes (and thus are able to stop
them in situations like mute).
As a perk, this is also faster because events are just dropped on read, rather
than pushed into a buffer then later removed (which is very slow).
Really hammering on mute or solo still seems to produce stuck notes
occasionally (perhaps related to multiple-on warnings). I am not yet sure why,
but occasional beats always.
|
|
Fixes bug #6206.
|
|
|
|
|
|
this is not a fix yet, just some comments and
code cleanup done while reading/investigating:
* limit reads to available write-space
* skip inactive tracks
* handle potential unsigned + negative value.
|
|
|
|
|
|
diskstream reads directly from port, Route
use prefilled buffer-set.
|
|
reading. Write chunk size should remain unchanged from before.
|
|
operation is undefined. C works on all platforms
|
|
|
|
This is a little hard-edged in that edits while rolling will prematurely chop
off any playing notes, but at least the state of things actually reflects
reality. More sophisticated solution hopefully to come...
|
|
Attempt to make mistakes much less likely in the future by statically requiring
caller to pass scoped locks where necessary.
|
|
Comments in various call sites of Evoral::coverage() marking things I think
are dubious (with XXX). Also straightened up the alignment of some ASCII
art in libs/ardour/diskstream.cc
|
|
|
|
This is not used anywhere in Evoral and is just a wrapper around the PBD
RingBuffer anyway. Towards a (once again?) independently buildable/testable
Evoral and fewer cross-dependencies.
|
|
This lets us get a more explicit handle on time conversions, and is the main
step towards using actual beat:tick time and getting away from floating point
precision problems.
|
|
Manually resolved conflicts in import.cc and session.cc
|
|
|
|
|
|
(previously it was not reset as long as rec-arm and rec-enable
remained enabled)
|
|
For audio: not writing frames to the capture ringbuffer offsets
the recording.
For midi: we need to keep track of the record range
and subtract the accumulated difference from the event time.
|
|
sources, especially when created via import
|
|
renaming
|
|
region on demand and cloning/unlinking
Existing code would cause data loss due to creation of two Source objects referring the same path, one with removable flags and one without. Careful code review suggested a variety of thinkos, function naming problems and other confusion that caused this. I have tried ot extensively comment what is going on with these operations, because it is one key area in which MIDI differs from audio: with audio, capture is the only way to add a new audio region, but for MIDI there are GUI input events that can add a new region.
|