ardour
reverse.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2004 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 <algorithm>
21 
22 #include "ardour/audioregion.h"
23 #include "ardour/audiosource.h"
24 #include "ardour/reverse.h"
25 #include "ardour/types.h"
26 
27 using namespace std;
28 using namespace ARDOUR;
29 
30 namespace ARDOUR { class Progress; class Session; }
31 
32 Reverse::Reverse (Session& s)
33  : Filter (s)
34 {
35 }
36 
38 {
39 }
40 
41 int
43 {
44  SourceList nsrcs;
45  SourceList::iterator si;
46  framecnt_t blocksize = 256 * 1024;
47  Sample* buf = 0;
48  framepos_t fpos;
49  framepos_t fstart;
50  framecnt_t to_read;
51  int ret = -1;
52 
54  if (!region)
55  return ret;
56 
57  /* create new sources */
58 
59  if (make_new_sources (region, nsrcs)) {
60  goto out;
61  }
62 
63  fstart = region->start();
64 
65  if (blocksize > region->length()) {
66  blocksize = region->length();
67  }
68 
69  fpos = max (fstart, (fstart + region->length() - blocksize));
70 
71  buf = new Sample[blocksize];
72  to_read = blocksize;
73 
74  /* now read it backwards */
75 
76  while (to_read) {
77 
78  uint32_t n;
79 
80  for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) {
81 
82  /* read it in directly from the source */
83 
84  if (region->audio_source (n)->read (buf, fpos, to_read) != to_read) {
85  goto out;
86  }
87 
88  /* swap memory order */
89 
90  for (framecnt_t i = 0; i < to_read/2; ++i) {
91  swap (buf[i],buf[to_read-1-i]);
92  }
93 
94  /* write it out */
95 
96  boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si));
97 
98  if (asrc && asrc->write (buf, to_read) != to_read) {
99  goto out;
100  }
101  }
102 
103  if (fpos > fstart + blocksize) {
104  fpos -= to_read;
105  to_read = blocksize;
106  } else {
107  to_read = fpos - fstart;
108  fpos = fstart;
109  }
110  };
111 
112  ret = finish (region, nsrcs);
113 
114  out:
115 
116  delete [] buf;
117 
118  if (ret) {
119  for (si = nsrcs.begin(); si != nsrcs.end(); ++si) {
120  boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si));
121  asrc->mark_for_remove ();
122  }
123  }
124 
125  return ret;
126 }
int make_new_sources(boost::shared_ptr< ARDOUR::Region >, ARDOUR::SourceList &, std::string suffix="")
Definition: filter.cc:42
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
Definition: Beats.hpp:239
int64_t framecnt_t
Definition: types.h:76
float Sample
Definition: types.h:54
Definition: amp.h:29
boost::shared_ptr< AudioSource > audio_source(uint32_t n=0) const
void swap(shared_ptr< T > &a, shared_ptr< T > &b)
Definition: shared_ptr.hpp:381
void mark_for_remove()
Definition: source.cc:249
int64_t framepos_t
Definition: types.h:66
uint32_t n_channels() const
Definition: region.h:259
virtual framecnt_t write(Sample *src, framecnt_t cnt)
Definition: audiosource.cc:321
framecnt_t length() const
Definition: region.h:114
framepos_t start() const
Definition: region.h:113
int finish(boost::shared_ptr< ARDOUR::Region >, ARDOUR::SourceList &, std::string region_name="")
Definition: filter.cc:88
int run(boost::shared_ptr< ARDOUR::Region >, Progress *)
Definition: reverse.cc:42
std::vector< boost::shared_ptr< Source > > SourceList
Definition: types.h:520