2 Copyright (C) 2002 Paul Davis
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.
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.
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.
23 #include "ardour/ardour.h"
24 #include "ardour/session.h"
25 #include "ardour/tempo.h"
26 #include "ardour/io.h"
27 #include "ardour/buffer_set.h"
28 #include "ardour/audio_buffer.h"
35 using namespace ARDOUR
;
38 Pool
Click::pool ("click", sizeof (Click
), 128);
41 Session::click (nframes_t start
, nframes_t nframes
)
43 TempoMap::BBTPointList
*points
;
50 Glib::RWLock::WriterLock
clickm (click_lock
, Glib::TRY_LOCK
);
52 if (!clickm
.locked() || _transport_speed
!= 1.0 || !_clicking
|| click_data
== 0) {
53 _click_io
->silence (nframes
);
57 const nframes_t end
= start
+ nframes
;
59 BufferSet
& bufs
= get_scratch_buffers(ChanCount(DataType::AUDIO
, 1));
60 buf
= bufs
.get_audio(0).data();
61 points
= _tempo_map
->get_points (start
, end
);
67 if (points
->empty()) {
72 for (TempoMap::BBTPointList::iterator i
= points
->begin(); i
!= points
->end(); ++i
) {
75 if (click_emphasis_data
== 0 || (click_emphasis_data
&& (*i
).beat
!= 1)) {
76 clicks
.push_back (new Click ((*i
).frame
, click_length
, click_data
));
81 if (click_emphasis_data
) {
82 clicks
.push_back (new Click ((*i
).frame
, click_emphasis_length
, click_emphasis_data
));
89 memset (buf
, 0, sizeof (Sample
) * nframes
);
91 for (list
<Click
*>::iterator i
= clicks
.begin(); i
!= clicks
.end(); ) {
94 nframes_t internal_offset
;
96 list
<Click
*>::iterator next
;
102 if (clk
->start
< start
) {
105 internal_offset
= clk
->start
- start
;
108 if (nframes
< internal_offset
) {
109 /* we've just located or something..
110 effectively going backwards.
111 lets get the flock out of here */
115 copy
= min (clk
->duration
- clk
->offset
, nframes
- internal_offset
);
117 memcpy (buf
+ internal_offset
, &clk
->data
[clk
->offset
], copy
* sizeof (Sample
));
121 if (clk
->offset
>= clk
->duration
) {
130 _click_io
->copy_to_outputs (bufs
, DataType::AUDIO
, nframes
, 0);
134 Session::setup_click_sounds (int which
)
141 if ((which
== 0 || which
== 1)) {
143 if (click_data
!= default_click
) {
144 delete [] click_data
;
148 string path
= Config
->get_click_sound();
152 click_data
= const_cast<Sample
*> (default_click
);
153 click_length
= default_click_length
;
158 if ((sndfile
= sf_open (path
.c_str(), SFM_READ
, &info
)) == 0) {
160 sf_error_str (0, errbuf
, sizeof (errbuf
) - 1);
161 warning
<< string_compose (_("cannot open click soundfile %1 (%2)"), path
, errbuf
) << endmsg
;
166 click_data
= new Sample
[info
.frames
];
167 click_length
= info
.frames
;
169 if (sf_read_float (sndfile
, click_data
, info
.frames
) != info
.frames
) {
170 warning
<< _("cannot read data from click soundfile") << endmsg
;
181 if ((which
== 0 || which
== -1)) {
183 if (click_emphasis_data
!= default_click_emphasis
) {
184 delete [] click_emphasis_data
;
185 click_emphasis_data
= 0;
188 string path
= Config
->get_click_emphasis_sound();
191 click_emphasis_data
= const_cast<Sample
*> (default_click_emphasis
);
192 click_emphasis_length
= default_click_emphasis_length
;
195 if ((sndfile
= sf_open (path
.c_str(), SFM_READ
, &info
)) == 0) {
197 sf_error_str (0, errbuf
, sizeof (errbuf
) - 1);
198 warning
<< string_compose (_("cannot open click emphasis soundfile %1 (%2)"), path
, errbuf
) << endmsg
;
202 click_emphasis_data
= new Sample
[info
.frames
];
203 click_emphasis_length
= info
.frames
;
205 if (sf_read_float (sndfile
, click_emphasis_data
, info
.frames
) != info
.frames
) {
206 warning
<< _("cannot read data from click emphasis soundfile") << endmsg
;
207 delete click_emphasis_data
;
208 click_emphasis_data
= 0;
217 Session::clear_clicks ()
219 Glib::RWLock::WriterLock
lm (click_lock
);
221 for (Clicks::iterator i
= clicks
.begin(); i
!= clicks
.end(); ++i
) {