summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorJesse Chappell <jesse@essej.net>2006-02-10 23:53:12 +0000
committerJesse Chappell <jesse@essej.net>2006-02-10 23:53:12 +0000
commit9ab70fb55284537228577d575f15aa03949bd678 (patch)
tree47a44c65846a46bb6bff1b49caa8edb68c2b8c13 /libs
parent17cb448b1df0def4c1e09da615e11a64f6e692e3 (diff)
committed INCOMPLETE 24bit filesource support
git-svn-id: svn://localhost/trunk/ardour2@316 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/audio_track.h2
-rw-r--r--libs/ardour/ardour/audioplaylist.h2
-rw-r--r--libs/ardour/ardour/audioregion.h6
-rw-r--r--libs/ardour/ardour/crossfade.h2
-rw-r--r--libs/ardour/ardour/destructive_filesource.h8
-rw-r--r--libs/ardour/ardour/diskstream.h6
-rw-r--r--libs/ardour/ardour/filesource.h39
-rw-r--r--libs/ardour/ardour/pcm_utils.h42
-rw-r--r--libs/ardour/ardour/playlist.h2
-rw-r--r--libs/ardour/ardour/region.h2
-rw-r--r--libs/ardour/ardour/session.h10
-rw-r--r--libs/ardour/ardour/sndfilesource.h4
-rw-r--r--libs/ardour/ardour/source.h6
-rw-r--r--libs/ardour/audio_playlist.cc6
-rw-r--r--libs/ardour/audio_track.cc6
-rw-r--r--libs/ardour/audioregion.cc19
-rw-r--r--libs/ardour/crossfade.cc6
-rw-r--r--libs/ardour/destructive_filesource.cc61
-rw-r--r--libs/ardour/diskstream.cc43
-rw-r--r--libs/ardour/filesource.cc239
-rw-r--r--libs/ardour/import.cc13
-rw-r--r--libs/ardour/insert.cc2
-rw-r--r--libs/ardour/pcm_utils.cc178
-rw-r--r--libs/ardour/plugin.cc6
-rw-r--r--libs/ardour/reverse.cc12
-rw-r--r--libs/ardour/session.cc17
-rw-r--r--libs/ardour/session_butler.cc6
-rw-r--r--libs/ardour/session_state.cc4
-rw-r--r--libs/ardour/session_timefx.cc7
-rw-r--r--libs/ardour/sndfilesource.cc6
-rw-r--r--libs/ardour/source.cc24
-rw-r--r--libs/gtkmm2ext/pixscroller.cc2
33 files changed, 617 insertions, 172 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index b1cab4bb7d..5f51e839eb 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -50,6 +50,7 @@ location.cc
mtc_slave.cc
named_selection.cc
panner.cc
+pcm_utils.cc
playlist.cc
playlist_factory.cc
plugin.cc
diff --git a/libs/ardour/ardour/audio_track.h b/libs/ardour/ardour/audio_track.h
index 030dd17a6b..0ef4c45f16 100644
--- a/libs/ardour/ardour/audio_track.h
+++ b/libs/ardour/ardour/audio_track.h
@@ -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;
diff --git a/libs/ardour/ardour/audioplaylist.h b/libs/ardour/ardour/audioplaylist.h
index 26cce91b12..fa2aa94471 100644
--- a/libs/ardour/ardour/audioplaylist.h
+++ b/libs/ardour/ardour/audioplaylist.h
@@ -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;
diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h
index 44159f73f5..fa6b3aeecc 100644
--- a/libs/ardour/ardour/audioregion.h
+++ b/libs/ardour/ardour/audioregion.h
@@ -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;
diff --git a/libs/ardour/ardour/crossfade.h b/libs/ardour/ardour/crossfade.h
index 4db833ca45..3e65e16901 100644
--- a/libs/ardour/ardour/crossfade.h
+++ b/libs/ardour/ardour/crossfade.h
@@ -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);
diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h
index bb46fdfd22..ceb049b29c 100644
--- a/libs/ardour/ardour/destructive_filesource.h
+++ b/libs/ardour/ardour/destructive_filesource.h
@@ -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);
};
diff --git a/libs/ardour/ardour/diskstream.h b/libs/ardour/ardour/diskstream.h
index 5b63cfad28..1d06c4ee49 100644
--- a/libs/ardour/ardour/diskstream.h
+++ b/libs/ardour/ardour/diskstream.h
@@ -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;
diff --git a/libs/ardour/ardour/filesource.h b/libs/ardour/ardour/filesource.h
index e426159014..af46596ec5 100644
--- a/libs/ardour/ardour/filesource.h
+++ b/libs/ardour/ardour/filesource.h
@@ -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);
diff --git a/libs/ardour/ardour/pcm_utils.h b/libs/ardour/ardour/pcm_utils.h
new file mode 100644
index 0000000000..6866e53251
--- /dev/null
+++ b/libs/ardour/ardour/pcm_utils.h
@@ -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
diff --git a/libs/ardour/ardour/playlist.h b/libs/ardour/ardour/playlist.h
index a5451c30d5..b0ac956d5c 100644
--- a/libs/ardour/ardour/playlist.h
+++ b/libs/ardour/ardour/playlist.h
@@ -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;
diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h
index e067f56f44..5af5a660c1 100644
--- a/libs/ardour/ardour/region.h
+++ b/libs/ardour/ardour/region.h
@@ -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;
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index a2a62703e4..d4ca8c1ddc 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -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;
diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h
index 7f9712b7ec..a7583c4fe1 100644
--- a/libs/ardour/ardour/sndfilesource.h
+++ b/libs/ardour/ardour/sndfilesource.h
@@ -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 */
diff --git a/libs/ardour/ardour/source.h b/libs/ardour/ardour/source.h
index e9afc04f03..9772968288 100644
--- a/libs/ardour/ardour/source.h
+++ b/libs/ardour/ardour/source.h
@@ -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;
diff --git a/libs/ardour/audio_playlist.cc b/libs/ardour/audio_playlist.cc
index be977447b7..f6c6440ab0 100644
--- a/libs/ardour/audio_playlist.cc
+++ b/libs/ardour/audio_playlist.cc
@@ -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.
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index dd9648c7bf..7bf8d5732f 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -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);
diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc
index bc14968fa7..804e378a16 100644
--- a/libs/ardour/audioregion.cc
+++ b/libs/ardour/audioregion.cc
@@ -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;
}
diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc
index 8aed204d71..c23689a3a3 100644
--- a/libs/ardour/crossfade.cc
+++ b/libs/ardour/crossfade.cc
@@ -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];
diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc
index 6df6ff06af..8715c5f283 100644
--- a/libs/ardour/destructive_filesource.cc
+++ b/libs/ardour/destructive_filesource.cc
@@ -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;
+
+ cerr << "First frame of capture will be at " << file_pos << endl;
- if (crossfade (data, cnt, 1) != cnt) {
+ 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;
diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc
index 154e085858..30f365ae32 100644
--- a/libs/ardour/diskstream.cc
+++ b/libs/ardour/diskstream.cc
@@ -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;
diff --git a/libs/ardour/filesource.cc b/libs/ardour/filesource.cc
index 780f26fed6..1f3a89557c 100644
--- a/libs/ardour/filesource.cc
+++ b/libs/ardour/filesource.cc
@@ -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)
{
diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc
index 3411481a3a..f5884a1c1d 100644
--- a/libs/ardour/import.cc
+++ b/libs/ardour/import.cc
@@ -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];
diff --git a/libs/ardour/insert.cc b/libs/ardour/insert.cc
index 3b3999a848..3ef84d1481 100644
--- a/libs/ardour/insert.cc
+++ b/libs/ardour/insert.cc
@@ -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()));
diff --git a/libs/ardour/pcm_utils.cc b/libs/ardour/pcm_utils.cc
new file mode 100644
index 0000000000..dd18fe8690
--- /dev/null
+++ b/libs/ardour/pcm_utils.cc
@@ -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 */
+
+//@@@@@@@
diff --git a/libs/ardour/plugin.cc b/libs/ardour/plugin.cc
index 059cf133a5..e9665908a3 100644
--- a/libs/ardour/plugin.cc
+++ b/libs/ardour/plugin.cc
@@ -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);
}
}
diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc
index 2474e0cb8d..335dacad6e 100644
--- a/libs/ardour/reverse.cc
+++ b/libs/ardour/reverse.cc
@@ -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;
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index b329c16cc6..e0c6c1bf7e 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -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;
diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc
index 12a838b5dd..00a2465d9b 100644
--- a/libs/ardour/session_butler.cc
+++ b/libs/ardour/session_butler.cc
@@ -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;
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 2a8bdf2fde..45a51e813b 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -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 */
diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc
index b8f0068a91..2fae4b32c9 100644
--- a/libs/ardour/session_timefx.cc
+++ b/libs/ardour/session_timefx.cc
@@ -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;
}
diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc
index 0baff36a3f..350a9c2ef1 100644
--- a/libs/ardour/sndfilesource.cc
+++ b/libs/ardour/sndfilesource.cc
@@ -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;
diff --git a/libs/ardour/source.cc b/libs/ardour/source.cc
index 515e8d4e9b..ee918375f6 100644
--- a/libs/ardour/source.cc
+++ b/libs/ardour/source.cc
@@ -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;
}
diff --git a/libs/gtkmm2ext/pixscroller.cc b/libs/gtkmm2ext/pixscroller.cc
index 556fce8080..8edf0723e1 100644
--- a/libs/gtkmm2ext/pixscroller.cc
+++ b/libs/gtkmm2ext/pixscroller.cc
@@ -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();