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:
Paul Davis 2006-03-14 03:43:54 +00:00
parent 1a52aeb370
commit af70789773
12 changed files with 109 additions and 41 deletions

View file

@ -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 */ /* 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; rf3 -= new_cache_start;
#if DEBUG_CACHE #if DEBUG_CACHE
fprintf (stderr, "\n\nAVAILABLE FRAMES = %lu of %lu, start = %lu, sstart = %lu, cstart = %lu\n", 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); waveview->region_start, start_sample, new_cache_start);
#endif #endif

View file

@ -76,7 +76,7 @@ struct _GnomeCanvasWaveView
guint32 channel; guint32 channel;
void (*peak_function)(void*,gulong,gulong,gulong,gpointer,guint32,double); void (*peak_function)(void*,gulong,gulong,gulong,gpointer,guint32,double);
gulong (*length_function)(void *); 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_curve_function)(void *arg, double start, double end, float* vector, guint32 veclen);
void *gain_src; void *gain_src;

View file

@ -82,6 +82,13 @@ was_pressed ()
cerr << "was pressed\n"; cerr << "was pressed\n";
} }
bool
was_button (GdkEventButton* ev)
{
cerr << "Bp/R: " << ev->type << endl;
return false;
}
GainMeter::GainMeter (IO& io, Session& s) GainMeter::GainMeter (IO& io, Session& s)
: _io (io), : _io (io),
_session (s), _session (s),
@ -123,6 +130,12 @@ GainMeter::GainMeter (IO& io, Session& s)
gain_unit_button.signal_clicked().connect (ptr_fun (was_pressed)); 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_col_spacings (2);
top_table.set_homogeneous (true); top_table.set_homogeneous (true);
top_table.attach (gain_unit_button, 0, 1, 0, 1); 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); 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); top_table.attach (meter_point_button, 1, 2, 0, 1);
} }

View file

@ -535,7 +535,7 @@ StreamView::set_selected_regionviews (AudioRegionSelection& regions)
{ {
bool selected; 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) { for (list<AudioRegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
selected = false; 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); (*i)->set_selected (selected, this);
} }
} }
@ -618,11 +618,12 @@ StreamView::setup_rec_box ()
// cerr << "\trolling\n"; // cerr << "\trolling\n";
if (!rec_active if (!rec_active &&
&& _trackview.session().record_status() == Session::Recording _trackview.session().record_status() == Session::Recording &&
&& _trackview.get_diskstream()->record_enabled()) { _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 */ /* add a new region, but don't bother if they set use_rec_regions mid-record */
AudioRegion::SourceList sources; AudioRegion::SourceList sources;
@ -664,7 +665,17 @@ StreamView::setup_rec_box ()
DiskStream& ds = at->disk_stream(); DiskStream& ds = at->disk_stream();
jack_nframes_t frame_pos = ds.current_capture_start (); jack_nframes_t frame_pos = ds.current_capture_start ();
gdouble xstart = _trackview.editor.frame_to_pixel (frame_pos); 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); ArdourCanvas::SimpleRect * rec_rect = new Gnome::Canvas::SimpleRect (*canvas_group);
rec_rect->property_x1() = xstart; rec_rect->property_x1() = xstart;
@ -749,15 +760,26 @@ StreamView::setup_rec_box ()
void void
StreamView::update_rec_box () StreamView::update_rec_box ()
{ {
/* only update the last box */
if (rec_active && rec_rects.size() > 0) { if (rec_active && rec_rects.size() > 0) {
/* only update the last box */
RecBoxInfo & rect = rec_rects.back(); RecBoxInfo & rect = rec_rects.back();
jack_nframes_t at = _trackview.get_diskstream()->current_capture_end(); jack_nframes_t at = _trackview.get_diskstream()->current_capture_end();
double xstart;
double xend;
rect.length = at - rect.start; 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;
gdouble xstart = _trackview.editor.frame_to_pixel ( rect.start ); case Destructive:
gdouble xend = _trackview.editor.frame_to_pixel ( at ); rect.length = 2;
xstart = _trackview.editor.frame_to_pixel (at);
xend = xstart + 2;
break;
}
rect.rectangle->property_x1() = xstart; rect.rectangle->property_x1() = xstart;
rect.rectangle->property_x2() = xend; rect.rectangle->property_x2() = xend;

View file

@ -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 */ /* every time the wave data changes and peaks are ready, redraw */
for (uint32_t n = 0; n < region.n_channels(); ++n) { for (uint32_t n = 0; n < region.n_channels(); ++n) {
region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n)); region.source(n).PeaksReady.connect (bind (mem_fun(*this, &TapeAudioRegionView::update), n));
} }

View file

@ -512,6 +512,14 @@ bool
key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev) key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
{ {
GtkWindow* win = window.gobj(); 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 /* This exists to allow us to override the way GTK handles
key events. The normal sequence is: key events. The normal sequence is:
@ -544,9 +552,17 @@ key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev)
all "normal text" accelerators. all "normal text" accelerators.
*/ */
if (ev->state & ~Gdk::SHIFT_MASK) { 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 */
/* modifiers in effect, accelerate first */
if (!gtk_window_activate_key (win, ev)) { if (!gtk_window_activate_key (win, ev)) {
return gtk_window_propagate_key_event (win, ev); return gtk_window_propagate_key_event (win, ev);
} else { } else {

View file

@ -223,7 +223,7 @@ class AudioRegion : public Region
extern "C" { 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); 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 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__ */ #endif /* __ardour_audio_region_h__ */

View file

@ -64,6 +64,8 @@ class Source : public Stateful, public sigc::trackable
return _length; 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 { virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
return 0; return 0;
} }

View file

@ -1397,9 +1397,9 @@ uint32_t region_length_from_c (void *arg)
return ((AudioRegion *) arg)->length(); 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" */ } /* extern "C" */

View file

@ -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) DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
: FileSource (path, rate, repair_first, samp_format) : FileSource (path, rate, repair_first, samp_format)
{ {
cerr << "DESTRUCTO DISK STREAM, " << _name << endl;
if (out_coefficient == 0) { if (out_coefficient == 0) {
setup_standard_crossfades (rate); 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) DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate)
: FileSource (node, rate) : FileSource (node, rate)
{ {
cerr << "from XML, DESTRUCTO DISK STREAM, " << _name << endl;
if (out_coefficient == 0) { if (out_coefficient == 0) {
setup_standard_crossfades (rate); setup_standard_crossfades (rate);
} }
@ -259,8 +261,6 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in,
jack_nframes_t jack_nframes_t
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf) 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__); 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 */ /* move to the correct location place */
file_pos = capture_start_frame; 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 // split cnt in half
jack_nframes_t subcnt = cnt / 2; jack_nframes_t subcnt = cnt / 2;
jack_nframes_t ofilepos = file_pos; 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 */ /* move to the correct location place */
file_pos = capture_start_frame; file_pos = capture_start_frame;
cerr << "First frame of capture will be at " << file_pos << endl;
if (crossfade (data, cnt, 1, workbuf) != cnt) { if (crossfade (data, cnt, 1, workbuf) != cnt) {
return 0; return 0;
} }
@ -327,8 +323,6 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
} }
file_pos += cnt; 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) { if (_build_peakfiles) {
PeakBuildRecord *pbr = 0; PeakBuildRecord *pbr = 0;

View file

@ -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) { 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; error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
return -1; return -1;
@ -1963,6 +1961,9 @@ DiskStream::get_state ()
char buf[64]; char buf[64];
LocaleGuard lg (X_("POSIX")); LocaleGuard lg (X_("POSIX"));
snprintf (buf, sizeof(buf), "0x%x", _flags);
node->add_property ("flags", buf);
snprintf (buf, sizeof(buf), "%zd", channels.size()); snprintf (buf, sizeof(buf), "%zd", channels.size());
node->add_property ("channels", buf); 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) { if ((prop = node.property ("channels")) != 0) {
nchans = atoi (prop->value().c_str()); nchans = atoi (prop->value().c_str());
} }

View file

@ -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); tnp = min ((_length/frames_per_peak - current_stored_peak), (jack_nframes_t) expected_peaks);
to_read = min (chunksize, tnp); to_read = min (chunksize, tnp);
off_t fend = lseek (peakfile, 0, SEEK_END);
if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte)) if ((nread = ::pread (peakfile, staging, sizeof (PeakData) * to_read, start_byte))
!= sizeof (PeakData) * to_read) { != sizeof (PeakData) * to_read) {
cerr << "Source[" cerr << "Source["
<< _name << _name
<< "]: cannot read peak data from peakfile (" << "]: cannot read peak data from peakfile ("
<< nread << (nread / sizeof(PeakData))
<< " peaks instead of " << " peaks instead of "
<< to_read << to_read
<< ") (" << ") ("
<< strerror (errno) << strerror (errno)
<< ')' << ')'
<< " at start_byte = " << start_byte << " at start_byte = " << start_byte
<< " _length = " << _length << " _length = " << _length << " versus len = " << fend
<< " expected maxpeaks = " << (_length - current_frame)/frames_per_peak << " expected maxpeaks = " << (_length - current_frame)/frames_per_peak
<< " npeaks was " << npeaks << " npeaks was " << npeaks
<< endl; << endl;
@ -699,7 +701,7 @@ Source::build_peaks ()
} }
#ifdef DEBUG_PEAK_BUILD #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 #endif
for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) { for (list<PeakBuildRecord *>::iterator i = copy.begin(); i != copy.end(); ++i) {
@ -732,6 +734,7 @@ Source::build_peaks ()
} }
if (pr_signal) { if (pr_signal) {
off_t fend = lseek (peakfile, 0, SEEK_END);
PeaksReady (); /* EMIT SIGNAL */ PeaksReady (); /* EMIT SIGNAL */
} }
} }
@ -849,3 +852,17 @@ Source::release ()
{ {
if (_use_cnt) --_use_cnt; 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;
}