ed97cf7b393e09459e9a5089695a5891796b5319
[ardour.git] / libs / ardour / auditioner.cc
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     $Id$
19 */
20
21 #include <pbd/lockmonitor.h>
22
23 #include <ardour/diskstream.h>
24 #include <ardour/audioregion.h>
25 #include <ardour/route.h>
26 #include <ardour/session.h>
27 #include <ardour/auditioner.h>
28 #include <ardour/audioplaylist.h>
29 #include <ardour/panner.h>
30
31 using namespace std;
32 using namespace ARDOUR;
33
34 Auditioner::Auditioner (Session& s)
35         : AudioTrack (s, "auditioner", Route::Hidden)
36 {
37         string left = Config->get_auditioner_output_left();
38         string right = Config->get_auditioner_output_right();
39         
40         if ((left.length() == 0) && (right.length() == 0)) {
41                 return;
42         }
43
44         defer_pan_reset ();
45
46         if (left.length()) {
47                 add_output_port (left, this);
48         }
49
50         if (right.length()) {
51                 disk_stream().add_channel();
52                 add_output_port (right, this);
53         }
54
55         allow_pan_reset ();
56         
57         IO::output_changed.connect (mem_fun (*this, &Auditioner::output_changed));
58
59         the_region = 0;
60         atomic_set (&_active, 0);
61 }
62
63 Auditioner::~Auditioner ()
64 {
65 }
66
67 AudioPlaylist&
68 Auditioner::prepare_playlist ()
69 {
70         diskstream->playlist()->clear (false, false);
71         return *diskstream->playlist();
72 }
73
74 void
75 Auditioner::audition_current_playlist ()
76 {
77         if (atomic_read (&_active)) {
78                 /* don't go via session for this, because we are going
79                    to remain active.
80                 */
81                 cancel_audition ();
82         }
83
84         LockMonitor lm (lock, __LINE__, __FILE__);
85         diskstream->seek (0);
86         length = diskstream->playlist()->get_maximum_extent();
87         current_frame = 0;
88
89         /* force a panner reset now that we have all channels */
90
91         _panner->reset (n_outputs(), diskstream->n_channels());
92
93         atomic_set (&_active, 1);
94 }
95
96 void
97 Auditioner::audition_region (AudioRegion& region)
98 {
99         if (atomic_read (&_active)) {
100                 /* don't go via session for this, because we are going
101                    to remain active.
102                 */
103                 cancel_audition ();
104         }
105
106         LockMonitor lm (lock, __LINE__, __FILE__);
107
108         the_region = new AudioRegion (region);
109         the_region->set_position (0, this);
110
111         diskstream->playlist()->clear (true, false);
112         diskstream->playlist()->add_region (*the_region, 0, 1, false);
113
114         while (diskstream->n_channels() < the_region->n_channels()) {
115                 diskstream->add_channel ();
116         }
117
118         while (diskstream->n_channels() > the_region->n_channels()) {
119                 diskstream->remove_channel ();
120         }
121
122         /* force a panner reset now that we have all channels */
123
124         _panner->reset (n_outputs(), diskstream->n_channels());
125
126         length = the_region->length();
127         diskstream->seek (0);
128         current_frame = 0;
129         atomic_set (&_active, 1);
130 }
131
132 int
133 Auditioner::play_audition (jack_nframes_t nframes)
134 {
135         bool need_butler;
136         jack_nframes_t this_nframes;
137         int ret;
138
139         if (atomic_read (&_active) == 0) {
140                 silence (nframes, 0);
141                 return 0;
142         }
143
144         this_nframes = min (nframes, length - current_frame);
145
146         diskstream->prepare ();
147
148         if ((ret = roll (this_nframes, current_frame, current_frame + nframes, 0, false, false, false)) != 0) {
149                 silence (nframes, 0);
150                 return ret;
151         }
152
153         need_butler = diskstream->commit (this_nframes);
154         current_frame += this_nframes;
155
156         if (current_frame >= length) {
157                 _session.cancel_audition ();
158                 return 0;
159         } else {
160                 return need_butler ? 1 : 0;
161         }
162 }
163
164 void
165 Auditioner::output_changed (IOChange change, void* src)
166 {
167         if (change & ConnectionsChanged) {
168                 const char ** connections;
169                 connections =  output (0)->get_connections ();
170                 if (connections) {
171                         Config->set_auditioner_output_left (connections[0]);
172                         free (connections);
173                 }
174                 
175                 connections = output (1)->get_connections ();
176                 if (connections) {
177                         Config->set_auditioner_output_right (connections[0]);
178                         free (connections);
179                 }
180         }
181 }