committed INCOMPLETE 24bit filesource support

git-svn-id: svn://localhost/trunk/ardour2@316 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Jesse Chappell 2006-02-10 23:53:12 +00:00
parent 17cb448b1d
commit 9ab70fb552
34 changed files with 623 additions and 176 deletions

View file

@ -50,6 +50,7 @@ location.cc
mtc_slave.cc
named_selection.cc
panner.cc
pcm_utils.cc
playlist.cc
playlist_factory.cc
plugin.cc

View file

@ -63,7 +63,7 @@ class AudioTrack : public Route
jack_nframes_t update_total_latency();
void set_latency_delay (jack_nframes_t);
int export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame);
int export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t nframes, jack_nframes_t end_frame);
sigc::signal<void,void*> diskstream_changed;

View file

@ -60,7 +60,7 @@ class AudioPlaylist : public ARDOUR::Playlist
void clear (bool with_delete = false, bool with_save = true);
jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0);
int set_state (const XMLNode&);
UndoAction get_memento() const;

View file

@ -104,13 +104,13 @@ class AudioRegion : public Region
jack_nframes_t read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t offset, jack_nframes_t cnt, uint32_t chan_n=0, double samples_per_unit= 1.0) const;
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n = 0,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const;
jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt, uint32_t chan_n=0) const;
XMLNode& state (bool);
@ -199,7 +199,7 @@ class AudioRegion : public Region
void rename_after_first_edit ();
jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n = 0,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const;

View file

@ -87,7 +87,7 @@ class Crossfade : public Stateful, public StateManager
ARDOUR::AudioRegion& out() const { return *_out; }
jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0);

View file

@ -31,7 +31,7 @@ namespace ARDOUR {
class DestructiveFileSource : public FileSource {
public:
DestructiveFileSource (std::string path, jack_nframes_t rate, bool repair_first = false);
DestructiveFileSource (std::string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatInt24);
DestructiveFileSource (const XMLNode&, jack_nframes_t rate);
~DestructiveFileSource ();
@ -41,7 +41,7 @@ class DestructiveFileSource : public FileSource {
void mark_capture_end ();
void clear_capture_marks();
jack_nframes_t write (Sample *src, jack_nframes_t cnt);
jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
private:
static jack_nframes_t xfade_frames;
@ -52,10 +52,10 @@ class DestructiveFileSource : public FileSource {
bool _capture_start;
bool _capture_end;
jack_nframes_t capture_start_frame;
jack_nframes_t file_pos;
jack_nframes_t file_pos; // unit is frames
Sample* xfade_buf;
jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir);
jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir, char * workbuf);
};

View file

@ -362,10 +362,10 @@ class DiskStream : public Stateful, public sigc::trackable
/* the two central butler operations */
int do_flush (bool force = false);
int do_refill (Sample *mixdown_buffer, float *gain_buffer);
int do_flush (char * workbuf, bool force = false);
int do_refill (Sample *mixdown_buffer, float *gain_buffer, char *workbuf);
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt,
int read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
ChannelInfo& channel_info, int channel, bool reversed);
uint32_t i_am_the_modifier;

View file

