fix merge with master
[ardour.git] / libs / canvas / test / wave_view.cc
1 #include <gtkmm/main.h>
2 #include "pbd/textreceiver.h"
3 #include "gtkmm2ext/utils.h"
4 #include "midi++/manager.h"
5 #include "ardour/session.h"
6 #include "ardour/audioengine.h"
7 #include "ardour/source_factory.h"
8 #include "ardour/audiosource.h"
9 #include "ardour/audiofilesource.h"
10 #include "ardour/region_factory.h"
11 #include "ardour/audioregion.h"
12 #include "canvas/wave_view.h"
13 #include "canvas/canvas.h"
14 #include "wave_view.h"
15
16 using namespace std;
17 using namespace PBD;
18 using namespace ARDOUR;
19 using namespace ArdourCanvas;
20
21 CPPUNIT_TEST_SUITE_REGISTRATION (WaveViewTest);
22
23 TextReceiver text_receiver ("test");
24
25 void
26 WaveViewTest::setUp ()
27 {
28         init (false, true);
29         Gtkmm2ext::init ();
30         SessionEvent::create_per_thread_pool ("test", 512);
31
32         Gtk::Main kit ();
33         Gtk::Main::init_gtkmm_internals ();
34
35         text_receiver.listen_to (error);
36         text_receiver.listen_to (info);
37         text_receiver.listen_to (fatal);
38         text_receiver.listen_to (warning);
39
40         AudioFileSource::set_build_peakfiles (true);
41         AudioFileSource::set_build_missing_peakfiles (true);
42
43         AudioEngine engine ("test", "");
44         MIDI::Manager::create (engine.jack ());
45         CPPUNIT_ASSERT (engine.start () == 0);
46         
47         Session session (engine, "tmp_session", "tmp_session");
48         engine.set_session (&session);
49
50         char buf[256];
51         getcwd (buf, sizeof (buf));
52         string const path = string_compose ("%1/../../libs/canvas/test/sine.wav", buf);
53
54         boost::shared_ptr<Source> source = SourceFactory::createReadable (
55                 DataType::AUDIO, session, path, 0, (Source::Flag) 0, false, true
56                 );
57
58         boost::shared_ptr<AudioFileSource> audio_file_source = boost::dynamic_pointer_cast<AudioFileSource> (source);
59
60         audio_file_source->setup_peakfile ();
61
62         PBD::PropertyList properties;
63         properties.add (Properties::position, 128);
64         properties.add (Properties::length, audio_file_source->readable_length ());
65         _region = RegionFactory::create (source, properties, false);
66         _audio_region = boost::dynamic_pointer_cast<AudioRegion> (_region);
67 }
68
69 void
70 WaveViewTest::make_canvas ()
71 {
72         /* this leaks various things, but hey ho */
73         
74         _canvas = new ImageCanvas (Duple (256, 256));
75         _wave_view = new WaveView (_canvas->root(), _audio_region);
76         _wave_view->set_frames_per_pixel ((double) (44100 / 1000) / 64);
77         _wave_view->set_height (64);
78 }
79
80 void
81 WaveViewTest::all ()
82 {
83         /* XXX: we run these all from the same method so that the setUp code only
84            gets called once; there are various singletons etc. in Ardour which don't
85            like being recreated.
86         */
87         
88         render_all_at_once ();
89         render_in_pieces ();
90         cache ();
91 }
92
93 void
94 WaveViewTest::render_all_at_once ()
95 {
96         make_canvas ();
97         
98         _canvas->render_to_image (Rect (0, 0, 256, 256));
99         _canvas->write_to_png ("waveview_1.png");
100
101         /* XXX: doesn't check the result! */
102 }
103
104 void
105 WaveViewTest::render_in_pieces ()
106 {
107         make_canvas ();
108
109         cout << "\n\n--------------> PIECES\n";
110         _canvas->render_to_image (Rect (0, 0, 128, 256));
111         _canvas->render_to_image (Rect (128, 0, 256, 256));
112         _canvas->write_to_png ("waveview_2.png");
113         cout << "\n\n<-------------- PIECES\n";
114
115         /* XXX: doesn't check the result! */
116 }
117
118 void
119 WaveViewTest::cache ()
120 {
121         make_canvas ();
122         
123         /* Whole of the render area needs caching from scratch */
124         
125         _wave_view->invalidate_whole_cache ();
126         
127         Rect whole (0, 0, 256, 256);
128         _canvas->render_to_image (whole);
129
130         CPPUNIT_ASSERT (_wave_view->_cache.size() == 1);
131         CPPUNIT_ASSERT (_wave_view->_cache.front()->start() == 0);
132         CPPUNIT_ASSERT (_wave_view->_cache.front()->end() == 256);
133
134         _wave_view->invalidate_whole_cache ();
135         
136         /* Render a bit in the middle */
137
138         Rect part1 (128, 0, 196, 256);
139         _canvas->render_to_image (part1);
140
141         CPPUNIT_ASSERT (_wave_view->_cache.size() == 1);
142         CPPUNIT_ASSERT (_wave_view->_cache.front()->start() == 128);
143         CPPUNIT_ASSERT (_wave_view->_cache.front()->end() == 196);
144
145         /* Now render the whole thing and check that the cache sorts itself out */
146
147         _canvas->render_to_image (whole);
148         
149         CPPUNIT_ASSERT (_wave_view->_cache.size() == 3);
150
151         list<WaveView::CacheEntry*>::iterator i = _wave_view->_cache.begin ();
152         
153         CPPUNIT_ASSERT ((*i)->start() == 0);
154         CPPUNIT_ASSERT ((*i)->end() == 128);
155         ++i;
156
157         CPPUNIT_ASSERT ((*i)->start() == 128);
158         CPPUNIT_ASSERT ((*i)->end() == 196);
159         ++i;
160
161         CPPUNIT_ASSERT ((*i)->start() == 196);
162         CPPUNIT_ASSERT ((*i)->end() == 256);
163         ++i;
164 }