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

@ -132,6 +132,7 @@ Editor::write_region (string path, AudioRegion& region)
jack_nframes_t to_read; jack_nframes_t to_read;
Sample buf[chunk_size]; Sample buf[chunk_size];
gain_t gain_buffer[chunk_size]; gain_t gain_buffer[chunk_size];
char workbuf[chunk_size *4];
jack_nframes_t pos; jack_nframes_t pos;
char s[PATH_MAX+1]; char s[PATH_MAX+1];
uint32_t cnt; uint32_t cnt;
@ -203,11 +204,11 @@ Editor::write_region (string path, AudioRegion& region)
fs = (*src); fs = (*src);
if (region.read_at (buf, buf, gain_buffer, pos, this_time) != this_time) { if (region.read_at (buf, buf, gain_buffer, workbuf, pos, this_time) != this_time) {
break; break;
} }
if (fs->write (buf, this_time) != this_time) { if (fs->write (buf, this_time, workbuf) != this_time) {
error << "" << endmsg; error << "" << endmsg;
goto error_out; goto error_out;
} }
@ -277,6 +278,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
jack_nframes_t nframes; jack_nframes_t nframes;
Sample buf[chunk_size]; Sample buf[chunk_size];
gain_t gain_buffer[chunk_size]; gain_t gain_buffer[chunk_size];
char workbuf[chunk_size*4];
jack_nframes_t pos; jack_nframes_t pos;
char s[PATH_MAX+1]; char s[PATH_MAX+1];
uint32_t cnt; uint32_t cnt;
@ -334,11 +336,11 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
fs = sources[n]; fs = sources[n];
if (playlist.read (buf, buf, gain_buffer, pos, this_time, n) != this_time) { if (playlist.read (buf, buf, gain_buffer, workbuf, pos, this_time, n) != this_time) {
break; break;
} }
if (fs->write (buf, this_time) != this_time) { if (fs->write (buf, this_time, workbuf) != this_time) {
goto error_out; goto error_out;
} }
} }
@ -364,7 +366,7 @@ Editor::write_audio_range (Playlist& playlist, uint32_t channels, list<AudioRang
for (uint32_t n=0; n < channels; ++n) { for (uint32_t n=0; n < channels; ++n) {
fs = sources[n]; fs = sources[n];
if (fs->write (buf, this_time) != this_time) { if (fs->write (buf, this_time, workbuf) != this_time) {
goto error_out; goto error_out;
} }
} }

View file

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

View file

@ -63,7 +63,7 @@ class AudioTrack : public Route
jack_nframes_t update_total_latency(); jack_nframes_t update_total_latency();
void set_latency_delay (jack_nframes_t); 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; 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); 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&); int set_state (const XMLNode&);
UndoAction get_memento() const; 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; 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, 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, uint32_t chan_n = 0,
jack_nframes_t read_frames = 0, jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const; jack_nframes_t skip_frames = 0) const;
jack_nframes_t master_read_at (Sample *buf, Sample *mixdown_buffer, 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); XMLNode& state (bool);
@ -199,7 +199,7 @@ class AudioRegion : public Region
void rename_after_first_edit (); void rename_after_first_edit ();
jack_nframes_t _read_at (const SourceList&, Sample *buf, Sample *mixdown_buffer, 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, uint32_t chan_n = 0,
jack_nframes_t read_frames = 0, jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const; 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; } ARDOUR::AudioRegion& out() const { return *_out; }
jack_nframes_t read_at (Sample *buf, Sample *mixdown_buffer, 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, uint32_t chan_n,
jack_nframes_t read_frames = 0, jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0); jack_nframes_t skip_frames = 0);

View file

@ -31,7 +31,7 @@ namespace ARDOUR {
class DestructiveFileSource : public FileSource { class DestructiveFileSource : public FileSource {
public: 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 (const XMLNode&, jack_nframes_t rate);
~DestructiveFileSource (); ~DestructiveFileSource ();
@ -41,7 +41,7 @@ class DestructiveFileSource : public FileSource {
void mark_capture_end (); void mark_capture_end ();
void clear_capture_marks(); 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: private:
static jack_nframes_t xfade_frames; static jack_nframes_t xfade_frames;
@ -52,10 +52,10 @@ class DestructiveFileSource : public FileSource {
bool _capture_start; bool _capture_start;
bool _capture_end; bool _capture_end;
jack_nframes_t capture_start_frame; jack_nframes_t capture_start_frame;
jack_nframes_t file_pos; jack_nframes_t file_pos; // unit is frames
Sample* xfade_buf; 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 */ /* the two central butler operations */
int do_flush (bool force = false); int do_flush (char * workbuf, bool force = false);
int do_refill (Sample *mixdown_buffer, float *gain_buffer); 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); ChannelInfo& channel_info, int channel, bool reversed);
uint32_t i_am_the_modifier; uint32_t i_am_the_modifier;

View file

@ -44,13 +44,19 @@ namespace ARDOUR {
class FileSource : public Source { class FileSource : public Source {
public: 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 (const XMLNode&, jack_nframes_t rate);
~FileSource (); ~FileSource ();
jack_nframes_t length() const { return _length; } 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 read (Sample *dst, jack_nframes_t start, jack_nframes_t cnt, char * workbuf) const;
jack_nframes_t write (Sample *src, jack_nframes_t cnt); jack_nframes_t write (Sample *src, jack_nframes_t cnt, char * workbuf);
void mark_for_remove(); void mark_for_remove();
string peak_path(string audio_path); string peak_path(string audio_path);
string old_peak_path(string audio_path); string old_peak_path(string audio_path);
@ -85,7 +91,9 @@ class FileSource : public Source {
bool is_bwf; bool is_bwf;
off64_t data_offset; off64_t data_offset;
string _take_id; string _take_id;
SampleFormat _sample_format;
int _sample_size;
static char bwf_country_code[3]; static char bwf_country_code[3];
static char bwf_organization_code[4]; static char bwf_organization_code[4];
static char bwf_serial_number[13]; static char bwf_serial_number[13];
@ -143,8 +151,27 @@ class FileSource : public Source {
} header; } header;
int init (string, bool must_exist, jack_nframes_t); 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); int discover_chunks (bool silent);
ChunkInfo* lookup_chunk (string name); 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&, string name, bool hidden = false);
Playlist (const Playlist&, jack_nframes_t start, jack_nframes_t cnt, 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 clear (bool with_delete = false, bool with_save = true);
virtual void dump () const; virtual void dump () const;
virtual UndoAction get_memento() const = 0; 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, 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, uint32_t chan_n = 0,
jack_nframes_t read_frames = 0, jack_nframes_t read_frames = 0,
jack_nframes_t skip_frames = 0) const = 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; } gain_t* gain_automation_buffer () const { return _gain_automation_buffer; }
pan_t** pan_automation_buffer() const { return _pan_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 */ /* VST support */
static long vst_callback (AEffect* effect, static long vst_callback (AEffect* effect,
@ -998,6 +1007,7 @@ class Session : public sigc::trackable, public Stateful
jack_nframes_t last_stop_frame; jack_nframes_t last_stop_frame;
vector<Sample *> _passthru_buffers; vector<Sample *> _passthru_buffers;
vector<Sample *> _silent_buffers; vector<Sample *> _silent_buffers;
map<RunContext,char*> _conversion_buffers;
jack_nframes_t current_block_size; jack_nframes_t current_block_size;
jack_nframes_t _worst_output_latency; jack_nframes_t _worst_output_latency;
jack_nframes_t _worst_input_latency; jack_nframes_t _worst_input_latency;

View file

@ -34,7 +34,7 @@ class SndFileSource : public Source {
~SndFileSource (); ~SndFileSource ();
jack_nframes_t length() const { return _info.frames; } 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 void mark_for_remove() {} // we never remove external sndfiles
string peak_path(string audio_path); string peak_path(string audio_path);
string old_peak_path(string audio_path); string old_peak_path(string audio_path);
@ -54,7 +54,7 @@ class SndFileSource : public Source {
string _path; string _path;
void init (const string &str, bool build_peak); 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 */ }; /* namespace EDL */

View file

@ -64,11 +64,11 @@ class Source : public Stateful, public sigc::trackable
return _length; 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; 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; return 0;
} }
@ -134,7 +134,7 @@ class Source : public Stateful, public sigc::trackable
void build_peaks_from_scratch (); void build_peaks_from_scratch ();
int do_build_peak (jack_nframes_t, jack_nframes_t); 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 peak_path(string audio_path) = 0;
virtual string old_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 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 cnt, unsigned chan_n)
{ {
jack_nframes_t ret = cnt; 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]); vector<Crossfade*>& x (relevant_xfades[*l]);
for (vector<Region*>::iterator i = r.begin(); i != r.end(); ++i) { 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(); _read_data_count += (*i)->read_data_count();
} }
for (vector<Crossfade*>::iterator i = x.begin(); i != x.end(); ++i) { 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 /* 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. 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 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_automation[nframes];
gain_t gain_buffer[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__); 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; return -1;
} }
@ -791,7 +791,7 @@ AudioTrack::export_stuff (vector<Sample*>& buffers, uint32_t nbufs, jack_nframes
++bi; ++bi;
for (; bi != buffers.end(); ++bi, ++n) { for (; bi != buffers.end(); ++bi, ++n) {
if (n < diskstream->n_channels()) { 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; return -1;
} }
b = (*bi); b = (*bi);

View file

@ -462,22 +462,22 @@ AudioRegion::read_peaks (PeakData *buf, jack_nframes_t npeaks, jack_nframes_t of
} }
jack_nframes_t 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, jack_nframes_t cnt,
uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const 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 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 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 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, jack_nframes_t position, jack_nframes_t cnt,
uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const 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; _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" */ return 0; /* "read nothing" */
} }
@ -1204,7 +1204,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
if (spec.channels == 1) { 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; goto out;
} }
@ -1214,7 +1214,7 @@ AudioRegion::exportme (Session& session, AudioExportSpecification& spec)
for (uint32_t chan = 0; chan < spec.channels; ++chan) { 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; goto out;
} }
@ -1276,6 +1276,7 @@ AudioRegion::normalize_to (float target_dB)
{ {
const jack_nframes_t blocksize = 256 * 1048; const jack_nframes_t blocksize = 256 * 1048;
Sample buf[blocksize]; Sample buf[blocksize];
char workbuf[blocksize * 4];
jack_nframes_t fpos; jack_nframes_t fpos;
jack_nframes_t fend; jack_nframes_t fend;
jack_nframes_t to_read; jack_nframes_t to_read;
@ -1304,7 +1305,7 @@ AudioRegion::normalize_to (float target_dB)
/* read it in */ /* 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; return;
} }

View file

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

View file

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

View file

@ -65,6 +65,7 @@
#include <ardour/filesource.h> #include <ardour/filesource.h>
#include <ardour/session.h> #include <ardour/session.h>
#include <ardour/cycle_timer.h> #include <ardour/cycle_timer.h>
#include <ardour/pcm_utils.h>
#include "i18n.h" #include "i18n.h"
@ -101,10 +102,16 @@ FileSource::set_search_path (string p)
search_path = 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 */ /* 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)) { if (repair_first && repair (pathstr, rate)) {
throw failed_constructor (); 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) FileSource::FileSource (const XMLNode& node, jack_nframes_t rate)
: Source (node) : Source (node)
{ {
_sample_format = FormatFloat;
_sample_size = sizeof(float);
if (set_state (node)) { if (set_state (node)) {
throw failed_constructor(); throw failed_constructor();
} }
@ -558,12 +568,19 @@ FileSource::fill_header (jack_nframes_t rate)
memcpy (header.format.id, "fmt ", 4); memcpy (header.format.id, "fmt ", 4);
header.format.size = sizeof (FMTChunk) - sizeof (GenericChunk); 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.nChannels = 1; /* mono */
header.format.nSamplesPerSec = rate; header.format.nSamplesPerSec = rate;
header.format.nAvgBytesPerSec = rate * sizeof (Sample); header.format.nAvgBytesPerSec = rate * sizeof (Sample);
header.format.nBlockAlign = 4;
header.format.nBitsPerSample = 32;
/* DATA */ /* DATA */
@ -788,9 +805,18 @@ FileSource::read_broadcast_data (ChunkInfo& info)
int int
FileSource::check_header (jack_nframes_t rate, bool silent) 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) { 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; "This is probably a programming error."), _path) << endmsg;
} }
return -1; return -1;
@ -932,73 +958,38 @@ FileSource::mark_for_remove ()
} }
jack_nframes_t 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__); LockMonitor lm (_lock, __LINE__, __FILE__);
return read_unlocked (dst, start, cnt); return read_unlocked (dst, start, cnt, workbuf);
} }
jack_nframes_t 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; if (file_read(dst, start, cnt, workbuf) != (ssize_t) cnt) {
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;
return 0; return 0;
} }
if (header.bigendian != WE_ARE_BIGENDIAN) {
swap_endian(dst, cnt);
}
_read_data_count = byte_cnt;
return cnt; return cnt;
} }
jack_nframes_t 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__); 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; jack_nframes_t oldlen;
int32_t frame_pos = _length;
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; if (file_write(data, frame_pos, cnt, workbuf) != (ssize_t) cnt) {
return 0; return 0;
} }
oldlen = _length; oldlen = _length;
_length += cnt; _length += cnt;
_write_data_count = byte_cnt;
if (_build_peakfiles) { if (_build_peakfiles) {
PeakBuildRecord *pbr = 0; PeakBuildRecord *pbr = 0;
@ -1031,6 +1022,152 @@ FileSource::write (Sample *data, jack_nframes_t cnt)
return 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 bool
FileSource::is_empty (string path) FileSource::is_empty (string path)
{ {

View file

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

View file

@ -599,7 +599,7 @@ PluginInsert::state (bool full)
node->add_property("id", string(buf)); node->add_property("id", string(buf));
if (_plugins[0]->state_node_name() == "ladspa") { if (_plugins[0]->state_node_name() == "ladspa") {
char buf[32]; 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("unique-id", string(buf));
} }
node->add_property("count", string_compose("%1", _plugins.size())); 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()); lrdf_uris* set_uris = lrdf_get_setting_uris(unique_id());
if (set_uris) { 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])) { if (char* label = lrdf_get_label(set_uris->items[i])) {
labels.push_back(label); labels.push_back(label);
presets[label] = set_uris->items[i]; 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()); lrdf_defaults* defs = lrdf_get_setting_values(presets[preset_label].c_str());
if (defs) { 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 // The defs->items[i].pid < defs->count check is to work around
// a bug in liblrdf that saves invalid values into the presets file. // 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); set_parameter(defs->items[i].pid, defs->items[i].value);
} }
} }

View file

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

View file

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

View file

@ -174,6 +174,8 @@ Session::butler_thread_work ()
butler_mixdown_buffer = new Sample[DiskStream::disk_io_frames()]; butler_mixdown_buffer = new Sample[DiskStream::disk_io_frames()];
butler_gain_buffer = new gain_t[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) { while (true) {
@ -260,7 +262,7 @@ Session::butler_thread_work ()
// cerr << "rah fondr " << (*i)->io()->name () << endl; // 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: case 0:
bytes += (*i)->read_data_count(); bytes += (*i)->read_data_count();
break; break;
@ -303,7 +305,7 @@ Session::butler_thread_work ()
// cerr << "write behind for " << (*i)->name () << endl; // cerr << "write behind for " << (*i)->name () << endl;
switch ((*i)->do_flush ()) { switch ((*i)->do_flush (conv_buffer)) {
case 0: case 0:
bytes += (*i)->write_data_count(); bytes += (*i)->write_data_count();
break; break;

View file

@ -190,6 +190,10 @@ Session::first_stage_init (string fullpath, string snapshot_name)
pending_abort = false; pending_abort = false;
layer_model = MoveAddHigher; layer_model = MoveAddHigher;
xfade_model = ShortCrossfade; 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 */ /* default short fade = 15ms */

View file

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

View file

@ -122,13 +122,13 @@ SndFileSource::~SndFileSource ()
} }
jack_nframes_t 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 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; int32_t nread;
float *ptr; float *ptr;

View file

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

View file

@ -33,7 +33,7 @@ PixScroller::PixScroller (Adjustment& a, Pix& pix)
: adj (a) : adj (a)
{ {
dragging = false; 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)); adj.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed));
default_value = adj.get_value(); default_value = adj.get_value();