diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-06-02 21:41:35 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-06-02 21:41:35 +0000 |
commit | 449aab3c465bbbf66d221fac3d7ea559f1720357 (patch) | |
tree | 6843cc40c88250a132acac701271f1504cd2df04 /libs/ardour/reverse.cc | |
parent | 9c0d7d72d70082a54f823cd44c0ccda5da64bb6f (diff) |
rollback to 3428, before the mysterious removal of libs/* at 3431/3432
git-svn-id: svn://localhost/ardour2/branches/3.0@3435 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/reverse.cc')
-rw-r--r-- | libs/ardour/reverse.cc | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc new file mode 100644 index 0000000000..02ec2924b0 --- /dev/null +++ b/libs/ardour/reverse.cc @@ -0,0 +1,130 @@ +/* + Copyright (C) 2004 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include <algorithm> + +#include <pbd/basename.h> + +#include <ardour/types.h> +#include <ardour/reverse.h> +#include <ardour/audiofilesource.h> +#include <ardour/session.h> +#include <ardour/audioregion.h> + +#include "i18n.h" + +using namespace std; +using namespace ARDOUR; + +Reverse::Reverse (Session& s) + : Filter (s) +{ +} + +Reverse::~Reverse () +{ +} + +int +Reverse::run (boost::shared_ptr<Region> r) +{ + SourceList nsrcs; + SourceList::iterator si; + nframes_t blocksize = 256 * 1024; + Sample* buf = 0; + nframes_t fpos; + nframes_t fstart; + nframes_t to_read; + int ret = -1; + + boost::shared_ptr<AudioRegion> region = boost::dynamic_pointer_cast<AudioRegion>(r); + if (!region) + return ret; + + /* create new sources */ + + if (make_new_sources (region, nsrcs)) { + goto out; + } + + fstart = region->start(); + + if (blocksize > region->length()) { + blocksize = region->length(); + } + + fpos = max (fstart, (fstart + region->length() - blocksize)); + buf = new Sample[blocksize]; + to_read = blocksize; + + /* now read it backwards */ + + while (to_read) { + + uint32_t n; + + for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) { + + /* read it in */ + + if (region->audio_source (n)->read (buf, fpos, to_read) != to_read) { + goto out; + } + + /* swap memory order */ + + for (nframes_t i = 0; i < to_read/2; ++i) { + swap (buf[i],buf[to_read-1-i]); + } + + /* write it out */ + + boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si)); + + if (asrc && asrc->write (buf, to_read) != to_read) { + goto out; + } + } + + if (fpos > fstart + blocksize) { + fpos -= to_read; + to_read = blocksize; + } else { + to_read = fpos - fstart; + fpos = fstart; + } + }; + + ret = finish (region, nsrcs); + + out: + + if (buf) { + delete [] buf; + } + + if (ret) { + for (si = nsrcs.begin(); si != nsrcs.end(); ++si) { + boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si)); + asrc->mark_for_remove (); + } + } + + return ret; +} |