@ -44,13 +44,19 @@ namespace ARDOUR {
class FileSource : public Source {
public:
FileSource (string path, jack_nframes_t rate, bool repair_first = false);
enum SampleFormat
{
FormatFloat = 0,
FormatInt24
};
FileSource (string path, jack_nframes_t rate, bool repair_first = false, SampleFormat samp_format=FormatFloat);
FileSource (const XMLNode&, jack_nframes_t rate);
~FileSource ();
jack_nframes_t length() const { return _length; }
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
jack_nframes_t write (Sample *src, jack_nframes_t cnt);
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
void mark_for_remove();
string peak_path(string audio_path);
string old_peak_path(string audio_path);
@ -85,7 +91,9 @@ class FileSource : public Source {
bool is_bwf;
off64_t data_offset;
string _take_id;
SampleFormat _sample_format;
int _sample_size;
static char bwf_country_code[3];
static char bwf_organization_code[4];
static char bwf_serial_number[13];
@ -143,8 +151,27 @@ class FileSource : public Source {
} header;
int init (string, bool must_exist, jack_nframes_t);
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
ssize_t file_write (Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf) {
switch (_sample_format) {
case FormatInt24: return write_pcm_24(src, framepos, cnt, workbuf);
default: return write_float(src, framepos, cnt, workbuf);
};
}
ssize_t file_read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
switch (_sample_format) {
case FormatInt24: return read_pcm_24(dst, start, cnt, workbuf);
default: return read_float(dst, start, cnt, workbuf);
};
}
ssize_t write_float(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
ssize_t read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
ssize_t write_pcm_24(Sample *src, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf);
ssize_t read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
int discover_chunks (bool silent);
ChunkInfo* lookup_chunk (string name);

View file

@ -0,0 +1,42 @@
/*
Copyright (C) 2006 Paul Davis , portions Erik de Castro Lopo
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.
$Id$
*/
#ifndef __ardour_pcm_utils_h__
#define __ardour_pcm_utils_h__
typedef void tribyte ;
#define SIZEOF_TRIBYTE 3
#define BET2H_INT_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
#define LET2H_INT_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
void pcm_let2f_array (tribyte *src, int count, float *dest);
void pcm_bet2f_array (tribyte *src, int count, float *dest);
void pcm_f2let_array (float *src, tribyte *dest, int count);
void pcm_f2let_clip_array (float *src, tribyte *dest, int count);
void pcm_f2bet_array (const float *src, tribyte *dest, int count);
void pcm_f2bet_clip_array (const float *src, tribyte *dest, int count);
#endif

View file

@ -53,7 +53,7 @@ class Playlist : public Stateful, public StateManager {
Playlist (const Playlist&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, string name, bool hidden = false);
virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
virtual jack_nframes_t read (Sample *dst, Sample *mixdown, float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n=0) = 0;
virtual void clear (bool with_delete = false, bool with_save = true);
virtual void dump () const;
virtual UndoAction get_memento() const = 0;

View file

@ -141,7 +141,7 @@ class Region : public Stateful, public StateManager
}
virtual jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t position, jack_nframes_t cnt,
float *gain_buffer, char * workbuf, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n = 0,
jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const = 0;

View file

@ -923,6 +923,15 @@ class Session : public sigc::trackable, public Stateful
gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
pan_t** pan_automation_buffer() const { return _pan_automation_buffer; }
/* buffers for conversion */
enum RunContext {
ButlerContext = 0,
TransportContext,
ExportContext
};
char * conversion_buffer(RunContext context) { return _conversion_buffers[context]; }
/* VST support */
static long vst_callback (AEffect* effect,
@ -998,6 +1007,7 @@ class Session : public sigc::trackable, public Stateful
jack_nframes_t last_stop_frame;
vector<Sample *> _passthru_buffers;
vector<Sample *> _silent_buffers;
map<RunContext,char*> _conversion_buffers;
jack_nframes_t current_block_size;
jack_nframes_t _worst_output_latency;
jack_nframes_t _worst_input_latency;

View file

@ -34,7 +34,7 @@ class SndFileSource : public Source {
~SndFileSource ();
jack_nframes_t length() const { return _info.frames; }
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
void mark_for_remove() {} // we never remove external sndfiles
string peak_path(string audio_path);
string old_peak_path(string audio_path);
@ -54,7 +54,7 @@ class SndFileSource : public Source {
string _path;
void init (const string &str, bool build_peak);
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const;
jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
};
}; /* namespace EDL */

View file

@ -64,11 +64,11 @@ class Source : public Stateful, public sigc::trackable
return _length;
}
virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const {
virtual jack_nframes_t read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const {
return 0;
}
virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt) {
virtual jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf) {
return 0;
}
@ -134,7 +134,7 @@ class Source : public Stateful, public sigc::trackable
void build_peaks_from_scratch ();
int do_build_peak (jack_nframes_t, jack_nframes_t);
virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const = 0;
virtual jack_nframes_t read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const = 0;
virtual string peak_path(string audio_path) = 0;
virtual string old_peak_path(string audio_path) = 0;

View file

@ -139,7 +139,7 @@ struct RegionSortByLayer {
};
jack_nframes_t
AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t start,
AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t start,
jack_nframes_t cnt, unsigned chan_n)
{
jack_nframes_t ret = cnt;
@ -209,13 +209,13 @@ AudioPlaylist::read (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, ja
vector<Crossfade*>& x (relevant_xfades[*l]);
for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) {
(*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n, read_frames, skip_frames);
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n, read_frames, skip_frames);
_read_data_count += (*i)->read_data_count();
}
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) {
(*i)->read_at (buf, mixdown_buffer, gain_buffer, start, cnt, chan_n);
(*i)->read_at (buf, mixdown_buffer, gain_buffer, workbuf, start, cnt, chan_n);
/* don't JACK up _read_data_count, since its the same data as we just
read from the regions, and the OS should handle that for us.

View file

@ -768,7 +768,7 @@ AudioTrack::set_name (string str, void *src)
}
int
AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes)
AudioTrack::export_stuff (vector<Sample*>& buffers, char * workbuf, uint32_t nbufs, jack_nframes_t start, jack_nframes_t nframes)
{
gain_t gain_automation[nframes];
gain_t gain_buffer[nframes];
@ -781,7 +781,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
RWLockMonitor rlock (redirect_lock, false, __LINE__, __FILE__);
if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, start, nframes) != nframes) {
if (diskstream->playlist()->read (buffers[0], mix_buffer, gain_buffer, workbuf, start, nframes) != nframes) {
return -1;
}
@ -791,7 +791,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
++bi;
for (; bi != buffers.end(); ++bi, ++n) {
if (n < diskstream->n_channels()) {
if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, start, nframes, n) != nframes) {
if (diskstream->playlist()->read ((*bi), mix_buffer, gain_buffer, workbuf, start, nframes, n) != nframes) {
return -1;
}
b = (*bi);

View file

@ -462,22 +462,22 @@ AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t of
}
jack_nframes_t
AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t position,
AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t position,
jack_nframes_t cnt,
uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const
{
return _read_at (sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames);
return _read_at (sources, buf, mixdown_buffer, gain_buffer, workbuf, position, cnt, chan_n, read_frames, skip_frames);
}
jack_nframes_t
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, jack_nframes_t position,
AudioRegion::master_read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf, jack_nframes_t position,
jack_nframes_t cnt, uint32_t chan_n) const
{
return _read_at (master_sources, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, 0, 0);
return _read_at (master_sources, buf, mixdown_buffer, gain_buffer, workbuf, position, cnt, chan_n, 0, 0);
}
jack_nframes_t
AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buffer, float *gain_buffer,
AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buffer, float *gain_buffer, char * workbuf,
jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const
{
@ -522,7 +522,7 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
_read_data_count = 0;
if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read) != to_read) {
if (srcs[chan_n]->read (mixdown_buffer, _start + internal_offset, to_read, workbuf) != to_read) {
return 0; /* "read nothing" */
}
@ -1204,7 +1204,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
if (spec.channels == 1) {
if (sources.front()->read (spec.dataF, _start + spec.pos, to_read) != to_read) {
if (sources.front()->read (spec.dataF, _start + spec.pos, to_read, 0) != to_read) {
goto out;
}
@ -1214,7 +1214,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
for (uint32_t chan = 0; chan < spec.channels; ++chan) {
if (sources[chan]->read (buf, _start + spec.pos, to_read) != to_read) {
if (sources[chan]->read (buf, _start + spec.pos, to_read, 0) != to_read) {
goto out;
}
@ -1276,6 +1276,7 @@ AudioRegion::normalize_to (float target_dB)
{
const jack_nframes_t blocksize = 256 * 1048;
Sample buf[blocksize];
char workbuf[blocksize * 4];
jack_nframes_t fpos;
jack_nframes_t fend;
jack_nframes_t to_read;
@ -1304,7 +1305,7 @@ AudioRegion::normalize_to (float target_dB)
/* read it in */
if (source (n).read (buf, fpos, to_read) != to_read) {
if (source (n).read (buf, fpos, to_read, workbuf) != to_read) {
return;
}

View file

@ -373,7 +373,7 @@ Crossfade::compute (AudioRegion& a, AudioRegion& b, CrossfadeModel model)
jack_nframes_t
Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
float *gain_buffer, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n,
float *gain_buffer, char * workbuf, jack_nframes_t start, jack_nframes_t cnt, uint32_t chan_n,
jack_nframes_t read_frames, jack_nframes_t skip_frames)
{
jack_nframes_t offset;
@ -409,8 +409,8 @@ Crossfade::read_at (Sample *buf, Sample *mixdown_buffer,
offset = start - _position;
_out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
_in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, start, to_write, chan_n, read_frames, skip_frames);
_out->read_at (crossfade_buffer_out, mixdown_buffer, gain_buffer, workbuf, start, to_write, chan_n, read_frames, skip_frames);
_in->read_at (crossfade_buffer_in, mixdown_buffer, gain_buffer, workbuf, start, to_write, chan_n, read_frames, skip_frames);
float* fiv = new float[to_write];
float* fov = new float[to_write];

View file

@ -66,8 +66,8 @@ gain_t* DestructiveFileSource::out_coefficient = 0;
gain_t* DestructiveFileSource::in_coefficient = 0;
jack_nframes_t DestructiveFileSource::xfade_frames = 64;
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first)
: FileSource (path, rate, repair_first)
DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
: FileSource (path, rate, repair_first, samp_format)
{
if (out_coefficient == 0) {
setup_standard_crossfades (rate);
@ -118,7 +118,7 @@ int
DestructiveFileSource::seek (jack_nframes_t frame)
{
// file_pos = data_offset + (sizeof (Sample) * frame);
cerr << _name << " Seek to " << frame << " = " << data_offset + (sizeof (Sample) * frame) << endl;
cerr << _name << " Seek to " << frame << " = " << data_offset + (_sample_size * frame) << endl;
return 0;
}
@ -143,41 +143,37 @@ DestructiveFileSource::clear_capture_marks ()
}
jack_nframes_t
DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in)
DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in, char * workbuf)
{
jack_nframes_t xfade = min (xfade_frames, cnt);
jack_nframes_t xfade_bytes = xfade * sizeof (Sample);
jack_nframes_t nofade = cnt - xfade;
jack_nframes_t nofade_bytes = nofade * sizeof (Sample);
Sample* fade_data = 0;
off_t fade_position = 0;
off_t fade_position = 0; // in frames
ssize_t retval;
if (fade_in) {
fade_position = file_pos;
fade_data = data;
} else {
fade_position = file_pos + nofade_bytes;
fade_position = file_pos + nofade;
fade_data = data + nofade;
}
if (::pread64 (fd, (char *) xfade_buf, xfade_bytes, fade_position) != (off64_t) xfade_bytes) {
if (errno == EAGAIN) {
if ((retval = file_read (xfade_buf, fade_position, xfade, workbuf)) != (ssize_t) xfade) {
if (retval < 0 && errno == EAGAIN) {
/* no data there, so no xfade */
xfade = 0;
xfade_bytes = 0;
nofade = cnt;
nofade_bytes = nofade * sizeof (Sample);
} else {
error << string_compose(_("FileSource: \"%1\" bad read (%2: %3)"), _path, errno, strerror (errno)) << endmsg;
return 0;
}
}
if (nofade && !fade_in) {
cerr << "write " << nofade_bytes << " of prefade OUT data to " << file_pos << " .. " << file_pos + nofade_bytes << endl;
if (::pwrite64 (fd, (char *) data, nofade_bytes, file_pos) != (off64_t) nofade_bytes) {
cerr << "write " << nofade << " frames of prefade OUT data to " << file_pos << " .. " << file_pos + nofade << endl;
if (file_write (data, file_pos, nofade, workbuf) != (ssize_t) nofade) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0;
}
@ -219,17 +215,18 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in)
}
if (xfade) {
cerr << "write " << xfade_bytes << " of xfade data to " << fade_position << " .. " << fade_position + xfade_bytes << endl;
if (::pwrite64 (fd, (char *) xfade_buf, xfade_bytes, fade_position) != (off64_t) xfade_bytes) {
cerr << "write " << xfade << " frames of xfade data to " << fade_position << " .. " << fade_position + xfade << endl;
if (file_write (xfade_buf, fade_position, xfade, workbuf) != (ssize_t) xfade) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0;
}
}
if (fade_in && nofade) {
cerr << "write " << nofade_bytes << " of postfade IN data to " << file_pos + xfade_bytes << " .. "
<< file_pos + xfade_bytes + nofade_bytes << endl;
if (::pwrite64 (fd, (char *) (data + xfade), nofade_bytes, file_pos + xfade_bytes) != (off64_t) nofade_bytes) {
cerr << "write " << nofade << " frames of postfade IN data to " << file_pos + xfade << " .. "
<< file_pos + xfade + nofade << endl;
if (file_write (data + xfade, file_pos + xfade, nofade, workbuf) != (ssize_t) nofade) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
return 0;
}
@ -239,14 +236,13 @@ DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int fade_in)
}
jack_nframes_t
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt)
DestructiveFileSource::write (Sample* data, jack_nframes_t cnt, char * workbuf)
{
cerr << _name << ": write " << cnt << " to " << file_pos << " start ? " << _capture_start << " end ? " << _capture_end << endl;
{
LockMonitor lm (_lock, __LINE__, __FILE__);
int32_t byte_cnt = cnt * sizeof (Sample);
jack_nframes_t oldlen;
if (_capture_start) {
@ -254,11 +250,12 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt)
_capture_end = false;
/* move to the correct location place */
file_pos = data_offset + (capture_start_frame * sizeof (Sample));
cerr << "First byte of capture will be at " << file_pos << endl;
//file_pos = data_offset + (capture_start_frame * sizeof (Sample));
file_pos = capture_start_frame;
if (crossfade (data, cnt, 1) != cnt) {
cerr << "First frame of capture will be at " << file_pos << endl;
if (crossfade (data, cnt, 1, workbuf) != cnt) {
return 0;
}
@ -266,12 +263,11 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt)
_capture_start = false;
_capture_end = false;
if (crossfade (data, cnt, 0) != cnt) {
if (crossfade (data, cnt, 0, workbuf) != cnt) {
return 0;
}
} else {
if (::pwrite64 (fd, (char *) data, byte_cnt, file_pos) != (off64_t) byte_cnt) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
if (file_write(data, file_pos, cnt, workbuf) != (ssize_t) cnt) {
return 0;
}
}
@ -280,8 +276,7 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt)
if (file_pos + cnt > _length) {
_length += cnt;
}
_write_data_count = byte_cnt;
file_pos += byte_cnt;
file_pos += cnt;
cerr << "at end of write, file_pos = " << file_pos << endl;

View file

@ -992,6 +992,7 @@ DiskStream::overwrite_existing_buffers ()
{
Sample* mixdown_buffer;
float* gain_buffer;
char * workbuf;
int ret = -1;
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
@ -1002,7 +1003,8 @@ DiskStream::overwrite_existing_buffers ()
mixdown_buffer = new Sample[size];
gain_buffer = new float[size];
workbuf = new char[size*4];
/* reduce size so that we can fill the buffer correctly. */
size--;
@ -1027,7 +1029,7 @@ DiskStream::overwrite_existing_buffers ()
jack_nframes_t to_read = size - overwrite_offset;
if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer,
if (read ((*chan).playback_buf->buffer() + overwrite_offset, mixdown_buffer, gain_buffer, workbuf,
start, to_read, *chan, n, reversed)) {
error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
_id, size, playback_sample) << endmsg;
@ -1038,7 +1040,7 @@ DiskStream::overwrite_existing_buffers ()
cnt -= to_read;
if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer,
if (read ((*chan).playback_buf->buffer(), mixdown_buffer, gain_buffer, workbuf,
start, cnt, *chan, n, reversed)) {
error << string_compose(_("DiskStream %1: when refilling, cannot read %2 from playlist at frame %3"),
_id, size, playback_sample) << endmsg;
@ -1053,6 +1055,7 @@ DiskStream::overwrite_existing_buffers ()
pending_overwrite = false;
delete [] gain_buffer;
delete [] mixdown_buffer;
delete [] workbuf;
return ret;
}
@ -1076,9 +1079,9 @@ DiskStream::seek (jack_nframes_t frame, bool complete_refill)
file_frame = frame;
if (complete_refill) {
while ((ret = do_refill (0, 0)) > 0);
while ((ret = do_refill (0, 0, 0)) > 0);
} else {
ret = do_refill (0, 0);
ret = do_refill (0, 0, 0);
}
return ret;
@ -1113,8 +1116,7 @@ DiskStream::internal_playback_seek (jack_nframes_t distance)
}
int
DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_nframes_t& start, jack_nframes_t cnt,
DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, char * workbuf, jack_nframes_t& start, jack_nframes_t cnt,
ChannelInfo& channel_info, int channel, bool reversed)
{
jack_nframes_t this_read = 0;
@ -1171,7 +1173,7 @@ DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_
this_read = min(cnt,this_read);
if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, start, this_read, channel) != this_read) {
if (_playlist->read (buf+offset, mixdown_buffer, gain_buffer, workbuf, start, this_read, channel) != this_read) {
error << string_compose(_("DiskStream %1: cannot read %2 from playlist at frame %3"), _id, this_read,
start) << endmsg;
return -1;
@ -1205,13 +1207,14 @@ DiskStream::read (Sample* buf, Sample* mixdown_buffer, float* gain_buffer, jack_
}
int
DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer, char * workbuf)
{
int32_t ret = 0;
jack_nframes_t to_read;
RingBufferNPT<Sample>::rw_vector vector;
bool free_mixdown;
bool free_gain;
bool free_workbuf;
bool reversed = (_visible_speed * _session.transport_speed()) < 0.0f;
jack_nframes_t total_space;
jack_nframes_t zero_fill;
@ -1346,6 +1349,13 @@ DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
free_gain = false;
}
if (workbuf == 0) {
workbuf = new char[disk_io_chunk_frames * 4];
free_workbuf = true;
} else {
free_workbuf = false;
}
jack_nframes_t file_frame_tmp = 0;
for (chan_n = 0, i = channels.begin(); i != channels.end(); ++i, ++chan_n) {
@ -1378,7 +1388,7 @@ DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
if (to_read) {
if (read (buf1, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
if (read (buf1, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
ret = -1;
goto out;
}
@ -1396,7 +1406,7 @@ DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
so read some or all of vector.len[1] as well.
*/
if (read (buf2, mixdown_buffer, gain_buffer, file_frame_tmp, to_read, chan, chan_n, reversed)) {
if (read (buf2, mixdown_buffer, gain_buffer, workbuf, file_frame_tmp, to_read, chan, chan_n, reversed)) {
ret = -1;
goto out;
}
@ -1419,12 +1429,15 @@ DiskStream::do_refill (Sample* mixdown_buffer, float* gain_buffer)
if (free_gain) {
delete [] gain_buffer;
}
if (free_workbuf) {
delete [] workbuf;
}
return ret;
}
int
DiskStream::do_flush (bool force_flush)
DiskStream::do_flush (char * workbuf, bool force_flush)
{
uint32_t to_write;
int32_t ret = 0;
@ -1470,7 +1483,7 @@ DiskStream::do_flush (bool force_flush)
to_write = min (disk_io_chunk_frames, (jack_nframes_t) vector.len[0]);
if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write) != to_write) {
if ((!(*chan).write_source) || (*chan).write_source->write (vector.buf[0], to_write, workbuf) != to_write) {
error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
return -1;
}
@ -1486,7 +1499,7 @@ DiskStream::do_flush (bool force_flush)
to_write = min ((jack_nframes_t)(disk_io_chunk_frames - to_write), (jack_nframes_t) vector.len[1]);
if ((*chan).write_source->write (vector.buf[1], to_write) != to_write) {
if ((*chan).write_source->write (vector.buf[1], to_write, workbuf) != to_write) {
error << string_compose(_("DiskStream %1: cannot write to disk"), _id) << endmsg;
return -1;
}
@ -1539,7 +1552,7 @@ DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture
*/
while (more_work && !err) {
switch (do_flush (true)) {
switch (do_flush ( _session.conversion_buffer(Session::TransportContext), true)) {
case 0:
more_work = false;
break;

View file

@ -65,6 +65,7 @@
#include <ardour/filesource.h>
#include <ardour/session.h>
#include <ardour/cycle_timer.h>
#include <ardour/pcm_utils.h>
#include "i18n.h"
@ -101,10 +102,16 @@ FileSource::set_search_path (string p)
search_path = p;
}
FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first)
FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first, SampleFormat samp_format)
{
/* constructor used when the file cannot already exist or might be damaged */
_sample_format = samp_format;
if (samp_format == FormatInt24) {
_sample_size = 3;
} else {
_sample_size = sizeof(float);
}
if (repair_first && repair (pathstr, rate)) {
throw failed_constructor ();
}
@ -119,6 +126,9 @@ FileSource::FileSource (string pathstr, jack_nframes_t rate, bool repair_first)
FileSource::FileSource (const XMLNode& node, jack_nframes_t rate)
: Source (node)
{
_sample_format = FormatFloat;
_sample_size = sizeof(float);
if (set_state (node)) {
throw failed_constructor();
}
@ -558,12 +568,19 @@ FileSource::fill_header (jack_nframes_t rate)
memcpy (header.format.id, "fmt ", 4);
header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk);
header.format.formatTag = 3; /* little-endian IEEE float format */
if (_sample_format == FormatInt24) {
header.format.formatTag = 1; // PCM
header.format.nBlockAlign = 3;
header.format.nBitsPerSample = 24;
}
else {
header.format.formatTag = 3; /* little-endian IEEE float format */
header.format.nBlockAlign = 4;
header.format.nBitsPerSample = 32;
}
header.format.nChannels = 1; /* mono */
header.format.nSamplesPerSec = rate;
header.format.nAvgBytesPerSec = rate * sizeof (Sample);
header.format.nBlockAlign = 4;
header.format.nBitsPerSample = 32;
/* DATA */
@ -788,9 +805,18 @@ FileSource::read_broadcast_data (ChunkInfo& info)
int
FileSource::check_header (jack_nframes_t rate, bool silent)
{
if (header.format.formatTag != 3) { /* IEEE float */
if (header.format.formatTag == 1 && header.format.nBitsPerSample == 24) {
// 24 bit PCM
_sample_format = FormatInt24;
_sample_size = 3;
} else if (header.format.formatTag == 3) {
/* IEEE float */
_sample_format = FormatFloat;
_sample_size = 4;
}
else {
if (!silent) {
error << string_compose(_("FileSource \"%1\" does not use floating point format.\n"
error << string_compose(_("FileSource \"%1\" does not use valid sample format.\n"
"This is probably a programming error."), _path) << endmsg;
}
return -1;
@ -932,73 +958,38 @@ FileSource::mark_for_remove ()
}
jack_nframes_t
FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
FileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
LockMonitor lm (_lock, __LINE__, __FILE__);
return read_unlocked (dst, start, cnt);
return read_unlocked (dst, start, cnt, workbuf);
}
jack_nframes_t
FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
FileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
int32_t byte_cnt;
int nread;
byte_cnt = cnt * sizeof (Sample);
if ((nread = pread (fd, (char *) dst, byte_cnt, data_offset + (start * sizeof (Sample)))) != (off64_t) byte_cnt) {
cerr << "FileSource: \""
<< _path
<< "\" bad read at frame "
<< start
<< ", of "
<< cnt
<< " (bytes="
<< byte_cnt
<< ") frames [length = " << _length
<< " eor = " << start + cnt << "] ("
<< strerror (errno)
<< ") (read "
<< nread / sizeof (Sample)
<< " (bytes=" <<nread
<< ")) pos was"
<< data_offset
<< '+'
<< start << '*' << sizeof(Sample)
<< " = " << data_offset + (start * sizeof(Sample))
<< endl;
if (file_read(dst, start, cnt, workbuf) != (ssize_t) cnt) {
return 0;
}
if (header.bigendian != WE_ARE_BIGENDIAN) {
swap_endian(dst, cnt);
}
_read_data_count = byte_cnt;
return cnt;
}
jack_nframes_t
FileSource::write (Sample *data, jack_nframes_t cnt)
FileSource::write (Sample *data, jack_nframes_t cnt, char * workbuf)
{
{
LockMonitor lm (_lock, __LINE__, __FILE__);
int32_t byte_cnt = cnt * sizeof (Sample);
int32_t byte_pos = data_offset + (_length * sizeof (Sample));
jack_nframes_t oldlen;
if (::pwrite64 (fd, (char *) data, byte_cnt, byte_pos) != (off64_t) byte_cnt) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
int32_t frame_pos = _length;
if (file_write(data, frame_pos, cnt, workbuf) != (ssize_t) cnt) {
return 0;
}
oldlen = _length;
_length += cnt;
_write_data_count = byte_cnt;
if (_build_peakfiles) {
PeakBuildRecord *pbr = 0;
@ -1031,6 +1022,152 @@ FileSource::write (Sample *data, jack_nframes_t cnt)
return cnt;
}
ssize_t
FileSource::write_float(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
{
int32_t byte_cnt = cnt * _sample_size;
int32_t byte_pos = data_offset + (framepos * _sample_size);
ssize_t retval;
if ((retval = ::pwrite64 (fd, (char *) data, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
if (retval > 0) {
return retval / _sample_size;
}
else {
return retval;
}
}
_write_data_count = byte_cnt;
return cnt;
}
ssize_t
FileSource::read_float (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
ssize_t nread;
ssize_t byte_cnt = (ssize_t) cnt * sizeof (Sample);
if ((nread = pread (fd, (char *) dst, byte_cnt, data_offset + (start * _sample_size))) != byte_cnt) {
cerr << "FileSource: \""
<< _path
<< "\" bad read at frame "
<< start
<< ", of "
<< cnt
<< " (bytes="
<< byte_cnt
<< ") frames [length = " << _length
<< " eor = " << start + cnt << "] ("
<< strerror (errno)
<< ") (read "
<< nread / sizeof (Sample)
<< " (bytes=" <<nread
<< ")) pos was"
<< data_offset
<< '+'
<< start << '*' << sizeof(Sample)
<< " = " << data_offset + (start * sizeof(Sample))
<< endl;
if (nread > 0) {
return nread / _sample_size;
}
else {
return nread;
}
}
if (header.bigendian != WE_ARE_BIGENDIAN) {
swap_endian(dst, cnt);
}
_read_data_count = byte_cnt;
return cnt;
}
ssize_t
FileSource::write_pcm_24(Sample *data, jack_nframes_t framepos, jack_nframes_t cnt, char * workbuf)
{
int32_t byte_cnt = cnt * _sample_size;
int32_t byte_pos = data_offset + (framepos * _sample_size);
ssize_t retval;
// convert to int24
if (header.bigendian) {
pcm_f2bet_clip_array (data, workbuf, cnt);
} else {
pcm_f2let_clip_array (data, workbuf, cnt);
}
if ((retval = ::pwrite64 (fd, (char *) workbuf, byte_cnt, byte_pos)) != (ssize_t) byte_cnt) {
error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg;
if (retval > 0) {
return retval / _sample_size;
}
else {
return retval;
}
}
return (ssize_t) cnt;
}
ssize_t
FileSource::read_pcm_24 (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
ssize_t nread;
ssize_t byte_cnt = (ssize_t) cnt * _sample_size;
if ((nread = pread (fd, (char *) workbuf, byte_cnt, data_offset + (start * _sample_size))) != byte_cnt) {
cerr << "FileSource: \""
<< _path
<< "\" bad 24bit read at frame "
<< start
<< ", of "
<< cnt
<< " (bytes="
<< byte_cnt
<< ") frames [length = " << _length
<< " eor = " << start + cnt << "] ("
<< strerror (errno)
<< ") (read "
<< nread / sizeof (Sample)
<< " (bytes=" <<nread
<< ")) pos was"
<< data_offset
<< '+'
<< start << '*' << sizeof(Sample)
<< " = " << data_offset + (start * sizeof(Sample))
<< endl;
if (nread > 0) {
return nread / _sample_size;
}
else {
return nread;
}
}
// convert from 24bit->float
if (header.bigendian) {
pcm_bet2f_array (workbuf, cnt, dst);
} else {
pcm_let2f_array (workbuf, cnt, dst);
}
_read_data_count = byte_cnt;
return (ssize_t) cnt;
}
bool
FileSource::is_empty (string path)
{

View file

@ -42,7 +42,7 @@
using namespace ARDOUR;
#define BLOCKSIZE 2048U
#define BLOCKSIZE 4096U
int
Session::import_audiofile (import_status& status)
@ -53,6 +53,7 @@ Session::import_audiofile (import_status& status)
SF_INFO info;
float *data = 0;
Sample **channel_data = 0;
char * workbuf = 0;
long nfiles = 0;
long n;
string basepath;
@ -147,7 +148,8 @@ Session::import_audiofile (import_status& status)
data = new float[BLOCKSIZE * info.channels];
channel_data = new Sample * [ info.channels ];
workbuf = new char[BLOCKSIZE * 4];
for (n = 0; n < info.channels; ++n) {
channel_data[n] = new Sample[BLOCKSIZE];
}
@ -178,7 +180,7 @@ Session::import_audiofile (import_status& status)
/* flush to disk */
for (chn = 0; chn < info.channels; ++chn) {
newfiles[chn]->write (channel_data[chn], nread);
newfiles[chn]->write (channel_data[chn], nread, workbuf);
}
so_far += nread;
@ -245,7 +247,10 @@ Session::import_audiofile (import_status& status)
if (data) {
delete [] data;
}
if (workbuf) {
delete [] workbuf;
}
if (channel_data) {
for (n = 0; n < info.channels; ++n) {
delete [] channel_data[n];

View file

@ -599,7 +599,7 @@ PluginInsert::state (bool full)
node->add_property("id", string(buf));
if (_plugins[0]->state_node_name() == "ladspa") {
char buf[32];
snprintf (buf, 31, "%d", _plugins[0]->get_info().unique_id);
snprintf (buf, 31, "%ld", _plugins[0]->get_info().unique_id);
node->add_property("unique-id", string(buf));
}
node->add_property("count", string_compose("%1", _plugins.size()));

178
libs/ardour/pcm_utils.cc Normal file
View file

@ -0,0 +1,178 @@
/*
Copyright (C) 2006 Paul Davis , portions Erik de Castro Lopo
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.
$Id$
*/
#include <ardour/pcm_utils.h>
#include <cmath>
using namespace std;
// TODO: check CPU_CLIPS_POSITIVE and CPU_CLIPS_NEGATIVE with scons
#define CPU_CLIPS_NEGATIVE 0
#define CPU_CLIPS_POSITIVE 0
/* these routines deal with 24 bit int handling (tribytes)
* originally from libsndfile, but modified. XXX - Copyright Erik de Castro Lopo
*/
void
pcm_let2f_array (tribyte *src, int count, float *dest)
{
/* Special normfactor because tribyte value is read into an int. */
static const float normfact = 1.0 / ((float) 0x80000000);
unsigned char *ucptr ;
int value ;
ucptr = ((unsigned char*) src) + 3 * count ;
while (--count >= 0)
{ ucptr -= 3 ;
value = LET2H_INT_PTR (ucptr) ;
dest [count] = ((float) value) * normfact ;
} ;
} /* let2f_array */
void
pcm_bet2f_array (tribyte *src, int count, float *dest)
{
/* Special normfactor because tribyte value is read into an int. */
static const float normfact = 1.0 / ((float) 0x80000000);
unsigned char *ucptr ;
int value ;
ucptr = ((unsigned char*) src) + 3 * count ;
while (--count >= 0)
{ ucptr -= 3 ;
value = BET2H_INT_PTR (ucptr) ;
dest [count] = ((float) value) * normfact ;
} ;
} /* bet2f_array */
void
pcm_f2let_array (float *src, tribyte *dest, int count)
{
static const float normfact = (1.0 * 0x7FFFFF);
unsigned char *ucptr ;
int value ;
ucptr = ((unsigned char*) dest) + 3 * count ;
while (count)
{ count -- ;
ucptr -= 3 ;
value = lrintf (src [count] * normfact) ;
ucptr [0] = value ;
ucptr [1] = value >> 8 ;
ucptr [2] = value >> 16 ;
} ;
} /* f2let_array */
void
pcm_f2let_clip_array (float *src, tribyte *dest, int count)
{
static const float normfact = (8.0 * 0x10000000);
unsigned char *ucptr ;
float scaled_value ;
int value ;
ucptr = ((unsigned char*) dest) + 3 * count ;
while (count)
{ count -- ;
ucptr -= 3 ;
scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
{ ucptr [0] = 0xFF ;
ucptr [1] = 0xFF ;
ucptr [2] = 0x7F ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
{ ucptr [0] = 0x00 ;
ucptr [1] = 0x00 ;
ucptr [2] = 0x80 ;
continue ;
} ;
value = lrintf (scaled_value) ;
ucptr [0] = value >> 8 ;
ucptr [1] = value >> 16 ;
ucptr [2] = value >> 24 ;
} ;
} /* f2let_clip_array */
void
pcm_f2bet_array (const float *src, tribyte *dest, int count)
{
static const float normfact = (1.0 * 0x7FFFFF);
unsigned char *ucptr ;
int value ;
ucptr = ((unsigned char*) dest) + 3 * count ;
while (--count >= 0)
{ ucptr -= 3 ;
value = lrintf (src [count] * normfact) ;
ucptr [0] = value >> 16 ;
ucptr [1] = value >> 8 ;
ucptr [2] = value ;
} ;
} /* f2bet_array */
void
pcm_f2bet_clip_array (const float *src, tribyte *dest, int count)
{
static const float normfact = (8.0 * 0x10000000);
unsigned char *ucptr ;
float scaled_value ;
int value ;
ucptr = ((unsigned char*) dest) + 3 * count ;
while (--count >= 0)
{ ucptr -= 3 ;
scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
{ ucptr [0] = 0x7F ;
ucptr [1] = 0xFF ;
ucptr [2] = 0xFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
{ ucptr [0] = 0x80 ;
ucptr [1] = 0x00 ;
ucptr [2] = 0x00 ;
continue ;
} ;
value = lrint (scaled_value) ;
ucptr [0] = value >> 24 ;
ucptr [1] = value >> 16 ;
ucptr [2] = value >> 8 ;
} ;
} /* f2bet_clip_array */
//@@@@@@@

View file

@ -273,7 +273,7 @@ Plugin::get_presets()
lrdf_uris* set_uris = lrdf_get_setting_uris(unique_id());
if (set_uris) {
for (uint32_t i = 0; i < set_uris->count; ++i) {
for (uint32_t i = 0; i < (uint32_t) set_uris->count; ++i) {
if (char* label = lrdf_get_label(set_uris->items[i])) {
labels.push_back(label);
presets[label] = set_uris->items[i];
@ -294,10 +294,10 @@ Plugin::load_preset(const string preset_label)
lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str());
if (defs) {
for (uint32_t i = 0; i < defs->count; ++i) {
for (uint32_t i = 0; i < (uint32_t) defs->count; ++i) {
// The defs->items[i].pid < defs->count check is to work around
// a bug in liblrdf that saves invalid values into the presets file.
if (((uint32_t) defs->items[i].pid < defs->count) && parameter_is_input (defs->items[i].pid)) {
if (((uint32_t) defs->items[i].pid < (uint32_t) defs->count) && parameter_is_input (defs->items[i].pid)) {
set_parameter(defs->items[i].pid, defs->items[i].value);
}
}

View file

@ -49,6 +49,7 @@ Reverse::run (AudioRegion& region)
AudioRegion::SourceList::iterator si;
const jack_nframes_t blocksize = 256 * 1048;
Sample buf[blocksize];
char * workbuf = 0;;
jack_nframes_t fpos;
jack_nframes_t fend;
jack_nframes_t fstart;
@ -61,6 +62,8 @@ Reverse::run (AudioRegion& region)
goto out;
}
workbuf = new char[blocksize * 4];
fend = region.start() + region.length();
fstart = region.start();
@ -82,7 +85,7 @@ Reverse::run (AudioRegion& region)
/* read it in */
if (region.source (n).read (buf, fpos, to_read) != to_read) {
if (region.source (n).read (buf, fpos, to_read, workbuf) != to_read) {
goto out;
}
@ -94,7 +97,7 @@ Reverse::run (AudioRegion& region)
/* write it out */
if ((*si)->write (buf, to_read) != to_read) {
if ((*si)->write (buf, to_read, workbuf) != to_read) {
goto out;
}
}
@ -120,6 +123,9 @@ Reverse::run (AudioRegion& region)
delete *si;
}
}
if (workbuf) {
delete [] workbuf;
}
return ret;
}

View file

@ -389,6 +389,10 @@ Session::~Session ()
free(*i);
}
for (map<RunContext,char*>::iterator i = _conversion_buffers.begin(); i != _conversion_buffers.end(); ++i) {
delete [] (i->second);
}
#undef TRACK_DESTRUCTION
#ifdef TRACK_DESTRUCTION
cerr << "delete named selections\n";
@ -1867,7 +1871,7 @@ void
Session::add_diskstream (DiskStream* dstream)
{
/* need to do this in case we're rolling at the time, to prevent false underruns */
dstream->do_refill(0, 0);
dstream->do_refill(0, 0, 0);
{
RWLockMonitor lm (diskstream_lock, true, __LINE__, __FILE__);
@ -3408,6 +3412,7 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
jack_nframes_t this_chunk;
jack_nframes_t to_do;
vector<Sample*> buffers;
char * workbuf = 0;
const jack_nframes_t chunk_size = (256 * 1024)/4;
atomic_set (&processing_prohibited, 1);
@ -3470,18 +3475,20 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
#endif
buffers.push_back (b);
}
workbuf = new char[chunk_size * 4];
while (to_do && !itt.cancel) {
this_chunk = min (to_do, chunk_size);
if (track.export_stuff (buffers, nchans, start, this_chunk)) {
if (track.export_stuff (buffers, workbuf, nchans, start, this_chunk)) {
goto out;
}
uint32_t n = 0;
for (vector<Source*>::iterator src=srcs.begin(); src != srcs.end(); ++src, ++n) {
if ((*src)->write (buffers[n], this_chunk) != this_chunk) {
if ((*src)->write (buffers[n], this_chunk, workbuf) != this_chunk) {
goto out;
}
}
@ -3525,6 +3532,10 @@ Session::write_one_track (AudioTrack& track, jack_nframes_t start, jack_nframes_
free(*i);
}
if (workbuf) {
delete [] workbuf;
}
atomic_set (&processing_prohibited, 0);
itt.done = true;

View file

@ -174,6 +174,8 @@ Session::butler_thread_work ()
butler_mixdown_buffer = new Sample[DiskStream::disk_io_frames()];
butler_gain_buffer = new gain_t[DiskStream::disk_io_frames()];
// this buffer is used for temp conversion purposes in filesources
char * conv_buffer = conversion_buffer(ButlerContext);
while (true) {
@ -260,7 +262,7 @@ Session::butler_thread_work ()
// cerr << "rah fondr " << (*i)->io()->name () << endl;
switch ((*i)->do_refill (butler_mixdown_buffer, butler_gain_buffer)) {
switch ((*i)->do_refill (butler_mixdown_buffer, butler_gain_buffer, conv_buffer)) {
case 0:
bytes += (*i)->read_data_count();
break;
@ -303,7 +305,7 @@ Session::butler_thread_work ()
// cerr << "write behind for " << (*i)->name () << endl;
switch ((*i)->do_flush ()) {
switch ((*i)->do_flush (conv_buffer)) {
case 0:
bytes += (*i)->write_data_count();
break;

View file

@ -190,6 +190,10 @@ Session::first_stage_init (string fullpath, string snapshot_name)
pending_abort = false;
layer_model = MoveAddHigher;
xfade_model = ShortCrossfade;
/* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
_conversion_buffers[TransportContext] = new char[DiskStream::disk_io_frames() * 4];
/* default short fade = 15ms */

View file

@ -93,6 +93,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
for (uint32_t i = 0; i < sources.size(); ++i) {
gain_t gain_buffer[bufsize];
Sample buffer[bufsize];
char workbuf[bufsize*4];
jack_nframes_t pos = 0;
jack_nframes_t this_read = 0;
@ -106,7 +107,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
not the ones currently in use, in case it's already been
subject to timefx. */
if ((this_read = tsr.region->master_read_at (buffer, buffer, gain_buffer, pos + tsr.region->position(), this_time)) != this_time) {
if ((this_read = tsr.region->master_read_at (buffer, buffer, gain_buffer, workbuf, pos + tsr.region->position(), this_time)) != this_time) {
error << string_compose (_("tempoize: error reading data from %1"), sources[i]->name()) << endmsg;
goto out;
}
@ -119,7 +120,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
st.putSamples (buffer, this_read);
while ((this_read = st.receiveSamples (buffer, bufsize)) > 0 && tsr.running) {
if (sources[i]->write (buffer, this_read) != this_read) {
if (sources[i]->write (buffer, this_read, workbuf) != this_read) {
error << string_compose (_("error writing tempo-adjusted data to %1"), sources[i]->name()) << endmsg;
goto out;
}
@ -131,7 +132,7 @@ Session::tempoize_region (TimeStretchRequest& tsr)
}
while (tsr.running && (this_read = st.receiveSamples (buffer, bufsize)) > 0) {
if (sources[i]->write (buffer, this_read) != this_read) {
if (sources[i]->write (buffer, this_read, workbuf) != this_read) {
error << string_compose (_("error writing tempo-adjusted data to %1"), sources[i]->name()) << endmsg;
goto out;
}

View file

@ -122,13 +122,13 @@ SndFileSource::~SndFileSource ()
}
jack_nframes_t
SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
SndFileSource::read_unlocked (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
return read (dst, start, cnt);
return read (dst, start, cnt, workbuf);
}
jack_nframes_t
SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt) const
SndFileSource::read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const
{
int32_t nread;
float *ptr;

View file

@ -419,7 +419,8 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
int ret = -1;
PeakData* staging = 0;
Sample* raw_staging = 0;
char * workbuf = 0;
expected_peaks = (cnt / (double) frames_per_peak);
scale = npeaks/expected_peaks;
@ -456,8 +457,9 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
*/
Sample* raw_staging = new Sample[cnt];
workbuf = new char[cnt*4];
if (read_unlocked (raw_staging, start, cnt) != cnt) {
if (read_unlocked (raw_staging, start, cnt, workbuf) != cnt) {
error << _("cannot read sample data for unscaled peak computation") << endmsg;
return -1;
}
@ -468,7 +470,7 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
}
delete [] raw_staging;
delete [] workbuf;
return 0;
}
@ -615,7 +617,8 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
jack_nframes_t nvisual_peaks = 0;
jack_nframes_t chunksize = (jack_nframes_t) min (cnt, (jack_nframes_t) 4096);
raw_staging = new Sample[chunksize];
workbuf = new char[chunksize *4];
jack_nframes_t frame_pos = start;
double pixel_pos = floor (frame_pos / samples_per_visual_peak);
double next_pixel_pos = ceil (frame_pos / samples_per_visual_peak);
@ -630,7 +633,7 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
to_read = min (chunksize, (_length - current_frame));
if ((frames_read = read_unlocked (raw_staging, current_frame, to_read)) < 0) {
if ((frames_read = read_unlocked (raw_staging, current_frame, to_read, workbuf)) < 0) {
error << string_compose(_("Source[%1]: peak read - cannot read %2 samples at offset %3")
, _name, to_read, current_frame)
<< endmsg;
@ -674,6 +677,10 @@ Source::read_peaks (PeakData *peaks, jack_nframes_t npeaks, jack_nframes_t start
delete [] raw_staging;
}
if (workbuf) {
delete [] workbuf;
}
return ret;
}
@ -743,6 +750,7 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
Sample xmin, xmax;
uint32_t peaki;
PeakData* peakbuf;
char * workbuf = 0;
jack_nframes_t frames_read;
jack_nframes_t frames_to_read;
off_t first_peak_byte;
@ -762,11 +770,13 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
peakbuf = new PeakData[(cnt/frames_per_peak)+1];
peaki = 0;
workbuf = new char[max(frames_per_peak, cnt) * 4];
while (cnt) {
frames_to_read = min (frames_per_peak, cnt);
if ((frames_read = read_unlocked (buf, current_frame, frames_to_read)) != frames_to_read) {
if ((frames_read = read_unlocked (buf, current_frame, frames_to_read, workbuf)) != frames_to_read) {
error << string_compose(_("%1: could not write read raw data for peak computation (%2)"), _name, strerror (errno)) << endmsg;
goto out;
}
@ -800,6 +810,8 @@ Source::do_build_peak (jack_nframes_t first_frame, jack_nframes_t cnt)
out:
delete [] peakbuf;
if (workbuf)
delete [] workbuf;
return ret;
}

View file

@ -33,7 +33,7 @@ PixScroller::PixScroller (Adjustment& a, Pix& pix)
: adj (a)
{
dragging = false;
add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
adj.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed));
default_value = adj.get_value();