improvements (!) to waveform display for destructive tracks, plus a generic fix that avoid waveview attemting to read peaks before they are ready
git-svn-id: svn://localhost/trunk/ardour2@388 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
1a52aeb370
commit
af70789773
|
@ -391,12 +391,12 @@ gnome_canvas_waveview_ensure_cache (GnomeCanvasWaveView *waveview, gulong start_
|
|||
|
||||
/* but make sure it doesn't extend beyond the end of the source material */
|
||||
|
||||
rf3 = (gulong) (waveview->sourcefile_length_function (waveview->data_src)) + 1;
|
||||
rf3 = (gulong) (waveview->sourcefile_length_function (waveview->data_src, waveview->samples_per_unit)) + 1;
|
||||
rf3 -= new_cache_start;
|
||||
|
||||
#if DEBUG_CACHE
|
||||
fprintf (stderr, "\n\nAVAILABLE FRAMES = %lu of %lu, start = %lu, sstart = %lu, cstart = %lu\n",
|
||||
rf3, waveview->sourcefile_length_function (waveview->data_src),
|
||||
rf3, waveview->sourcefile_length_function (waveview->data_src, waveview->samples_per_unit),
|
||||
waveview->region_start, start_sample, new_cache_start);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ struct _GnomeCanvasWaveView
|
|||
guint32 channel;
|
||||
void (*peak_function)(void*,gulong,gulong,gulong,gpointer,guint32,double);
|
||||
gulong (*length_function)(void *);
|
||||
gulong (*sourcefile_length_function)(void*);
|
||||
gulong (*sourcefile_length_function)(void*,double);
|
||||
void (*gain_curve_function)(void *arg, double start, double end, float* vector, guint32 veclen);
|
||||
void *gain_src;
|
||||
|
||||
|
|
|
@ -82,6 +82,13 @@ was_pressed ()
|
|||
cerr << "was pressed\n";
|
||||
}
|
||||
|
||||
bool
|
||||
was_button (GdkEventButton* ev)
|
||||
{
|
||||
cerr << "Bp/R: " << ev->type << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
GainMeter::GainMeter (IO& io, Session& s)
|
||||
: _io (io),
|
||||
_session (s),
|
||||
|
@ -123,6 +130,12 @@ GainMeter::GainMeter (IO& io, Session& s)
|
|||
|
||||
gain_unit_button.signal_clicked().connect (ptr_fun (was_pressed));
|
||||
|
||||
meter_point_button.signal_button_press_event().connect (mem_fun (*this, &GainMeter::meter_press));
|
||||
meter_point_button.signal_button_release_event().connect (mem_fun (*this, &GainMeter::meter_release));
|
||||
g_signal_connect (meter_point_button.gobj(), "button-press-event", (void (*)()) was_button, 0);
|
||||
g_signal_connect (meter_point_button.gobj(), "button-release-event", (void (*)()) was_button, 0);
|
||||
|
||||
|
||||
top_table.set_col_spacings (2);
|
||||
top_table.set_homogeneous (true);
|
||||
top_table.attach (gain_unit_button, 0, 1, 0, 1);
|
||||
|
@ -156,8 +169,6 @@ GainMeter::GainMeter (IO& io, Session& s)
|
|||
|
||||
set_size_request_to_display_given_text (meter_point_button, _("tupni"), 2, 2);
|
||||
|
||||
meter_point_button.signal_button_press_event().connect (mem_fun(*this, &GainMeter::meter_press));
|
||||
meter_point_button.signal_button_release_event().connect (mem_fun(*this, &GainMeter::meter_release));
|
||||
|
||||
top_table.attach (meter_point_button, 1, 2, 0, 1);
|
||||
}
|
||||
|
|
|
@ -535,7 +535,7 @@ StreamView::set_selected_regionviews (AudioRegionSelection& regions)
|
|||
{
|
||||
bool selected;
|
||||
|
||||
cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
|
||||
// cerr << _trackview.name() << " (selected = " << regions.size() << ")" << endl;
|
||||
for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
|
||||
|
||||
selected = false;
|
||||
|
@ -546,7 +546,7 @@ StreamView::set_selected_regionviews (AudioRegionSelection& regions)
|
|||
}
|
||||
}
|
||||
|
||||
cerr << "\tregion " << (*i)->region.name() << " selected = " << selected << endl;
|
||||
// cerr << "\tregion " << (*i)->region.name() << " selected = " << selected << endl;
|
||||
(*i)->set_selected (selected, this);
|
||||
}
|
||||
}
|
||||
|
@ -618,11 +618,12 @@ StreamView::setup_rec_box ()
|
|||
|
||||
// cerr << "\trolling\n";
|
||||
|
||||
if (!rec_active
|
||||
&& _trackview.session().record_status() == Session::Recording
|
||||
&& _trackview.get_diskstream()->record_enabled()) {
|
||||
if (!rec_active &&
|
||||
_trackview.session().record_status() == Session::Recording &&
|
||||
_trackview.get_diskstream()->record_enabled()) {
|
||||
|
||||
if (_trackview.audio_track()->mode() == Normal && use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
|
||||
if (use_rec_regions && rec_regions.size() == rec_rects.size()) {
|
||||
/* add a new region, but don't bother if they set use_rec_regions mid-record */
|
||||
|
||||
AudioRegion::SourceList sources;
|
||||
|
@ -664,7 +665,17 @@ StreamView::setup_rec_box ()
|
|||
DiskStream& ds = at->disk_stream();
|
||||
jack_nframes_t frame_pos = ds.current_capture_start ();
|
||||
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos);
|
||||
gdouble xend = xstart;
|
||||
gdouble xend;
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
xend = xstart;
|
||||
break;
|
||||
|
||||
case Destructive:
|
||||
xend = xstart + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
|
||||
rec_rect->property_x1() = xstart;
|
||||
|
@ -749,21 +760,32 @@ StreamView::setup_rec_box ()
|
|||
void
|
||||
StreamView::update_rec_box ()
|
||||
{
|
||||
/* only update the last box */
|
||||
if (rec_active && rec_rects.size() > 0) {
|
||||
/* only update the last box */
|
||||
RecBoxInfo & rect = rec_rects.back();
|
||||
jack_nframes_t at = _trackview.get_diskstream()->current_capture_end();
|
||||
double xstart;
|
||||
double xend;
|
||||
|
||||
switch (_trackview.audio_track()->mode()) {
|
||||
case Normal:
|
||||
rect.length = at - rect.start;
|
||||
xstart = _trackview.editor.frame_to_pixel (rect.start);
|
||||
xend = _trackview.editor.frame_to_pixel (at);
|
||||
break;
|
||||
|
||||
case Destructive:
|
||||
rect.length = 2;
|
||||
xstart = _trackview.editor.frame_to_pixel (at);
|
||||
xend = xstart + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
rect.length = at - rect.start;
|
||||
|
||||
gdouble xstart = _trackview.editor.frame_to_pixel ( rect.start );
|
||||
gdouble xend = _trackview.editor.frame_to_pixel ( at );
|
||||
|
||||
rect.rectangle->property_x1() = xstart;
|
||||
rect.rectangle->property_x2() = xend;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AudioRegionView*
|
||||
StreamView::find_view (const AudioRegion& region)
|
||||
{
|
||||
|
|
|
@ -103,6 +103,7 @@ TapeAudioRegionView::init (double amplitude_above_axis, Gdk::Color& basic_color,
|
|||
|
||||
/* every time the wave data changes and peaks are ready, redraw */
|
||||
|
||||
|
||||
for (uint32_t n = 0; n < region.n_channels(); ++n) {
|
||||
region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
|
||||
}
|
||||
|
|
|
@ -512,6 +512,14 @@ bool
|
|||
key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
|
||||
{
|
||||
GtkWindow* win = window.gobj();
|
||||
GtkWidget* focus = gtk_window_get_focus (win);
|
||||
bool special_handling_of_unmodified_accelerators = false;
|
||||
|
||||
if (focus) {
|
||||
if (GTK_IS_ENTRY(focus)) {
|
||||
special_handling_of_unmodified_accelerators = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* This exists to allow us to override the way GTK handles
|
||||
key events. The normal sequence is:
|
||||
|
@ -544,9 +552,17 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
|
|||
all "normal text" accelerators.
|
||||
*/
|
||||
|
||||
if (ev->state & ~Gdk::SHIFT_MASK) {
|
||||
|
||||
/* modifiers in effect, accelerate first */
|
||||
if (!special_handling_of_unmodified_accelerators ||
|
||||
ev->state & (Gdk::MOD1_MASK|
|
||||
Gdk::MOD2_MASK|
|
||||
Gdk::MOD3_MASK|
|
||||
Gdk::MOD4_MASK|
|
||||
Gdk::MOD5_MASK|
|
||||
Gdk::CONTROL_MASK|
|
||||
Gdk::LOCK_MASK)) {
|
||||
|
||||
/* no special handling or modifiers in effect: accelerate first */
|
||||
|
||||
if (!gtk_window_activate_key (win, ev)) {
|
||||
return gtk_window_propagate_key_event (win, ev);
|
||||
} else {
|
||||
|
@ -555,7 +571,7 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
|
|||
}
|
||||
|
||||
/* no modifiers, propagate first */
|
||||
|
||||
|
||||
if (!gtk_window_propagate_key_event (win, ev)) {
|
||||
return gtk_window_activate_key (win, ev);
|
||||
}
|
||||
|
|
|
@ -223,7 +223,7 @@ class AudioRegion : public Region
|
|||
extern "C" {
|
||||
int region_read_peaks_from_c (void *arg, uint32_t npeaks, uint32_t start, uint32_t length, intptr_t data, uint32_t n_chan, double samples_per_unit);
|
||||
uint32_t region_length_from_c (void *arg);
|
||||
uint32_t sourcefile_length_from_c (void *arg);
|
||||
uint32_t sourcefile_length_from_c (void *arg, double);
|
||||
}
|
||||
|
||||
#endif /* __ardour_audio_region_h__ */
|
||||
|
|
|
@ -64,6 +64,8 @@ class Source : public Stateful, public sigc::trackable
|
|||
return _length;
|
||||
}
|
||||
|
||||
virtual jack_nframes_t available_peaks (double zoom) const;
|
||||
|
||||
virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1397,9 +1397,9 @@ uint32_t region_length_from_c (void *arg)
|
|||
return ((AudioRegion *) arg)->length();
|
||||
}
|
||||
|
||||
uint32_t sourcefile_length_from_c (void *arg)
|
||||
uint32_t sourcefile_length_from_c (void *arg, double zoom_factor)
|
||||
{
|
||||
return ( (AudioRegion *) arg)->source().length() ;
|
||||
return ( (AudioRegion *) arg)->source().available_peaks (zoom_factor) ;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
|
|
@ -69,6 +69,7 @@ jack_nframes_t DestructiveFileSource::xfade_frames = 64;
|
|||
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
|
||||
: FileSource (path, rate, repair_first, samp_format)
|
||||
{
|
||||
cerr << "DESTRUCTO DISK STREAM, " << _name << endl;
|
||||
if (out_coefficient == 0) {
|
||||
setup_standard_crossfades (rate);
|
||||
}
|
||||
|
@ -83,6 +84,7 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate,
|
|||
DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
|
||||
: FileSource (node, rate)
|
||||
{
|
||||
cerr << "from XML, DESTRUCTO DISK STREAM, " << _name << endl;
|
||||
if (out_coefficient == 0) {
|
||||
setup_standard_crossfades (rate);
|
||||
}
|
||||
|
@ -259,8 +261,6 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
|
|||
jack_nframes_t
|
||||
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
|
||||
{
|
||||
cerr << _name << ": write " << cnt << " to " << file_pos << " start ? " << _capture_start << " end ? " << _capture_end << endl;
|
||||
|
||||
{
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
|
||||
|
@ -273,8 +273,6 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
|
|||
/* move to the correct location place */
|
||||
file_pos = capture_start_frame;
|
||||
|
||||
cerr << "First frame of capture will be at " << file_pos << " and last at: " << file_pos + cnt << endl;
|
||||
|
||||
// split cnt in half
|
||||
jack_nframes_t subcnt = cnt / 2;
|
||||
jack_nframes_t ofilepos = file_pos;
|
||||
|
@ -302,8 +300,6 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
|
|||
/* move to the correct location place */
|
||||
file_pos = capture_start_frame;
|
||||
|
||||
cerr << "First frame of capture will be at " << file_pos << endl;
|
||||
|
||||
if (crossfade (data, cnt, 1, workbuf) != cnt) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -327,8 +323,6 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
|
|||
}
|
||||
file_pos += cnt;
|
||||
|
||||
//cerr << this << ' ' << _name << " at end of write, file_pos = " << file_pos << " length = " << ((int) &_length - (int) this) << ' ' << &_length << ' ' << _length << endl;
|
||||
|
||||
if (_build_peakfiles) {
|
||||
PeakBuildRecord *pbr = 0;
|
||||
|
||||
|
|
|
@ -603,7 +603,7 @@ DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t
|
|||
}
|
||||
|
||||
/* change state */
|
||||
|
||||
|
||||
/* if per-track or global rec-enable turned on while the other was already on, we've started recording */
|
||||
|
||||
if ((change & track_rec_enabled) && record_enabled() && (!(change & global_rec_enabled) && can_record) ||
|
||||
|
@ -692,7 +692,7 @@ DiskStream::check_record_status (jack_nframes_t transport_frame, jack_nframes_t
|
|||
} else if (!record_enabled() || !can_record) {
|
||||
|
||||
/* stop recording */
|
||||
|
||||
|
||||
last_recordable_frame = transport_frame + _capture_offset;
|
||||
|
||||
if (_alignment_style == ExistingMaterial) {
|
||||
|
@ -1608,8 +1608,6 @@ DiskStream::do_flush (char * workbuf, bool force_flush)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
|
||||
error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
|
||||
return -1;
|
||||
|
@ -1963,6 +1961,9 @@ DiskStream::get_state ()
|
|||
char buf[64];
|
||||
LocaleGuard lg (X_("POSIX"));
|
||||
|
||||
snprintf (buf, sizeof(buf), "0x%x", _flags);
|
||||
node->add_property ("flags", buf);
|
||||
|
||||
snprintf (buf, sizeof(buf), "%zd", channels.size());
|
||||
node->add_property ("channels", buf);
|
||||
|
||||
|
@ -2047,6 +2048,10 @@ DiskStream::set_state (const XMLNode& node)
|
|||
}
|
||||
}
|
||||
|
||||
if ((prop = node.property ("_flags")) != 0) {
|
||||
_flags = atoi (prop->value().c_str());
|
||||
}
|
||||
|
||||
if ((prop = node.property ("channels")) != 0) {
|
||||
nchans = atoi (prop->value().c_str());
|
||||
}
|
||||
|
|
|
@ -545,19 +545,21 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
|
|||
tnp = min ((_length/frames_per_peak - current_stored_peak), (jack_nframes_t) expected_peaks);
|
||||
to_read = min (chunksize, tnp);
|
||||
|
||||
off_t fend = lseek (peakfile, 0, SEEK_END);
|
||||
|
||||
if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
|
||||
!= sizeof (PeakData) * to_read) {
|
||||
cerr << "Source["
|
||||
<< _name
|
||||
<< "]: cannot read peak data from peakfile ("
|
||||
<< nread
|
||||
<< (nread / sizeof(PeakData))
|
||||
<< " peaks instead of "
|
||||
<< to_read
|
||||
<< ") ("
|
||||
<< strerror (errno)
|
||||
<< ')'
|
||||
<< " at start_byte = " << start_byte
|
||||
<< " _length = " << _length
|
||||
<< " _length = " << _length << " versus len = " << fend
|
||||
<< " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
|
||||
<< " npeaks was " << npeaks
|
||||
<< endl;
|
||||
|
@ -699,7 +701,7 @@ Source::build_peaks ()
|
|||
}
|
||||
|
||||
#ifdef DEBUG_PEAK_BUILD
|
||||
cerr << "build peaks with " << pending_peak_builds.size() << " requests pending\n";
|
||||
cerr << "build peaks with " << copy.size() << " requests pending\n";
|
||||
#endif
|
||||
|
||||
for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
|
||||
|
@ -732,6 +734,7 @@ Source::build_peaks ()
|
|||
}
|
||||
|
||||
if (pr_signal) {
|
||||
off_t fend = lseek (peakfile, 0, SEEK_END);
|
||||
PeaksReady (); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
@ -849,3 +852,17 @@ Source::release ()
|
|||
{
|
||||
if (_use_cnt) --_use_cnt;
|
||||
}
|
||||
|
||||
jack_nframes_t
|
||||
Source::available_peaks (double zoom_factor) const
|
||||
{
|
||||
if (zoom_factor < frames_per_peak) {
|
||||
return length(); // peak data will come from the audio file
|
||||
}
|
||||
|
||||
/* peak data comes from peakfile */
|
||||
|
||||
LockMonitor lm (_lock, __LINE__, __FILE__);
|
||||
off_t end = lseek (peakfile, 0, SEEK_END);
|
||||
return (end/sizeof(PeakData)) * frames_per_peak;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue