mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-15 19:16:40 +01:00
committed INCOMPLETE 24bit filesource support
git-svn-id: svn://localhost/trunk/ardour2@316 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
17cb448b1d
commit
9ab70fb552
34 changed files with 623 additions and 176 deletions
|
|
@ -50,6 +50,7 @@ location.cc
|
|||
mtc_slave.cc
|
||||
named_selection.cc
|
||||
panner.cc
|
||||
pcm_utils.cc
|
||||
playlist.cc
|
||||
playlist_factory.cc
|
||||
plugin.cc
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
42
libs/ardour/ardour/pcm_utils.h
Normal file
42
libs/ardour/ardour/pcm_utils.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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
178
libs/ardour/pcm_utils.cc
Normal 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 */
|
||||
|
||||
//@@@@@@@
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue