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 */
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

View File

@ -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;

View File

@ -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);
}

View File

@ -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)
{

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 */
for (uint32_t n = 0; n < region.n_channels(); ++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)
{
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);
}

View File

@ -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__ */

View File

@ -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;
}

View File

@ -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" */

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)
: 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;

View File

@ -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());
}

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);
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;
}