ardour
audio_region_editor.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2001 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #include <cmath>
21 
22 #include <gtkmm2ext/utils.h>
23 
24 #include "pbd/memento_command.h"
26 #include "pbd/pthread_utils.h"
27 
28 #include "ardour/audioregion.h"
29 #include "ardour/session_event.h"
30 #include "ardour/dB.h"
31 
32 #include "audio_region_editor.h"
33 #include "audio_region_view.h"
34 #include "ardour_ui.h"
35 #include "gui_thread.h"
36 
37 #include "i18n.h"
38 
39 using namespace ARDOUR;
40 using namespace PBD;
41 using namespace std;
42 using namespace Gtkmm2ext;
43 
44 static void *
46 {
47  SessionEvent::create_per_thread_pool ("peak amplitude events", 64);
48  static_cast<AudioRegionEditor*>(arg)->peak_amplitude_thread ();
49  return 0;
50 }
51 
53  : RegionEditor (s, r)
54  , _audio_region (r)
55  , gain_adjustment(accurate_coefficient_to_dB(_audio_region->scale_amplitude()), -40.0, +40.0, 0.1, 1.0, 0)
56 #ifndef PLATFORM_WINDOWS
57  , _peak_channel (false)
58 #endif
59 {
60 
61  Gtk::HBox* b = Gtk::manage (new Gtk::HBox);
62  b->set_spacing (6);
63  b->pack_start (gain_entry);
64  b->pack_start (*Gtk::manage (new Gtk::Label (_("dB"))), false, false);
65 
66  gain_label.set_name ("AudioRegionEditorLabel");
67  gain_label.set_text (_("Region gain:"));
68  gain_label.set_alignment (1, 0.5);
69  gain_entry.configure (gain_adjustment, 0.0, 1);
70  _table.attach (gain_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
71  _table.attach (*b, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
72  ++_table_row;
73 
74  b = Gtk::manage (new Gtk::HBox);
75  b->set_spacing (6);
76  b->pack_start (_peak_amplitude);
77  b->pack_start (*Gtk::manage (new Gtk::Label (_("dBFS"))), false, false);
78 
79  _peak_amplitude_label.set_name ("AudioRegionEditorLabel");
80  _peak_amplitude_label.set_text (_("Peak amplitude:"));
81  _peak_amplitude_label.set_alignment (1, 0.5);
82  _table.attach (_peak_amplitude_label, 0, 1, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
83  _table.attach (*b, 1, 2, _table_row, _table_row + 1, Gtk::FILL, Gtk::FILL);
84  ++_table_row;
85 
86  gain_changed ();
87 
88  gain_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &AudioRegionEditor::gain_adjustment_changed));
89 
90  _peak_amplitude.property_editable() = false;
91  _peak_amplitude.set_text (_("Calculating..."));
92 
96 }
97 
99 {
100  void* v;
102  pthread_join (_peak_amplitude_thread_handle, &v);
103 }
104 
105 void
107 {
108  RegionEditor::region_changed (what_changed);
109 
110  if (what_changed.contains (ARDOUR::Properties::scale_amplitude)) {
111  gain_changed ();
112  }
113 
114  if (what_changed.contains (ARDOUR::Properties::start) || what_changed.contains (ARDOUR::Properties::length)) {
115  /* ask the peak thread to run again */
117  }
118 }
119 void
121 {
122  float const region_gain_dB = accurate_coefficient_to_dB (_audio_region->scale_amplitude());
123  if (region_gain_dB != gain_adjustment.get_value()) {
124  gain_adjustment.set_value(region_gain_dB);
125  }
126 }
127 
128 void
130 {
131  float const gain = dB_to_coefficient (gain_adjustment.get_value());
132  if (_audio_region->scale_amplitude() != gain) {
134  }
135 }
136 
137 void
139 {
140 #ifdef PLATFORM_WINDOWS
141  m_peak_sem.post ();
142 #else
143  _peak_channel.deliver ('c');
144 #endif
145 }
146 
147 void
149 {
150 #ifdef PLATFORM_WINDOWS
151  m_peak_sem.wait ();
152 #else
153  char msg;
154  _peak_channel.receive (msg);
155 #endif
156 }
157 
158 void
160 {
161  while (1) {
162  /* await instructions to run */
163  wait_for_signal ();
164 
165  /* compute peak amplitude and signal the fact */
167  }
168 }
169 
170 void
172 {
173  stringstream s;
174  s.precision (2);
175  s.setf (ios::fixed, ios::floatfield);
176  s << p;
177  _peak_amplitude.set_text (s.str ());
178 }
179 
PBD::ScopedConnection _peak_amplitude_connection
static void * _peak_amplitude_thread(void *arg)
pthread_t _peak_amplitude_thread_handle
void region_changed(PBD::PropertyChange const &)
static void create_per_thread_pool(const std::string &n, uint32_t nitems)
int receive(char &msg, bool wait=false)
Definition: Beats.hpp:239
LIBARDOUR_API PBD::PropertyDescriptor< bool > gain
Definition: route_group.cc:44
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
#define invalidator(x)
Definition: gui_thread.h:40
static float accurate_coefficient_to_dB(float coeff)
Definition: dB.h:38
#define _(Text)
Definition: i18n.h:11
boost::shared_ptr< ARDOUR::AudioRegion > _audio_region
#define X_(Text)
Definition: i18n.h:13
double maximum_amplitude(Progress *p=0) const
Definition: amp.h:29
gain_t scale_amplitude() const
Definition: audioregion.h:78
#define gui_context()
Definition: gui_thread.h:36
AudioRegionEditor(ARDOUR::Session *, boost::shared_ptr< ARDOUR::AudioRegion >)
void peak_amplitude_found(double)
Gtk::Table _table
Definition: region_editor.h:61
Gtk::SpinButton gain_entry
void set_scale_amplitude(gain_t)
Definition: debug.h:30
CrossThreadChannel _peak_channel
static float dB_to_coefficient(float dB)
Definition: dB.h:30
bool contains(PropertyDescriptor< T > p) const
Gtk::Label _peak_amplitude_label
Gtk::Adjustment gain_adjustment
LIBARDOUR_API PBD::PropertyDescriptor< float > scale_amplitude
Definition: audioregion.cc:66
LIBPBD_API int pthread_create_and_store(std::string name, pthread_t *thread, void *(*start_routine)(void *), void *arg)
PBD::Signal1< void, double > PeakAmplitudeFound
LIBPBD_API void pthread_cancel_one(pthread_t thread)
virtual void region_changed(const PBD::PropertyChange &)
LIBARDOUR_API PBD::PropertyDescriptor< framecnt_t > length
Definition: region.cc:64