[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src commands/AudioClipExternalProcessi...
From: |
Remon Sijrier |
Subject: |
[Traverso-commit] traverso/src commands/AudioClipExternalProcessi... |
Date: |
Wed, 18 Jul 2007 13:13:08 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Remon Sijrier <r_sijrier> 07/07/18 13:13:08
Modified files:
src/commands : AudioClipExternalProcessing.cpp
src/core : AbstractAudioReader.cpp AbstractAudioReader.h
AudioClip.cpp AudioClip.h AudioSource.cpp
AudioSource.h core.pro DiskIO.cpp DiskIO.h
FlacAudioReader.cpp MadAudioReader.cpp Peak.cpp
ReadSource.cpp ReadSource.h
ResampleAudioReader.cpp ResampleAudioReader.h
ResourcesManager.cpp ResourcesManager.h
SFAudioReader.cpp Song.cpp Track.cpp
VorbisAudioReader.cpp
src/traverso/songcanvas: AudioClipView.cpp
Removed files:
src/core : MonoReader.cpp MonoReader.h
Log message:
* Merged MonoReader and ReadSource into ReadSource
* Buffered reading reads all channels in one go now, modified Peak,
Track, AudioClip::process() to take care of it
* Renamed AbstractAudioReader variable m_nextFrame to m_readPos, seems
more logical. Updating of this variable is only done now in AUR read_from()
function, avoids duplication of code in all audioreaders, and it also fixed the
always seeking in read_from() with resampled reader.
* AudioDevice paramater changes now issues a seek, so DiskIO seeks to
the correct position and as a result ResampleReader buffers are cleared and
filled with correc data
* Needs more love and work :D
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/commands/AudioClipExternalProcessing.cpp?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AbstractAudioReader.cpp?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AbstractAudioReader.h?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.cpp?cvsroot=traverso&r1=1.113&r2=1.114
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.h?cvsroot=traverso&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.cpp?cvsroot=traverso&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.h?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/core.pro?cvsroot=traverso&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/DiskIO.cpp?cvsroot=traverso&r1=1.38&r2=1.39
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/DiskIO.h?cvsroot=traverso&r1=1.17&r2=1.18
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/FlacAudioReader.cpp?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MadAudioReader.cpp?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Peak.cpp?cvsroot=traverso&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ReadSource.cpp?cvsroot=traverso&r1=1.39&r2=1.40
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ReadSource.h?cvsroot=traverso&r1=1.29&r2=1.30
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.cpp?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResampleAudioReader.h?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResourcesManager.cpp?cvsroot=traverso&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ResourcesManager.h?cvsroot=traverso&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/SFAudioReader.cpp?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Song.cpp?cvsroot=traverso&r1=1.122&r2=1.123
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Track.cpp?cvsroot=traverso&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/VorbisAudioReader.cpp?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MonoReader.cpp?cvsroot=traverso&r1=1.22&r2=0
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/MonoReader.h?cvsroot=traverso&r1=1.7&r2=0
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/songcanvas/AudioClipView.cpp?cvsroot=traverso&r1=1.80&r2=1.81
Patches:
Index: commands/AudioClipExternalProcessing.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/commands/AudioClipExternalProcessing.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- commands/AudioClipExternalProcessing.cpp 2 Jul 2007 20:34:21 -0000
1.20
+++ commands/AudioClipExternalProcessing.cpp 18 Jul 2007 13:13:05 -0000
1.21
@@ -54,7 +54,8 @@
void run() {
uint buffersize = 16384;
audio_sample_t readbuffer[buffersize];
- audio_sample_t* mixdown = new audio_sample_t[2 * buffersize];
+ audio_sample_t* mixdown[2];
+ for (int i=0; i<2; ++i) mixdown[i] = new audio_sample_t[2 *
buffersize];
ExportSpecification* spec = new ExportSpecification();
spec->start_frame = 0;
@@ -82,12 +83,11 @@
memset (spec->dataF, 0, sizeof (spec->dataF[0]) *
nframes * spec->channels);
- for (int chan=0; chan < 2; ++chan) {
-
- m_readsource->file_read(chan, mixdown,
spec->pos, nframes, readbuffer);
+ m_readsource->file_read(mixdown, spec->pos, nframes,
readbuffer);
+ for (int chan=0; chan < 2; ++chan) {
for (uint x = 0; x < nframes; ++x) {
- spec->dataF[chan+(x*spec->channels)] =
mixdown[x];
+ spec->dataF[chan+(x*spec->channels)] =
mixdown[chan][x];
}
}
@@ -101,7 +101,8 @@
delete writesource;
delete [] spec->dataF;
delete spec;
- delete [] mixdown;
+ for (int i=0; i<2; ++i)
+ delete [] mixdown[i];
}
private:
@@ -125,6 +126,7 @@
int AudioClipExternalProcessing::prepare_actions()
{
+ PENTER;
ExternalProcessingDialog epdialog(Interface::instance(), this);
epdialog.exec();
@@ -217,15 +219,15 @@
m_filename.remove(".wav").remove(".").append("-").append(m_commandargs.simplified()).append(".wav");
- if (rs->get_channel_count() == 2 && rs->get_file_count() == 2) {
+/* if (rs->get_channel_count() == 2 && rs->get_file_count() == 2) {
m_merger = new MergeThread(rs, "merged.wav");
connect(m_merger, SIGNAL(finished()), this,
SLOT(start_external_processing()));
m_merger->start();
statusText->setHtml(tr("Preparing audio data to a format that
can be used by <b>%1</b>, this can take a while for large
files!").arg(m_program));
progressBar->setMaximum(0);
- } else {
+ } else { */
start_external_processing();
- }
+// }
}
void ExternalProcessingDialog::start_external_processing()
Index: core/AbstractAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AbstractAudioReader.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/AbstractAudioReader.cpp 15 Jul 2007 05:14:47 -0000 1.6
+++ core/AbstractAudioReader.cpp 18 Jul 2007 13:13:05 -0000 1.7
@@ -34,11 +34,11 @@
#include "Debugger.h"
-AbstractAudioReader::AbstractAudioReader(QString filename)
+AbstractAudioReader::AbstractAudioReader(const QString& filename)
: QObject(0)
{
m_fileName = filename;
- m_nextFrame = 0;
+ m_readPos = 0;
}
@@ -53,20 +53,28 @@
{
QMutexLocker locker( &m_mutex );
- if (m_nextFrame != start) {
+// printf("read_from:: before_seek from %d, framepos is %d\n", start,
m_readPos);
+
+ if (m_readPos != start) {
+// printf("starting seek\n");
if (!seek(start)) {
return 0;
+ } else {
+ m_readPos = start;
}
}
+// printf("read_from:: after_seek from %d, framepos is %d\n", start,
m_readPos);
int samplesRead = read(dst, cnt);
+ m_readPos += samplesRead / get_num_channels();
+
return samplesRead;
}
// Static method used by other classes to get an AudioReader for the correct
file type
-AbstractAudioReader* AbstractAudioReader::create_audio_reader(QString filename)
+AbstractAudioReader* AbstractAudioReader::create_audio_reader(const QString&
filename)
{
AbstractAudioReader* newReader;
@@ -97,7 +105,7 @@
// Static method used by other classes to get an automatically resampling
AudioReader that wraps
// an AudioReader chosen by create_audio_reader().
-AbstractAudioReader*
AbstractAudioReader::create_resampled_audio_reader(QString filename, int
converter_type)
+AbstractAudioReader* AbstractAudioReader::create_resampled_audio_reader(const
QString& filename, int converter_type)
{
ResampleAudioReader* newReader;
Index: core/AbstractAudioReader.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AbstractAudioReader.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/AbstractAudioReader.h 15 Jul 2007 05:14:47 -0000 1.6
+++ core/AbstractAudioReader.h 18 Jul 2007 13:13:05 -0000 1.7
@@ -31,9 +31,10 @@
class AbstractAudioReader : public QObject
{
-Q_OBJECT
+ Q_OBJECT
+
public:
- AbstractAudioReader(QString filename);
+ AbstractAudioReader(const QString& filename);
~AbstractAudioReader();
virtual int get_num_channels() = 0;
@@ -43,14 +44,13 @@
virtual bool seek(nframes_t start) = 0;
virtual int read(audio_sample_t* dst, int sampleCount) = 0;
- static AbstractAudioReader* create_audio_reader(QString filename);
- static AbstractAudioReader* create_resampled_audio_reader(QString
filename, int converter_type);
- static bool can_decode(QString filename) { return false; };
+ static AbstractAudioReader* create_audio_reader(const QString&
filename);
+ static AbstractAudioReader* create_resampled_audio_reader(const
QString& filename, int converter_type);
protected:
QString m_fileName;
QMutex m_mutex;
- nframes_t m_nextFrame;
+ nframes_t m_readPos;
};
Index: core/AudioClip.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.cpp,v
retrieving revision 1.113
retrieving revision 1.114
diff -u -b -r1.113 -r1.114
--- core/AudioClip.cpp 16 Jul 2007 01:48:10 -0000 1.113
+++ core/AudioClip.cpp 18 Jul 2007 13:13:05 -0000 1.114
@@ -102,6 +102,10 @@
m_song->get_diskio()->unregister_read_source(m_readSource);
delete m_readSource;
}
+ // FIXME crashes with a double free in ResourcesManager desctructor on
deleting a ReadSource :(
+/* foreach(Peak* peak, m_peaks) {
+ peak->close();
+ }*/
}
void AudioClip::init()
@@ -379,12 +383,12 @@
//
// Function called in RealTime AudioThread processing path
//
-int AudioClip::process(nframes_t nframes, audio_sample_t* buffer, uint channel)
+int AudioClip::process(nframes_t nframes)
{
Q_ASSERT(m_song);
if (m_recordingStatus == RECORDING) {
- process_capture(nframes, channel);
+// process_capture(nframes, channel);
return 0;
}
@@ -398,12 +402,13 @@
Q_ASSERT(m_readSource);
- if (channel >= m_readSource->get_channel_count()) {
+/* if (channel >= m_readSource->get_channel_count()) {
return 1;
- }
+ }*/
+ AudioBus* bus = m_song->get_render_bus();
nframes_t mix_pos;
- audio_sample_t* mixdown;
+ audio_sample_t* mixdown[get_channels()];
nframes_t transportFrame = m_song->get_transport_frame();
@@ -413,11 +418,17 @@
if (transportFrame < trackStartFrame) {
uint offset = trackStartFrame - transportFrame;
mix_pos = sourceStartFrame;
- mixdown = buffer + offset;
+// mixdown = buffer + offset;
+ for (int chan=0; chan<bus->get_channel_count(); ++chan)
{
+ mixdown[chan] = bus->get_buffer(chan, nframes)
+ offset;
+ }
nframes = nframes - offset;
} else {
mix_pos = transportFrame - trackStartFrame +
sourceStartFrame;
- mixdown = buffer;
+// mixdown = buffer;
+ for (int chan=0; chan<bus->get_channel_count(); ++chan)
{
+ mixdown[chan] = bus->get_buffer(chan, nframes);
+ }
}
if (trackEndFrame < upperRange) {
nframes -= (upperRange - trackEndFrame);
@@ -431,21 +442,27 @@
if (m_song->realtime_path()) {
- read_frames = m_readSource->rb_read(channel, mixdown, mix_pos,
nframes);
+ read_frames = m_readSource->rb_read(mixdown, mix_pos, nframes);
} else {
- read_frames = m_readSource->file_read(channel, mixdown,
mix_pos, nframes, m_song->readbuffer);
+ read_frames = m_readSource->file_read(mixdown, mix_pos,
nframes, m_song->readbuffer);
}
if (read_frames <= 0) {
return 0;
}
+ for (int chan=0; chan<bus->get_channel_count(); ++chan) {
for (int i=0; i<m_fades.size(); ++i) {
- m_fades.at(i)->process(mixdown, read_frames);
+ m_fades.at(i)->process(mixdown[chan], read_frames);
+ }
+
+ m_fader->process_gain(mixdown[chan],
(m_song->get_transport_frame() - (trackStartFrame - sourceStartFrame)),
read_frames);
+
+ Mixer::apply_gain_to_buffer(bus->get_buffer(chan, nframes),
nframes, get_gain());
}
- m_fader->process_gain(mixdown, (m_song->get_transport_frame() -
(trackStartFrame - sourceStartFrame)), read_frames);
+
return 1;
}
@@ -619,8 +636,10 @@
Peak* AudioClip::get_peak_for_channel( int chan ) const
{
PENTER2;
- Q_ASSERT(m_readSource);
- return m_readSource->get_peak(chan);
+ if (chan >= m_peaks.size()) {
+ return 0;
+ }
+ return m_peaks.at(chan);
}
void AudioClip::set_audio_source(ReadSource* rs)
@@ -657,6 +676,16 @@
rs->set_audio_clip(this);
+ foreach(Peak* peak, m_peaks) {
+ peak->close();
+ }
+
+ m_peaks.clear();
+
+ for (int chan=0; chan<m_readSource->get_channel_count(); ++chan) {
+ m_peaks.append(new Peak(rs, chan));
+ }
+
emit stateChanged();
}
@@ -894,7 +923,7 @@
}
for (uint i=0; i<m_readSource->get_channel_count(); ++i) {
- double amp =
m_readSource->get_peak(i)->get_max_amplitude(sourceStartFrame, sourceEndFrame);
+ double amp =
get_peak_for_channel(i)->get_max_amplitude(sourceStartFrame, sourceEndFrame);
if (amp == 0.0f) {
printf("AudioClip::normalization: max amplitude ==
0\n");
Index: core/AudioClip.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- core/AudioClip.h 28 Jun 2007 15:03:56 -0000 1.55
+++ core/AudioClip.h 18 Jul 2007 13:13:05 -0000 1.56
@@ -69,7 +69,7 @@
void set_audio_source(ReadSource* source);
int init_recording(QByteArray bus);
- int process(nframes_t nframes, audio_sample_t* channelBuffer, uint
channel);
+ int process(nframes_t nframes);
void set_track_start_frame(nframes_t newTrackFirstFrame);
void set_name(const QString& name);
@@ -130,6 +130,7 @@
ReadSource* m_readSource;
QList<WriteSource* > writeSources;
QList<FadeCurve* > m_fades;
+ QList<Peak* > m_peaks;
AudioBus* m_captureBus;
FadeCurve* fadeIn;
FadeCurve* fadeOut;
Index: core/AudioSource.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.cpp,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- core/AudioSource.cpp 27 Jun 2007 13:17:06 -0000 1.25
+++ core/AudioSource.cpp 18 Jul 2007 13:13:05 -0000 1.26
@@ -67,7 +67,6 @@
{
QDomElement node = doc.createElement("Source");
node.setAttribute("channelcount", m_channelCount);
- node.setAttribute("filecount", m_fileCount);
node.setAttribute("origsheetid", m_origSongId);
node.setAttribute("dir", m_dir);
node.setAttribute("id", m_id);
@@ -87,7 +86,6 @@
QDomElement e = node.toElement();
m_channelCount = e.attribute("channelcount", "0").toInt();
- m_fileCount = e.attribute("filecount", "0").toInt();
m_origSongId = e.attribute("origsheetid", "0").toLongLong();
set_dir( e.attribute("dir", "" ));
m_id = e.attribute("id", "").toLongLong();
@@ -99,7 +97,7 @@
// For older project files, this should properly detect if the
// audio source was a recording or not., in fact this should suffice
// and the flag wasrecording would be unneeded, but oh well....
- if (m_origSongId != 0 && m_channelCount == 2 && m_fileCount == 2) {
+ if (m_origSongId != 0) {
m_wasRecording = true;
}
Index: core/AudioSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- core/AudioSource.h 20 Jun 2007 15:27:16 -0000 1.20
+++ core/AudioSource.h 18 Jul 2007 13:13:05 -0000 1.21
@@ -38,7 +38,7 @@
AudioSource(){};
~AudioSource();
- virtual void process_ringbuffer(audio_sample_t* framebuffer,
audio_sample_t* readbuffer = 0, bool seeking=false);
+ virtual void process_ringbuffer(audio_sample_t** framebuffer,
audio_sample_t* readbuffer = 0, bool seeking=false);
void set_name(const QString& name);
void set_dir(const QString& name);
@@ -56,12 +56,10 @@
qint64 get_orig_song_id() const {return m_origSongId;}
int get_rate() const;
uint get_channel_count() const;
- uint get_file_count() const {return m_fileCount;}
int get_bit_depth() const;
protected:
- uint m_channelCount;
- uint m_fileCount;
+ int m_channelCount;
qint64 m_origSongId;
QString m_dir;
qint64 m_id;
@@ -77,7 +75,7 @@
inline uint AudioSource::get_channel_count( ) const {return m_channelCount;}
-inline void AudioSource::process_ringbuffer(audio_sample_t*, audio_sample_t*,
bool) {}
+inline void AudioSource::process_ringbuffer(audio_sample_t**, audio_sample_t*,
bool) {}
inline qint64 AudioSource::get_id( ) const {return m_id;}
#endif
Index: core/core.pro
===================================================================
RCS file: /sources/traverso/traverso/src/core/core.pro,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- core/core.pro 13 Jul 2007 07:41:03 -0000 1.32
+++ core/core.pro 18 Jul 2007 13:13:05 -0000 1.33
@@ -34,7 +34,6 @@
InputEngine.cpp \
Mixer.cpp \
Peak.cpp \
- MonoReader.cpp \
Project.cpp \
ProjectManager.cpp \
ReadSource.cpp \
@@ -77,7 +76,6 @@
InputEngine.h \
Mixer.h \
Peak.h \
- MonoReader.h \
Project.h \
ProjectManager.h \
ReadSource.h \
@@ -114,3 +112,7 @@
win32{
INCLUDEPATH += ../../3thparty/include .
}
+SOURCES -= MonoReader.cpp
+
+HEADERS -= MonoReader.h
+
Index: core/DiskIO.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/DiskIO.cpp,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -b -r1.38 -r1.39
--- core/DiskIO.cpp 22 Jun 2007 12:29:27 -0000 1.38
+++ core/DiskIO.cpp 18 Jul 2007 13:13:05 -0000 1.39
@@ -150,7 +150,8 @@
m_hardDiskOverLoadCounter = 0;
// TODO This is a LARGE buffer, any ideas how to make it smaller ??
- framebuffer = new audio_sample_t[audiodevice().get_sample_rate() *
writebuffertime];
+ framebuffer[0] = new audio_sample_t[audiodevice().get_sample_rate() *
writebuffertime];
+ framebuffer[1] = new audio_sample_t[audiodevice().get_sample_rate() *
writebuffertime];
// We assume here that the audiofiles have max 2 channels, and
readbuffer time is max 3 seconds.
m_readbuffer = new audio_sample_t[audiodevice().get_sample_rate() * 6];
@@ -168,7 +169,8 @@
PENTERDES;
stop();
delete cpuTimeBuffer;
- delete [] framebuffer;
+ delete [] framebuffer[0];
+ delete [] framebuffer[1];
delete [] m_readbuffer;
}
@@ -189,7 +191,7 @@
m_stopWork = 0;
m_seeking = true;
- foreach(MonoReader* source, m_monoReaders) {
+ foreach(ReadSource* source, m_readSources) {
source->rb_seek_to_file_position(position);
}
@@ -243,7 +245,7 @@
int DiskIO::there_are_processable_sources( )
{
m_processableSources.clear();
- QList< MonoReader * > syncSources;
+ QList<ReadSource* > syncSources;
for (int i=6; i >= 0; --i) {
@@ -270,9 +272,9 @@
}
}
- for (int j=0; j<m_monoReaders.size(); ++j) {
+ for (int j=0; j<m_readSources.size(); ++j) {
- MonoReader* source = m_monoReaders.at(j);
+ ReadSource* source = m_readSources.at(j);
BufferStatus* status = source->get_buffer_status();
if (status->priority > i && source->is_active() &&
!status->needSync ) {
@@ -350,12 +352,7 @@
QMutexLocker locker(&mutex);
m_readSources.append(source);
-
- foreach(MonoReader* prs, source->get_mono_readers()) {
- prs->prepare_buffer();
- m_monoReaders.append(prs);
- }
-
+ source->prepare_buffer();
}
/**
@@ -387,10 +384,6 @@
QMutexLocker locker(&mutex);
m_readSources.removeAll(source);
-
- foreach(MonoReader* prs, source->get_mono_readers()) {
- m_monoReaders.removeAll(prs);
- }
}
Index: core/DiskIO.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/DiskIO.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- core/DiskIO.h 22 Jun 2007 12:29:28 -0000 1.17
+++ core/DiskIO.h 18 Jul 2007 13:13:05 -0000 1.18
@@ -29,7 +29,6 @@
#include "defines.h"
class ReadSource;
-class MonoReader;
class WriteSource;
class AudioSource;
class RingBuffer;
@@ -70,7 +69,6 @@
Song* m_song;
volatile size_t m_stopWork;
QList<ReadSource*> m_readSources;
- QList<MonoReader*> m_monoReaders;
QList<AudioSource*> m_processableSources;
QList<WriteSource*> m_writeSources;
DiskIOThread* m_diskThread;
@@ -83,7 +81,7 @@
trav_time_t lastCpuReadTime;
bool m_seeking;
int m_hardDiskOverLoadCounter;
- audio_sample_t* framebuffer;
+ audio_sample_t* framebuffer[2];
audio_sample_t* m_readbuffer;
Index: core/FlacAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/FlacAudioReader.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- core/FlacAudioReader.cpp 17 Jul 2007 00:49:55 -0000 1.4
+++ core/FlacAudioReader.cpp 18 Jul 2007 13:13:05 -0000 1.5
@@ -370,8 +370,6 @@
return false;
}
- m_nextFrame = start;
-
return true;
}
@@ -398,14 +396,14 @@
if (!m_flac->process_single()) {
PERROR("process_single() error\n");
m_flac->reset();
- seek(m_nextFrame);
+ seek(m_readPos);
return -1;
}
}
else {
- PERROR("flac_state() = %d\n",
m_flac->get_state());
+ PERROR("flac_state() = %d\n",
int(m_flac->get_state()));
m_flac->reset();
- seek(m_nextFrame);
+ seek(m_readPos);
return -1;
}
#else
@@ -418,14 +416,14 @@
if (!m_flac->process_single()) {
PERROR("process_single() error\n");
m_flac->reset();
- seek(m_nextFrame);
+ seek(m_readPos);
return -1;
}
}
else {
- PERROR("flac_state() = %d\n",
m_flac->get_state());
+ PERROR("flac_state() = %d\n",
int(m_flac->get_state()));
m_flac->reset();
- seek(m_nextFrame);
+ seek(m_readPos);
return -1;
}
#endif
@@ -451,7 +449,7 @@
// Pad end of file with 0s if necessary. (Shouldn't be necessary...)
int remainingSamplesRequested = sampleCount - samplesCoppied;
- int remainingSamplesInFile = get_length() * get_num_channels() -
(m_nextFrame * get_num_channels() + samplesCoppied);
+ int remainingSamplesInFile = get_length() * get_num_channels() -
(m_readPos * get_num_channels() + samplesCoppied);
if (samplesCoppied == 0 && remainingSamplesInFile > 0) {
int padLength = (remainingSamplesRequested >
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
//PERROR("padLength: %d", padLength);
@@ -463,9 +461,7 @@
samplesCoppied = sampleCount;
}
- m_nextFrame += samplesCoppied / get_num_channels();
-
- //printf("copied %d of %d. nextFrame: %lu of %lu\n", samplesCoppied,
sampleCount, m_nextFrame, get_length());
+ //printf("copied %d of %d. nextFrame: %lu of %lu\n", samplesCoppied,
sampleCount, m_readPos, get_length());
return samplesCoppied;
}
Index: core/MadAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/MadAudioReader.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/MadAudioReader.cpp 15 Jul 2007 19:59:35 -0000 1.5
+++ core/MadAudioReader.cpp 18 Jul 2007 13:13:06 -0000 1.6
@@ -697,8 +697,6 @@
d->overflowSize -= frameOffset;
}
- m_nextFrame = start;
-
return true;
}
@@ -791,7 +789,6 @@
memcpy(d->outputBuffer, d->overflowBuffer +
d->overflowStart, sampleCount * sizeof(audio_sample_t));
d->overflowSize -= sampleCount;
d->overflowStart += sampleCount;
- m_nextFrame += sampleCount / get_num_channels();
return sampleCount;
}
}
@@ -828,7 +825,7 @@
// is get_length() reporting incorrectly?
// are we not outputting the last mp3-frame for some reason?
int remainingSamplesRequested = sampleCount - samplesWritten;
- int remainingSamplesInFile = (get_length() - m_nextFrame) *
get_num_channels() - samplesWritten;
+ int remainingSamplesInFile = (get_length() - m_readPos) *
get_num_channels() - samplesWritten;
if (remainingSamplesRequested > 0 && remainingSamplesInFile > 0) {
int padLength = (remainingSamplesRequested >
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
memset(d->outputPointer, 0, padLength * sizeof(audio_sample_t));
@@ -842,9 +839,8 @@
samplesWritten = remainingSamplesInFile;
}
- //printf("at: %lu (total: %lu), request: %d (returned: %d)\n",
m_nextFrame, m_frames, sampleCount/get_num_channels(),
samplesWritten/get_num_channels());
+ //printf("at: %lu (total: %lu), request: %d (returned: %d)\n",
m_readPos, m_frames, sampleCount/get_num_channels(),
samplesWritten/get_num_channels());
- m_nextFrame += samplesWritten / get_num_channels();
return samplesWritten;
}
@@ -855,9 +851,9 @@
bool overflow = false;
int i;
- if ((nframes + ((d->outputPointer - d->outputBuffer)/get_num_channels()
+ m_nextFrame)) > get_length()) {
- nframes = get_length() - ((d->outputPointer -
d->outputBuffer)/get_num_channels() + m_nextFrame);
- //printf("!!!nframes: %lu, length: %lu, current: %lu\n",
nframes, get_length(), (d->outputPointer - d->outputBuffer)/get_num_channels()
+ m_nextFrame);
+ if ((nframes + ((d->outputPointer - d->outputBuffer)/get_num_channels()
+ m_readPos)) > get_length()) {
+ nframes = get_length() - ((d->outputPointer -
d->outputBuffer)/get_num_channels() + m_readPos);
+ //printf("!!!nframes: %lu, length: %lu, current: %lu\n",
nframes, get_length(), (d->outputPointer - d->outputBuffer)/get_num_channels()
+ m_readPos);
}
// now create the output
Index: core/Peak.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Peak.cpp,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- core/Peak.cpp 16 Jul 2007 01:48:11 -0000 1.36
+++ core/Peak.cpp 18 Jul 2007 13:13:06 -0000 1.37
@@ -56,7 +56,7 @@
ReadSource* rs = qobject_cast<ReadSource*>(source);
if (rs) {
- m_source = resources_manager()->get_readsource(rs->get_id(),
true);
+ m_source = resources_manager()->get_readsource(rs->get_id());
}
if (source->get_channel_count() > 1) {
@@ -299,27 +299,23 @@
// Micro view mode
} else {
nframes_t toRead = pixelcount * zoomStep[zoomLevel];
- audio_sample_t buf[toRead];
- audio_sample_t readbuffer[toRead*2];
-
- nframes_t readFrames = 0;
- nframes_t totalReadFrames = 0;
- do {
- readFrames = m_source->file_read(m_channel, buf +
totalReadFrames, startPos + totalReadFrames, toRead - totalReadFrames,
readbuffer);
- if (readFrames <= 0) {
- PERROR("readFrames < 0");
- break;
+ // Maybe they can be created on the stack for better
performance ?
+ audio_sample_t* audiobuf[m_source->get_channel_count()];
+ for (uint chan=0; chan < m_source->get_channel_count(); ++chan)
{
+ audiobuf[chan] = new audio_sample_t[toRead];
}
- totalReadFrames += readFrames;
- } while (totalReadFrames < toRead);
+ audio_sample_t readbuffer[toRead*2];
+
+ nframes_t readFrames = m_source->file_read(audiobuf, startPos,
toRead, readbuffer);
- if ( totalReadFrames != toRead) {
- PWARN("Unable to read nframes %d (only %d available)",
toRead, totalReadFrames);
- if (totalReadFrames == 0) {
+ if (readFrames == 0) {
return NO_PEAKDATA_FOUND;
}
- pixelcount = totalReadFrames / zoomStep[zoomLevel];
+
+ if ( readFrames != toRead) {
+ PWARN("Unable to read nframes %d (only %d available)",
toRead, readFrames);
+ pixelcount = readFrames / zoomStep[zoomLevel];
}
int count = 0;
@@ -333,7 +329,7 @@
for(int i=0; i < zoomStep[zoomLevel]; i++) {
if (pos > readFrames)
break;
- sample = buf[pos];
+ sample = audiobuf[m_channel][pos];
if (sample > valueMax)
valueMax = sample;
if (sample < valueMin)
@@ -356,6 +352,11 @@
int processtime = (int) (get_microseconds() - starttime);
printf("Process time: %d useconds\n\n", processtime);
#endif
+
+ for (uint chan=0; chan < m_source->get_channel_count(); ++chan)
{
+ delete audiobuf[chan];
+ }
+
return count;
}
@@ -604,7 +605,10 @@
}
}
- audio_sample_t* buf = new audio_sample_t[bufferSize];
+ audio_sample_t* buffer[m_source->get_channel_count()];
+ for (uint chan=0; chan<m_source->get_channel_count(); ++chan) {
+ buffer[chan] = new audio_sample_t[bufferSize];
+ }
audio_sample_t* readbuffer = new audio_sample_t[bufferSize * 2];
do {
@@ -613,12 +617,12 @@
goto out;
}
- readFrames = m_source->file_read(m_channel, buf,
totalReadFrames, bufferSize, readbuffer);
+ readFrames = m_source->file_read(buffer, totalReadFrames,
bufferSize, readbuffer);
if (readFrames <= 0) {
PERROR("readFrames < 0 during peak building");
break;
}
- process(buf, readFrames);
+ process(buffer[m_channel], readFrames);
totalReadFrames += readFrames;
p = (int) ((float)totalReadFrames /
((float)m_source->get_nframes() / 100.0));
@@ -638,7 +642,9 @@
ret = 1;
out:
- delete [] buf;
+ for (uint chan=0; chan<m_source->get_channel_count(); ++chan) {
+ delete buffer[chan];
+ }
delete [] readbuffer;
return ret;
@@ -666,9 +672,9 @@
int toRead = (int) ((startpos * NORMALIZE_CHUNK_SIZE) -
startframe);
audio_sample_t buf[toRead];
- int read = m_source->file_read(m_channel, buf, startframe,
toRead, readbuffer);
+// int read = m_source->file_read(m_channel, buf, startframe,
toRead, readbuffer);
- maxamp = Mixer::compute_peak(buf, read, maxamp);
+// maxamp = Mixer::compute_peak(buf, read, maxamp);
}
@@ -678,7 +684,8 @@
int endpos = (int) f;
int toRead = (int) ((f - (endframe / NORMALIZE_CHUNK_SIZE)) *
NORMALIZE_CHUNK_SIZE);
audio_sample_t buf[toRead];
- int read = m_source->file_read(m_channel, buf, endframe - toRead,
toRead, readbuffer);
+// int read = m_source->file_read(m_channel, buf, endframe - toRead,
toRead, readbuffer);
+ int read = 0;//m_source->file_read(m_channel, buf, endframe - toRead,
toRead, readbuffer);
maxamp = Mixer::compute_peak(buf, read, maxamp);
// Now that we have covered both boundary situations,
Index: core/ReadSource.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ReadSource.cpp,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -b -r1.39 -r1.40
--- core/ReadSource.cpp 15 Jul 2007 05:09:47 -0000 1.39
+++ core/ReadSource.cpp 18 Jul 2007 13:13:06 -0000 1.40
@@ -29,7 +29,10 @@
#include "AudioClip.h"
#include "DiskIO.h"
#include "Utils.h"
+#include "Song.h"
+#include "AudioDevice.h"
#include <QFile>
+#include "Config.h"
// Always put me below _all_ includes, this is needed
// in case we run with memory leak detection enabled!
@@ -44,10 +47,9 @@
// This constructor is called for existing (recorded/imported) audio sources
ReadSource::ReadSource(const QDomNode node)
: AudioSource(node)
- , m_refcount(0)
- , m_error(0)
- , m_clip(0)
{
+ private_init();
+
Project* project = pm().get_project();
// Check if the audiofile exists in our project audiosources dir
@@ -60,41 +62,35 @@
}
m_silent = (m_channelCount == 0);
- m_forPeaks = false;
}
// constructor for file import
ReadSource::ReadSource(const QString& dir, const QString& name)
: AudioSource(dir, name)
- , m_refcount(0)
- , m_error(0)
- , m_clip(0)
{
- AbstractAudioReader* reader =
AbstractAudioReader::create_audio_reader(m_fileName);
+ private_init();
- m_channelCount = 0;
+ AbstractAudioReader* reader =
AbstractAudioReader::create_audio_reader(m_fileName);
if (reader) {
m_channelCount = reader->get_num_channels();
delete reader;
+ } else {
+ m_channelCount = 0;
}
- m_fileCount = 1;
m_silent = false;
- m_forPeaks = false;
}
// Constructor for recorded audio.
ReadSource::ReadSource(const QString& dir, const QString& name, int
channelCount)
: AudioSource(dir, name)
- , m_refcount(0)
- , m_error(0)
- , m_clip(0)
{
- m_channelCount = m_fileCount = channelCount;
+ private_init();
+
+ m_channelCount = channelCount;
m_silent = false;
- m_forPeaks = false;
m_name = name + "-" + QString::number(m_id);
m_fileName = m_dir + m_name;
m_length = 0;
@@ -107,28 +103,35 @@
// Constructor for silent clips
ReadSource::ReadSource()
: AudioSource("", tr("Silence"))
- , m_refcount(0)
- , m_error(0)
- , m_clip(0)
{
+ private_init();
+
m_channelCount = 0;
- m_fileCount = 0;
m_silent = true;
}
+void ReadSource::private_init()
+{
+ m_refcount = 0;
+ m_error = 0;
+ m_clip = 0;
+ m_audioReader = 0;
+}
+
+
ReadSource::~ReadSource()
{
PENTERDES;
- foreach(MonoReader* source, m_sources) {
- delete source;
+ for(int i=0; i<m_buffers.size(); ++i) {
+ delete m_buffers.at(i);
}
-}
+ if (m_audioReader) {
+ delete m_audioReader;
+ }
-void ReadSource::set_is_for_peaks(bool forPeaks)
-{
- m_forPeaks = forPeaks;
+ delete m_bufferstatus;
}
@@ -156,80 +159,99 @@
}
- QString fileName = m_dir + m_name;
+ m_rbFileReadPos = 0;
+ m_rbRelativeFileReadPos = 0;
+ m_rbReady = 0;
+ m_needSync = 0;
+ m_syncInProgress = 0;
+ m_bufferUnderRunDetected = m_wasActivated = 0;
- if (m_wasRecording) {
- if (m_channelCount == 1 && m_fileCount == 1) {
- if ( (m_error = add_mono_reader(1, 0, fileName + "-ch"
+ QByteArray::number(0) + ".wav")) < 0) {
- return m_error;
- }
- } else if (m_channelCount == 2 && m_fileCount == 2) {
- if (((m_error = add_mono_reader(1, 0, fileName + "-ch"
+ QByteArray::number(0) + ".wav") < 0)) ||
- ((m_error = add_mono_reader(1, 1, fileName +
"-ch" + QByteArray::number(1) + ".wav")) < 0)) {
- return m_error;
+ bool useResampling = config().get_property("Conversion",
"DynamicResampling", false).toBool();
+
+ if (useResampling) {
+ int converter_type;
+ converter_type = config().get_property("Conversion",
"RTResamplingConverterType", 2).toInt();
+ // There should be another config option for ConverterType to
use for export (higher quality)
+ //converter_type = config().get_property("Conversion",
"ExportResamplingConverterType", 0).toInt();
+ m_audioReader =
AbstractAudioReader::create_resampled_audio_reader(m_fileName, converter_type);
}
- } else {
- PERROR("WasRecording section: Unsupported combination
of channelcount/filecount (%d/%d)", m_channelCount, m_fileCount);
- return (m_error = CHANNELCOUNT_FILECOUNT_MISMATCH);
+ else {
+ m_audioReader =
AbstractAudioReader::create_audio_reader(m_fileName);
}
- } else {
- if (m_channelCount == 1 && m_fileCount == 1) {
- if ((m_error = add_mono_reader(1, 0, fileName)) < 0) {
- return m_error;
- }
- } else if (m_channelCount == 2 && m_fileCount == 1) {
- if (((m_error = add_mono_reader(2, 0, fileName)) < 0)
|| ((m_error = add_mono_reader(2, 1, fileName)) < 0)) {
- return m_error;
+ if (m_audioReader == 0) {
+ return COULD_NOT_OPEN_FILE;
}
- } else {
- PERROR("Unsupported combination of
channelcount/filecount (%d/%d)", m_channelCount, m_fileCount);
- return (m_error = CHANNELCOUNT_FILECOUNT_MISMATCH);
+
+ if (m_channelCount > m_audioReader->get_num_channels()) {
+ PERROR("ReadAudioSource: file only contains %d channels; %d is
invalid as a channel number", m_audioReader->get_num_channels(),
m_channelCount);
+ delete m_audioReader;
+ m_audioReader = 0;
+ return INVALID_CHANNEL_COUNT;
}
+
+ if (m_audioReader->get_num_channels() == 0) {
+ PERROR("ReadAudioSource: not a valid channel count: %d",
m_audioReader->get_num_channels());
+ delete m_audioReader;
+ m_audioReader = 0;
+ return ZERO_CHANNELS;
}
+ m_length = m_audioReader->get_length();
+ m_rate = m_audioReader->get_rate();
+
+ m_bufferstatus = new BufferStatus;
return 1;
}
-int ReadSource::add_mono_reader(int sourceChannelCount, int channelNumber,
const QString& fileName)
-{
- int result = 1;
-
- MonoReader* source = new MonoReader(this, sourceChannelCount,
channelNumber, fileName);
- if ( (result = source->init(m_forPeaks)) > 0) {
- m_sources.append(source);
- } else {
- PERROR("Failed to initialize a MonoReader (%s)",
QS_C(fileName));
- delete source;
+int ReadSource::file_read(audio_sample_t** dst, nframes_t start, nframes_t
cnt, audio_sample_t* readbuffer) const
+{
+#if defined (profile)
+ trav_time_t starttime = get_microseconds();
+#endif
+ if (m_audioReader->get_num_channels() == 1) {
+ int result = m_audioReader->read_from(dst[0], start, cnt);
+#if defined (profile)
+ int processtime = (int) (get_microseconds() - starttime);
+ if (processtime > 40000)
+ printf("Process time for %s: %d useconds\n\n",
QS_C(m_fileName), processtime);
+#endif
return result;
}
- return result;
-}
+ float *ptr;
+ uint real_cnt = cnt * m_audioReader->get_num_channels();
-int ReadSource::file_read (int channel, audio_sample_t* dst, nframes_t start,
nframes_t cnt, audio_sample_t* readbuffer) const
-{
- Q_ASSERT(channel < m_sources.size());
- return m_sources.at(channel)->file_read(dst, start, cnt, readbuffer);
-}
+ // The readbuffer 'assumes' that there is max 2 channels...
+ Q_ASSERT(m_audioReader->get_num_channels() <= 2);
+ int nread = m_audioReader->read_from(readbuffer, start, real_cnt);
+#if defined (profile)
+ int processtime = (int) (get_microseconds() - starttime);
+ if (processtime > 40000)
+ printf("Process time for %s: %d useconds\n\n",
QS_C(m_fileName), processtime);
+#endif
+ ptr = readbuffer;
+ nread /= m_audioReader->get_num_channels();
-int ReadSource::rb_read(int channel, audio_sample_t* dst, nframes_t start,
nframes_t cnt)
-{
- Q_ASSERT(channel < m_sources.size());
- return m_sources.at(channel)->rb_read(dst, start, cnt);
-
-}
+ /* stride through the interleaved data */
+ // FIXME: deinterlace in AudioReader Classes instead of here
+ for (int32_t n = 0; n < nread; ++n) {
+ dst[0][n] = *ptr;
+ ptr += m_audioReader->get_num_channels();
+ }
-void ReadSource::set_active(bool active)
-{
- PENTER2;
- foreach(MonoReader* source, m_sources) {
- source->set_active(active);
+ ptr = readbuffer+1;
+ for (int32_t n = 0; n < nread; ++n) {
+ dst[1][n] = *ptr;
+ ptr += m_audioReader->get_num_channels();
}
+
+
+ return nread;
}
@@ -243,22 +265,11 @@
return source;
}
-
void ReadSource::set_audio_clip( AudioClip * clip )
{
PENTER;
Q_ASSERT(clip);
m_clip = clip;
- foreach(MonoReader* source, m_sources) {
- source->set_audio_clip(clip);
- }
-}
-
-
-Peak * ReadSource::get_peak( int channel )
-{
- Q_ASSERT(channel < m_sources.size());
- return m_sources.at(channel)->get_peak();
}
nframes_t ReadSource::get_nframes( ) const
@@ -294,4 +305,250 @@
return 1;
}
+
+
+
+int ReadSource::rb_read(audio_sample_t** dst, nframes_t start, nframes_t count)
+{
+
+ if ( ! m_rbReady ) {
+// printf("ringbuffer not ready\n");
+ return 0;
+ }
+
+ if (start != m_rbRelativeFileReadPos) {
+ int available = m_buffers.at(0)->read_space();
+// printf("start %d, m_rbFileReadPos %d\n", start,
m_rbRelativeFileReadPos);
+ if ( (start > m_rbRelativeFileReadPos) &&
(m_rbRelativeFileReadPos + available) > (start + count)) {
+ int advance = start - m_rbRelativeFileReadPos;
+ if (available < advance) {
+ printf("available < advance !!!!!!!\n");
+ }
+ for (int i=m_buffers.size()-1; i>=0; --i) {
+ m_buffers.at(i)->increment_read_ptr(advance);
+ }
+ m_rbRelativeFileReadPos += advance;
+ } else {
+ start_resync(start + (m_clip->get_track_start_frame() +
m_clip->get_source_start_frame()));
+ return 0;
+ }
+ }
+
+ nframes_t readcount = 0;
+
+ for (int chan=0; chan<m_channelCount; ++chan) {
+
+ readcount = m_buffers.at(chan)->read(dst[chan], count);
+
+ if (readcount != count) {
+ // Hmm, not sure what to do in this case....
+ }
+
+ }
+
+ m_rbRelativeFileReadPos += readcount;
+
+ return readcount;
+}
+
+
+int ReadSource::rb_file_read(audio_sample_t** dst, nframes_t cnt,
audio_sample_t* readbuffer )
+{
+ int readFrames = file_read(dst, m_rbFileReadPos, cnt, readbuffer);
+ m_rbFileReadPos += readFrames;
+
+ return readFrames;
+}
+
+
+void ReadSource::rb_seek_to_file_position( nframes_t position )
+{
+ Q_ASSERT(m_clip);
+
+// printf("rb_seek_to_file_position:: seeking to %d\n", position);
+
+ // calculate position relative to the file!
+ long fileposition = position - (m_clip->get_track_start_frame() +
m_clip->get_source_start_frame());
+
+ if ((long)m_rbFileReadPos == fileposition) {
+// printf("ringbuffer allready at position %d\n", position);
+ return;
+ }
+
+ // check if the clip's start position is within the range
+ // if not, fill the buffer from the earliest point this clip
+ // will come into play.
+ if (fileposition < 0) {
+// printf("not seeking to %ld, but too %d\n\n",
fileposition,m_clip->get_source_start_frame());
+ // Song's start from 0, this makes a period start from
+ // 0 - 1023 for example, the nframes is 1024!
+ // Setting a songs new position is on 1024, and NOT
+ // 1023.. Hmm, something isn't correct here, but at least
substract 1
+ // to make this thing work!
+ fileposition = m_clip->get_source_start_frame() - 1;
+ }
+
+// printf("rb_seek_to_file_position:: seeking to relative pos: %d\n",
fileposition);
+ for (int i=0; i<m_buffers.size(); ++i) {
+ m_buffers.at(i)->reset();
+ }
+ m_rbFileReadPos = fileposition;
+ m_rbRelativeFileReadPos = fileposition;
+}
+
+void ReadSource::process_ringbuffer(audio_sample_t** framebuffer,
audio_sample_t* readbuffer, bool seeking)
+{
+ // Do nothing if we passed the lenght of the AudioFile.
+ if (m_rbFileReadPos >= m_length) {
+// printf("returning, m_rbFileReadPos > m_length! (%d > %d)\n",
m_rbFileReadPos, m_source->m_length);
+ if (m_syncInProgress) {
+ finish_resync();
+ }
+ return;
+ }
+
+ // Calculate the number of samples we can write into the buffer
+ int writeSpace = m_buffers.at(0)->write_space();
+
+ // The amount of chunks which can be 'read'
+ int chunkCount = (int)(writeSpace / m_chunkSize);
+
+ int toRead = m_chunkSize;
+
+ if (seeking) {
+ toRead = writeSpace;
+// printf("doing a full seek buffer fill\n");
+ } else if (m_syncInProgress) {
+ // Currently, we fill the buffer completely.
+ // For some reason, filling it with 1/4 at a time
+ // doesn't fill it consitently, and thus giving audible
artifacts.
+ /* toRead = m_chunkSize * 2;*/
+ toRead = writeSpace;
+ } else if (chunkCount == 0) {
+ // If we are nearing the end of the source file it could be
possible
+ // we only need to read the last samples which is smaller in
size then
+ // chunksize. If so, set toRead to m_source->m_length -
rbFileReasPos
+ if ( (int) (m_length - m_rbFileReadPos) <= m_chunkSize) {
+ toRead = m_length - m_rbFileReadPos;
+ } else {
+ printf("MonoReader:: chunkCount == 0, but not at end of
file, this shouldn't happen!!\n");
+ return;
+ }
+ }
+
+ // Read in the samples from source
+ nframes_t toWrite = rb_file_read(framebuffer, toRead, readbuffer);
+
+ // and write it to the ringbuffer
+ for (int i=m_buffers.size()-1; i>=0; --i) {
+ m_buffers.at(i)->write(framebuffer[i], toWrite);
+ }
+}
+
+
+void ReadSource::recover_from_buffer_underrun(nframes_t position)
+{
+// printf("buffer underrun detected!\n");
+ m_bufferUnderRunDetected = 1;
+ start_resync(position);
+}
+
+void ReadSource::start_resync( nframes_t position )
+{
+// printf("starting resync!\n");
+ m_syncPos = position;
+ m_rbReady = 0;
+ m_needSync = 1;
+}
+
+void ReadSource::finish_resync()
+{
+// printf("sync finished\n");
+ m_needSync = 0;
+ m_bufferUnderRunDetected = 0;
+ m_rbReady = 1;
+ m_syncInProgress = 0;
+}
+
+void ReadSource::sync(audio_sample_t** framebuffer, audio_sample_t* readbuffer)
+{
+ PENTER2;
+ if (!m_needSync) {
+ return;
+ }
+
+ if (!m_syncInProgress) {
+ rb_seek_to_file_position(m_syncPos);
+ m_syncInProgress = 1;
+ }
+
+ // Currently, we fill the buffer completely.
+ // For some reason, filling it with 1/4 at a time
+ // doesn't fill it consitently, and thus giving audible artifacts.
+ process_ringbuffer(framebuffer, readbuffer);
+
+ if (m_buffers.at(0)->write_space() == 0) {
+ finish_resync();
+ }
+
+// PWARN("Resyncing ringbuffer finished");
+}
+
+
+
+void ReadSource::prepare_buffer( )
+{
+ PENTER;
+
+ Q_ASSERT(m_clip);
+
+ float size = config().get_property("Hardware", "readbuffersize",
1.0).toDouble();
+
+ m_bufferSize = (int) (size * audiodevice().get_sample_rate());
+
+ m_chunkSize = m_bufferSize / DiskIO::bufferdividefactor;
+
+ for (int i=0; i<m_channelCount; ++i) {
+ m_buffers.append(new RingBufferNPT<float>(m_bufferSize));
+ }
+
+ start_resync(m_clip->get_song()->get_working_frame());
+}
+
+BufferStatus* ReadSource::get_buffer_status()
+{
+ int freespace = m_buffers.at(0)->write_space();
+
+ if (m_rbFileReadPos >= m_length) {
+ m_bufferstatus->fillStatus = 100;
+ freespace = 0;
+ } else {
+ m_bufferstatus->fillStatus = (int) (((float)freespace /
m_bufferSize) * 100);
+ }
+
+ m_bufferstatus->bufferUnderRun = m_bufferUnderRunDetected;
+ m_bufferstatus->needSync = m_needSync;
+
+ m_bufferstatus->priority = (int) (freespace / m_chunkSize);
+
+ return m_bufferstatus;
+}
+
+void ReadSource::set_active(bool active)
+{
+ if (m_active == active)
+ return;
+
+ if (active) {
+ m_active = 1;
+// m_wasActivated = 1;
+// printf("setting private readsource %s to active\n",
QS_C(m_fileName));
+ } else {
+// printf("setting private readsource %s to IN-active\n",
QS_C(m_fileName));
+ m_active = 0;
+ }
+}
+
+
//eof
+
Index: core/ReadSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ReadSource.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -b -r1.29 -r1.30
--- core/ReadSource.h 15 Jul 2007 05:09:47 -0000 1.29
+++ core/ReadSource.h 18 Jul 2007 13:13:06 -0000 1.30
@@ -23,10 +23,12 @@
#define READSOURCE_H
#include "AudioSource.h"
+#include "RingBufferNPT.h"
+#include "defines.h"
+class AbstractAudioReader;
class AudioClip;
-class Peak;
-class MonoReader;
+struct BufferStatus;
class ReadSource : public AudioSource
{
@@ -47,37 +49,64 @@
ReadSource* deep_copy();
- int rb_read(int channel, audio_sample_t* dst, nframes_t start,
nframes_t cnt);
- int file_read(int channel, audio_sample_t* dst, nframes_t start,
nframes_t cnt, audio_sample_t* readbuffer) const;
+ int rb_read(audio_sample_t** dest, nframes_t start, nframes_t cnt);
+ void rb_seek_to_file_position(nframes_t position);
+
+ int file_read(audio_sample_t** dst, nframes_t start, nframes_t cnt,
audio_sample_t* readbuffer) const;
int init();
int get_error() const {return m_error;}
int set_file(const QString& filename);
void set_active(bool active);
- void set_is_for_peaks(bool forPeaks);
void set_audio_clip(AudioClip* clip);
- Peak* get_peak(int channel);
nframes_t get_nframes() const;
- QList<MonoReader*> get_mono_readers() const {return m_sources;}
+ void sync(audio_sample_t** framebuffer, audio_sample_t* readbuffer);
+ void process_ringbuffer(audio_sample_t** framebuffer, audio_sample_t*
readbuffer, bool seeking=false);
+ void prepare_buffer();
+ size_t is_active() const;
+ BufferStatus* get_buffer_status();
private:
- QList<MonoReader*> m_sources;
+ QList<RingBufferNPT<float>*> m_buffers;
+ AbstractAudioReader* m_audioReader;
+ AudioClip* m_clip;
int m_refcount;
int m_error;
- AudioClip* m_clip;
bool m_silent;
- bool m_forPeaks;
+ uint m_bufferSize;
+ int m_chunkSize;
+ nframes_t m_rbFileReadPos;
+ nframes_t m_rbRelativeFileReadPos;
+ volatile size_t m_syncPos;
+ volatile size_t m_rbReady;
+ volatile size_t m_needSync;
+ volatile size_t m_active;
+ volatile size_t m_wasActivated;
+ volatile size_t m_bufferUnderRunDetected;
+ bool m_syncInProgress;
+
+ BufferStatus* m_bufferstatus;
int ref() { return m_refcount++;}
- int add_mono_reader(int channel, int channelNumber, const QString&
fileName);
- friend class MonoReader;
+ void private_init();
+ void start_resync(nframes_t position);
+ void finish_resync();
+ void recover_from_buffer_underrun(nframes_t position);
+ int rb_file_read(audio_sample_t** dst, nframes_t cnt, audio_sample_t*
readbuffer);
+
friend class ResourcesManager;
signals:
void stateChanged();
};
+
+inline size_t ReadSource::is_active() const
+{
+ return m_active;
+}
+
#endif
Index: core/ResampleAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- core/ResampleAudioReader.cpp 15 Jul 2007 05:14:47 -0000 1.6
+++ core/ResampleAudioReader.cpp 18 Jul 2007 13:13:06 -0000 1.7
@@ -36,8 +36,8 @@
m_fileBuffer = 0;
m_fileBufferLength = 0;
- m_realReader = AbstractAudioReader::create_audio_reader(filename);
- if (!m_realReader) {
+ m_reader = AbstractAudioReader::create_audio_reader(filename);
+ if (!m_reader) {
PERROR("ResampleAudioReader: couldn't create AudioReader");
return;
}
@@ -53,8 +53,8 @@
src_delete(m_srcState);
}
- if (m_realReader) {
- delete m_realReader;
+ if (m_reader) {
+ delete m_reader;
}
if (m_fileBuffer) {
@@ -70,11 +70,11 @@
}
int error;
- m_srcState = src_new (converter_type, m_realReader->get_num_channels(),
&error);
+ m_srcState = src_new (converter_type, m_reader->get_num_channels(),
&error);
if (!m_srcState) {
PERROR("ResampleAudioReader: couldn't create libSampleRate
SRC_STATE");
- delete m_realReader;
- m_realReader = 0;
+ delete m_reader;
+ m_reader = 0;
}
reset();
@@ -93,8 +93,8 @@
// Get from child AudioReader
int ResampleAudioReader::get_num_channels()
{
- if (m_realReader) {
- return m_realReader->get_num_channels();
+ if (m_reader) {
+ return m_reader->get_num_channels();
}
return 0;
}
@@ -103,20 +103,23 @@
// Get from child AudioReader, convert from file's frames to song's frames
nframes_t ResampleAudioReader::get_length()
{
- if (m_realReader) {
- if (audiodevice().get_sample_rate() ==
m_realReader->get_rate()) {
- return m_realReader->get_length();
+ if (m_reader) {
+ if (audiodevice().get_sample_rate() ==
(uint)m_reader->get_rate()) {
+ return m_reader->get_length();
}
- return file_to_song_frame(m_realReader->get_length());
+ return file_to_song_frame(m_reader->get_length());
}
return 0;
}
// Always the rate of the audio device
+// Remon @ Ben: why is that? imo it should just return the real rate, how else
+// is anything gonna to know what the 'real' rate of an audiofile is ?
int ResampleAudioReader::get_rate()
{
- return audiodevice().get_sample_rate();
+ return m_reader->get_rate();
+// return audiodevice().get_sample_rate();
}
@@ -124,17 +127,15 @@
// otherwise convert and seek
bool ResampleAudioReader::seek(nframes_t start)
{
- Q_ASSERT(m_realReader);
+ Q_ASSERT(m_reader);
- if (audiodevice().get_sample_rate() == m_realReader->get_rate()) {
- return m_realReader->seek(start);
+ if (audiodevice().get_sample_rate() == (uint)m_reader->get_rate()) {
+ return m_reader->seek(start);
}
reset();
- m_nextFrame = start;
-
- return m_realReader->seek(song_to_file_frame(start));
+ return m_reader->seek(song_to_file_frame(start));
}
@@ -143,7 +144,7 @@
int ResampleAudioReader::read(audio_sample_t* dst, int sampleCount)
{
uint samplesRead;
- Q_ASSERT(m_realReader);
+ Q_ASSERT(m_reader);
/////////////////////////////////
// Ben says: FIXME: Add an overflow buffer, and grab more samples at a
time, saving the extra to the overflow.
@@ -151,9 +152,8 @@
/////////////////////////////////
// pass through if not changing sampleRate.
- if (audiodevice().get_sample_rate() == m_realReader->get_rate()) {
- samplesRead = m_realReader->read(dst, sampleCount);
- m_nextFrame += samplesRead / get_num_channels();
+ if (audiodevice().get_sample_rate() == (uint)m_reader->get_rate()) {
+ samplesRead = m_reader->read(dst, sampleCount);
return samplesRead;
}
@@ -164,7 +164,7 @@
}
// make sure that the reusable m_fileBuffer is big enough for this read
- if (m_fileBufferLength < fileCnt) {
+ if ((uint)m_fileBufferLength < fileCnt) {
if (m_fileBuffer) {
delete m_fileBuffer;
}
@@ -172,7 +172,7 @@
m_fileBufferLength = fileCnt;
}
- samplesRead = m_realReader->read(m_fileBuffer, fileCnt);
+ samplesRead = m_reader->read(m_fileBuffer, fileCnt);
//printf("Resampler: sampleCount %lu, fileCnt %lu, returned %lu\n",
sampleCount/get_num_channels(), fileCnt/get_num_channels(),
samplesRead/get_num_channels());
@@ -181,7 +181,7 @@
m_srcData.input_frames = samplesRead / get_num_channels();
m_srcData.data_out = dst;
m_srcData.output_frames = sampleCount / get_num_channels();
- m_srcData.src_ratio = (double) audiodevice().get_sample_rate() /
m_realReader->get_rate();
+ m_srcData.src_ratio = (double) audiodevice().get_sample_rate() /
m_reader->get_rate();
src_set_ratio(m_srcState, m_srcData.src_ratio);
if (src_process(m_srcState, &m_srcData)) {
@@ -193,7 +193,7 @@
// Pad end of file with 0s if necessary
int remainingSamplesRequested = sampleCount - samplesRead;
- int remainingSamplesInFile = (get_length() - m_nextFrame -
m_srcData.output_frames_gen) * get_num_channels();
+ int remainingSamplesInFile = (get_length() - m_readPos -
m_srcData.output_frames_gen) * get_num_channels();
if (samplesRead == 0 && remainingSamplesRequested > 0 &&
remainingSamplesInFile > 0) {
int padLength = (remainingSamplesRequested >
remainingSamplesInFile) ? remainingSamplesInFile : remainingSamplesRequested;
@@ -203,12 +203,11 @@
}
// Truncate so we don't return too many samples
- if (samplesRead > remainingSamplesInFile) {
+ if (samplesRead > (uint)remainingSamplesInFile) {
printf("Resampler: truncating: %d\n", samplesRead -
remainingSamplesInFile);
samplesRead = remainingSamplesInFile;
}
- m_nextFrame += samplesRead / get_num_channels();
//printf("Resampler: req: %d, got: %d\n", sampleCount, samplesRead);
return samplesRead;
@@ -217,16 +216,16 @@
nframes_t ResampleAudioReader::song_to_file_frame(nframes_t frame)
{
- Q_ASSERT(m_realReader);
+ Q_ASSERT(m_reader);
- return (nframes_t)(frame * (((double) m_realReader->get_rate()) /
audiodevice().get_sample_rate()));
+ return (nframes_t)(frame * (((double) m_reader->get_rate()) /
audiodevice().get_sample_rate()));
}
nframes_t ResampleAudioReader::file_to_song_frame(nframes_t frame)
{
- Q_ASSERT(m_realReader);
+ Q_ASSERT(m_reader);
- return (nframes_t)(frame * (((double) audiodevice().get_sample_rate())
/ m_realReader->get_rate()));
+ return (nframes_t)(frame * (((double) audiodevice().get_sample_rate())
/ m_reader->get_rate()));
}
Index: core/ResampleAudioReader.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResampleAudioReader.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/ResampleAudioReader.h 15 Jul 2007 05:14:48 -0000 1.5
+++ core/ResampleAudioReader.h 18 Jul 2007 13:13:06 -0000 1.6
@@ -28,6 +28,7 @@
class ResampleAudioReader : public AbstractAudioReader
{
+
public:
ResampleAudioReader(QString filename, int converter_type);
~ResampleAudioReader();
@@ -38,8 +39,6 @@
bool seek(nframes_t start);
int read(audio_sample_t* dst, int sampleCount);
- // Shouldn't ever actually get called
- static bool can_decode(QString filename) {return false;}
protected:
void init(int converter_type);
@@ -48,7 +47,7 @@
nframes_t song_to_file_frame(nframes_t frame);
nframes_t file_to_song_frame(nframes_t frame);
- AbstractAudioReader* m_realReader;
+ AbstractAudioReader* m_reader;
SRC_STATE* m_srcState;
SRC_DATA m_srcData;
audio_sample_t *m_fileBuffer;
Index: core/ResourcesManager.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResourcesManager.cpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- core/ResourcesManager.cpp 15 Jul 2007 05:09:47 -0000 1.20
+++ core/ResourcesManager.cpp 18 Jul 2007 13:13:07 -0000 1.21
@@ -211,7 +211,7 @@
}
-ReadSource * ResourcesManager::get_readsource( qint64 id, bool forPeaks )
+ReadSource * ResourcesManager::get_readsource(qint64 id)
{
SourceData* data = m_sources.value(id);
@@ -230,8 +230,6 @@
source->ref();
}
- source->set_is_for_peaks(forPeaks);
-
if ( source->init() < 0) {
info().warning( tr("ResourcesManager:: Failed to initialize
ReadSource %1")
.arg(source->get_filename()));
@@ -338,8 +336,9 @@
SourceData* sourcedata = m_sources.value(clip->get_readsource_id());
if (!sourcedata) {
PERROR("Source %lld not in database",
clip->get_readsource_id());
- }
+ } else {
sourcedata->clipCount--;
+ }
emit clipRemoved(clip);
}
Index: core/ResourcesManager.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ResourcesManager.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- core/ResourcesManager.h 15 Jul 2007 05:09:47 -0000 1.12
+++ core/ResourcesManager.h 18 Jul 2007 13:13:07 -0000 1.13
@@ -63,7 +63,7 @@
bool is_clip_in_use(qint64) const;
bool is_source_in_use(qint64 id) const;
- ReadSource* get_readsource(qint64 id, bool forPeaks = false);
+ ReadSource* get_readsource(qint64 id);
QList<ReadSource*> get_all_audio_sources() const;
Index: core/SFAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/SFAudioReader.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- core/SFAudioReader.cpp 8 Jul 2007 23:16:56 -0000 1.3
+++ core/SFAudioReader.cpp 18 Jul 2007 13:13:07 -0000 1.4
@@ -115,6 +115,7 @@
{
Q_ASSERT(m_sf);
+
if (start >= get_length()) {
return false;
}
@@ -126,8 +127,6 @@
return false;
}
- m_nextFrame = start;
-
return true;
}
@@ -140,8 +139,6 @@
// FIXME: deinterlace here instead of in MonoReader
- m_nextFrame += samplesRead / get_num_channels();
-
return samplesRead;
}
Index: core/Song.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Song.cpp,v
retrieving revision 1.122
retrieving revision 1.123
diff -u -b -r1.122 -r1.123
--- core/Song.cpp 30 Jun 2007 00:15:31 -0000 1.122
+++ core/Song.cpp 18 Jul 2007 13:13:07 -0000 1.123
@@ -919,6 +919,13 @@
void Song::audiodevice_params_changed()
{
resize_buffer(true, audiodevice().get_buffer_size());
+
+ // The samplerate possibly has been changed, this initiates
+ // a seek in DiskIO, which clears the buffers and refills them
+ // with the correct resampled audio data!
+ // We need to seek to a different position then the current one,
+ // else the seek won't happen at all :)
+ set_transport_pos(m_transportFrame + audiodevice().get_buffer_size());
}
int Song::get_bitdepth( )
Index: core/Track.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Track.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- core/Track.cpp 5 Jun 2007 11:14:32 -0000 1.62
+++ core/Track.cpp 18 Jul 2007 13:13:07 -0000 1.63
@@ -414,7 +414,6 @@
AudioBus* bus = m_song->get_render_bus();
bus->silence_buffers(nframes);
- audio_sample_t* mixdown = m_song->mixdown;
int result;
float gainFactor, panFactor;
@@ -422,8 +421,6 @@
for (int i=0; i<audioClipList.size(); ++i) {
- memset (mixdown, 0, sizeof (audio_sample_t) * nframes);
-
AudioClip* clip = audioClipList.at(i);
if (isArmed && clip->recording_state() ==
AudioClip::NO_RECORDING) {
@@ -431,17 +428,18 @@
continue;
}
- for (int chan=0; chan<bus->get_channel_count(); ++chan) {
- result = clip->process(nframes, mixdown, chan);
+ result = clip->process(nframes);
if (result <= 0) {
continue;
}
processResult |= result;
+ }
- gainFactor = get_gain() * clip->get_gain();
+ for (int chan=0; chan<bus->get_channel_count(); ++chan) {
+ gainFactor = get_gain();
if ( (chan == 0) && (m_pan > 0)) {
panFactor = 1 - m_pan;
@@ -453,8 +451,7 @@
gainFactor *= panFactor;
}
- Mixer::mix_buffers_with_gain(bus->get_buffer(chan,
nframes), mixdown, nframes, gainFactor);
- }
+ Mixer::apply_gain_to_buffer(bus->get_buffer(chan, nframes),
nframes, gainFactor);
}
processResult |= m_pluginChain->process_post_fader(bus, nframes);
Index: core/VorbisAudioReader.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/VorbisAudioReader.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- core/VorbisAudioReader.cpp 15 Jul 2007 05:14:48 -0000 1.5
+++ core/VorbisAudioReader.cpp 18 Jul 2007 13:13:07 -0000 1.6
@@ -123,8 +123,6 @@
return false;
}
- m_nextFrame = start;
-
return true;
}
@@ -164,8 +162,6 @@
totalRead += samplesRead * get_num_channels();
}
- m_nextFrame += totalRead / get_num_channels();
-
return totalRead;
}
Index: traverso/songcanvas/AudioClipView.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/songcanvas/AudioClipView.cpp,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -b -r1.80 -r1.81
--- traverso/songcanvas/AudioClipView.cpp 8 Jul 2007 19:45:06 -0000
1.80
+++ traverso/songcanvas/AudioClipView.cpp 18 Jul 2007 13:13:07 -0000
1.81
@@ -268,6 +268,10 @@
nframes_t clipstartoffset = m_clip->get_source_start_frame();
Peak* peak = m_clip->get_peak_for_channel(chan);
+ if (!peak) {
+ PERROR("No Peak object available for clip %s channel
%d", QS_C(m_clip->get_name()), chan);
+ return;
+ }
int availpeaks = peak->calculate_peaks( buffers[chan],
microView ?
m_song->get_hzoom() : m_song->get_hzoom() + 1,
(xstart *
m_sv->scalefactor) + clipstartoffset,
Index: core/MonoReader.cpp
===================================================================
RCS file: core/MonoReader.cpp
diff -N core/MonoReader.cpp
--- core/MonoReader.cpp 15 Jul 2007 20:17:51 -0000 1.22
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,418 +0,0 @@
-/*
-Copyright (C) 2006-2007 Remon Sijrier
-
-This file is part of Traverso
-
-Traverso 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-*/
-
-
-#include "MonoReader.h"
-
-#include "Peak.h"
-#include "ProjectManager.h"
-#include "Project.h"
-#include "AudioClip.h"
-#include "ReadSource.h"
-#include "Utils.h"
-#include <Config.h>
-#include <AudioDevice.h>
-#include <DiskIO.h>
-#include <Song.h>
-#include "AbstractAudioReader.h"
-
-// Always put me below _all_ includes, this is needed
-// in case we run with memory leak detection enabled!
-#include "Debugger.h"
-
-
-
-MonoReader::MonoReader(ReadSource* source, int sourceChannelCount, int
channelNumber, const QString& fileName)
- : AudioSource(),
- m_source(source),
- m_buffer(0),
- m_peak(0),
- m_audioReader(0),
- m_sourceChannelCount(sourceChannelCount),
- m_channelNumber(channelNumber),
- m_fileName(fileName)
-{
- PENTERCONS;
- m_bufferstatus = new BufferStatus;
-}
-
-MonoReader::~MonoReader()
-{
- PENTERDES;
- if (m_buffer) {
- delete m_buffer;
- }
- if (m_peak) {
- m_peak->close();
- }
- if (m_audioReader) {
- delete m_audioReader;
- }
-
- delete m_bufferstatus;
-}
-
-
-int MonoReader::init(bool forPeaks)
-{
- PENTER;
-
- Q_ASSERT(m_audioReader == 0);
-
- m_rbFileReadPos = 0;
- m_rbRelativeFileReadPos = 0;
- m_rbReady = 0;
- m_needSync = 0;
- m_syncInProgress = 0;
- m_clip = 0;
- m_bufferUnderRunDetected = m_wasActivated = 0;
-
- bool useResampling = config().get_property("Conversion",
"DynamicResampling", false).toBool();
-
- if (useResampling) {
- int converter_type;
- if (forPeaks) {
- converter_type = 4; // Very fast, and acurate enough
for drawing
- }
- else {
- converter_type = config().get_property("Conversion",
"RTResamplingConverterType", 2).toInt();
- // There should be another config option for
ConverterType to use for export (higher quality)
- //converter_type = config().get_property("Conversion",
"ExportResamplingConverterType", 0).toInt();
- }
- m_audioReader =
AbstractAudioReader::create_resampled_audio_reader(m_fileName, converter_type);
- }
- else {
- m_audioReader =
AbstractAudioReader::create_audio_reader(m_fileName);
- }
-
- if (m_audioReader == 0) {
- return ReadSource::COULD_NOT_OPEN_FILE;
- }
-
- if (m_sourceChannelCount > m_audioReader->get_num_channels()) {
- PERROR("ReadAudioSource: file only contains %d channels; %d is
invalid as a channel number", m_audioReader->get_num_channels(),
m_sourceChannelCount);
- delete m_audioReader;
- m_audioReader = 0;
- return ReadSource::INVALID_CHANNEL_COUNT;
- }
-
- if (m_audioReader->get_num_channels() == 0) {
- PERROR("ReadAudioSource: not a valid channel count: %d",
m_audioReader->get_num_channels());
- delete m_audioReader;
- m_audioReader = 0;
- return ReadSource::ZERO_CHANNELS;
- }
-
- m_source->m_length = m_audioReader->get_length();
- m_length = m_audioReader->get_length();
- m_source->m_rate = m_audioReader->get_rate();
-
- if (!forPeaks) {
- m_peak = new Peak(m_source, m_channelNumber);
- }
- else {
- m_peak = 0;
- }
-
- return 1;
-}
-
-
-int MonoReader::file_read (audio_sample_t* dst, nframes_t start, nframes_t
cnt, audio_sample_t* readbuffer) const
-{
-#if defined (profile)
- trav_time_t starttime = get_microseconds();
-#endif
- if (m_audioReader->get_num_channels() == 1) {
- int result = m_audioReader->read_from(dst, start, cnt);
-#if defined (profile)
- int processtime = (int) (get_microseconds() - starttime);
- if (processtime > 40000)
- printf("Process time for %s, channel %d: %d
useconds\n\n", QS_C(m_fileName), m_channelNumber, processtime);
-#endif
- return result;
- }
-
- float *ptr;
- uint real_cnt = cnt * m_audioReader->get_num_channels();
-
- // The readbuffer 'assumes' that there is max 2 channels...
- Q_ASSERT(m_audioReader->get_num_channels() <= 2);
-
- int nread = m_audioReader->read_from(readbuffer, start, real_cnt);
-#if defined (profile)
- int processtime = (int) (get_microseconds() - starttime);
- if (processtime > 40000)
- printf("Process time for %s, channel %d: %d useconds\n\n",
QS_C(m_fileName), m_channelNumber, processtime);
-#endif
- ptr = readbuffer + m_channelNumber;
- nread /= m_audioReader->get_num_channels();
-
- /* stride through the interleaved data */
- // FIXME: deinterlace in AudioReader Classes instead of here
-
- for (int32_t n = 0; n < nread; ++n) {
- dst[n] = *ptr;
- ptr += m_audioReader->get_num_channels();
- }
-
-
- return nread;
-}
-
-
-int MonoReader::rb_read(audio_sample_t* dst, nframes_t start, nframes_t count)
-{
-
- if ( ! m_rbReady ) {
-// printf("ringbuffer not ready\n");
- return 0;
- }
-
- if (start != m_rbRelativeFileReadPos) {
- int available = m_buffer->read_space();
-// printf("start %d, m_rbFileReadPos %d\n", start,
m_rbRelativeFileReadPos);
- if ( (start > m_rbRelativeFileReadPos) &&
(m_rbRelativeFileReadPos + available) > (start + count)) {
- int advance = start - m_rbRelativeFileReadPos;
- if (available < advance)
- printf("available < advance !!!!!!!\n");
- m_buffer->increment_read_ptr(advance);
- m_rbRelativeFileReadPos += advance;
- } else {
- start_resync(start + (m_clip->get_track_start_frame() +
m_clip->get_source_start_frame()));
- return 0;
- }
- }
-
- nframes_t readcount = m_buffer->read(dst, count);
-
- if (readcount != count) {
- // Hmm, not sure what to do in this case....
- }
-
- m_rbRelativeFileReadPos += readcount;
-
- return readcount;
-}
-
-
-int MonoReader::rb_file_read(audio_sample_t* dst, nframes_t cnt,
audio_sample_t* readbuffer )
-{
- int readFrames = file_read( dst, m_rbFileReadPos, cnt, readbuffer);
- m_rbFileReadPos += readFrames;
-
- return readFrames;
-}
-
-
-void MonoReader::rb_seek_to_file_position( nframes_t position )
-{
- Q_ASSERT(m_clip);
-
-// printf("rb_seek_to_file_position:: seeking to %d\n", position);
-
- // calculate position relative to the file!
- long fileposition = position - (m_clip->get_track_start_frame() +
m_clip->get_source_start_frame());
-
- if (m_rbFileReadPos == fileposition) {
-// printf("ringbuffer allready at position %d\n", position);
- return;
- }
-
- // check if the clip's start position is within the range
- // if not, fill the buffer from the earliest point this clip
- // will come into play.
- if (fileposition < 0) {
-// printf("not seeking to %ld, but too %d\n\n",
fileposition,m_clip->get_source_start_frame());
- // Song's start from 0, this makes a period start from
- // 0 - 1023 for example, the nframes is 1024!
- // Setting a songs new position is on 1024, and NOT
- // 1023.. Hmm, something isn't correct here, but at least
substract 1
- // to make this thing work!
- fileposition = m_clip->get_source_start_frame() - 1;
- }
-
-// printf("rb_seek_to_file_position:: seeking to relative pos: %d\n",
fileposition);
- m_buffer->reset();
- m_rbFileReadPos = fileposition;
- m_rbRelativeFileReadPos = fileposition;
-}
-
-void MonoReader::process_ringbuffer( audio_sample_t * framebuffer,
audio_sample_t* readbuffer, bool seeking)
-{
- // Do nothing if we passed the lenght of the AudioFile.
- if (m_rbFileReadPos >= m_length) {
-// printf("returning, m_rbFileReadPos > m_length! (%d > %d)\n",
m_rbFileReadPos, m_source->m_length);
- if (m_syncInProgress) {
- finish_resync();
- }
- return;
- }
-
- // Calculate the number of samples we can write into the buffer
- int writeSpace = m_buffer->write_space();
-
- // The amount of chunks which can be 'read'
- int chunkCount = (int)(writeSpace / m_chunkSize);
-
- int toRead = m_chunkSize;
-
- if (seeking) {
- toRead = writeSpace;
-// printf("doing a full seek buffer fill\n");
- } else if (m_syncInProgress) {
- // Currently, we fill the buffer completely.
- // For some reason, filling it with 1/4 at a time
- // doesn't fill it consitently, and thus giving audible
artifacts.
-/* toRead = m_chunkSize * 2;*/
- toRead = writeSpace;
- } else if (chunkCount == 0) {
- // If we are nearing the end of the source file it could be
possible
- // we only need to read the last samples which is smaller in
size then
- // chunksize. If so, set toRead to m_source->m_length -
rbFileReasPos
- if ( (int) (m_source->m_length - m_rbFileReadPos) <=
m_chunkSize) {
- toRead = m_source->m_length - m_rbFileReadPos;
- } else {
- printf("MonoReader:: chunkCount == 0, but not at end of
file, this shouldn't happen!!\n");
- return;
- }
- }
-
- // Read in the samples from source
- nframes_t toWrite = rb_file_read(framebuffer, toRead, readbuffer);
-
- // and write it to the ringbuffer
- m_buffer->write(framebuffer, toWrite);
-
-}
-
-void MonoReader::recover_from_buffer_underrun(nframes_t position)
-{
-// printf("buffer underrun detected!\n");
- m_bufferUnderRunDetected = 1;
- start_resync(position);
-}
-
-void MonoReader::start_resync( nframes_t position )
-{
-// printf("starting resync!\n");
- m_syncPos = position;
- m_rbReady = 0;
- m_needSync = 1;
-}
-
-void MonoReader::finish_resync()
-{
-// printf("sync finished\n");
- m_needSync = 0;
- m_bufferUnderRunDetected = 0;
- m_rbReady = 1;
- m_syncInProgress = 0;
-}
-
-void MonoReader::sync(audio_sample_t* framebuffer, audio_sample_t* readbuffer)
-{
- PENTER2;
- if (!m_needSync) {
- return;
- }
-
- if (!m_syncInProgress) {
- rb_seek_to_file_position(m_syncPos);
- m_syncInProgress = 1;
- }
-
- // Currently, we fill the buffer completely.
- // For some reason, filling it with 1/4 at a time
- // doesn't fill it consitently, and thus giving audible artifacts.
- process_ringbuffer(framebuffer, readbuffer);
-
- if (m_buffer->write_space() == 0) {
- finish_resync();
- }
-
-// PWARN("Resyncing ringbuffer finished");
-}
-
-
-void MonoReader::set_audio_clip( AudioClip * clip )
-{
- m_clip = clip;
-}
-
-Peak* MonoReader::get_peak( )
-{
- return m_peak;
-}
-
-void MonoReader::prepare_buffer( )
-{
- PENTER;
-
- Q_ASSERT(m_clip);
-
- float size = config().get_property("Hardware", "readbuffersize",
1.0).toDouble();
-
- m_bufferSize = (int) (size * audiodevice().get_sample_rate());
-
- m_chunkSize = m_bufferSize / DiskIO::bufferdividefactor;
-
- m_buffer = new RingBufferNPT<float>(m_bufferSize);
-
- start_resync(m_clip->get_song()->get_working_frame());
-}
-
-BufferStatus* MonoReader::get_buffer_status()
-{
- int freespace = m_buffer->write_space();
-
- if (m_rbFileReadPos >= m_length) {
- m_bufferstatus->fillStatus = 100;
- freespace = 0;
- } else {
- m_bufferstatus->fillStatus = (int) (((float)freespace /
m_bufferSize) * 100);
- }
-
- m_bufferstatus->bufferUnderRun = m_bufferUnderRunDetected;
- m_bufferstatus->needSync = m_needSync;
-
- m_bufferstatus->priority = (int) (freespace / m_chunkSize);
-
- return m_bufferstatus;
-}
-
-void MonoReader::set_active(bool active)
-{
- if (m_active == active)
- return;
-
- if (active) {
- m_active = 1;
-// m_wasActivated = 1;
-// printf("setting private readsource %s to active\n",
QS_C(m_fileName));
- } else {
-// printf("setting private readsource %s to IN-active\n",
QS_C(m_fileName));
- m_active = 0;
- }
-}
-
-
-//eof
Index: core/MonoReader.h
===================================================================
RCS file: core/MonoReader.h
diff -N core/MonoReader.h
--- core/MonoReader.h 15 Jul 2007 05:11:10 -0000 1.7
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,105 +0,0 @@
-/*
-Copyright (C) 2006-2007 Remon Sijrier
-
-This file is part of Traverso
-
-Traverso 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
-*/
-
-#ifndef MONO_READER_H
-#define MONO_READER_H
-
-#include "AudioSource.h"
-#include "RingBufferNPT.h"
-#include "defines.h"
-
-
-class AudioClip;
-class AbstractAudioReader;
-class Peak;
-class ReadSource;
-class QString;
-struct BufferStatus;
-
-class MonoReader : public AudioSource
-{
-public :
- int rb_read(audio_sample_t* dst, nframes_t start, nframes_t cnt);
- int rb_file_read(audio_sample_t* dst, nframes_t cnt, audio_sample_t*
readbuffer);
- void rb_seek_to_file_position(nframes_t position);
-
- void process_ringbuffer(audio_sample_t* framebuffer, audio_sample_t*
readbuffer, bool seeking=false);
- BufferStatus* get_buffer_status();
-
- int file_read(audio_sample_t* dst, nframes_t start, nframes_t cnt,
audio_sample_t* readbuffer) const;
-
- int init(bool forPeaks);
- int ref();
-
- void sync(audio_sample_t* framebuffer, audio_sample_t* readbuffer);
- void set_audio_clip(AudioClip* clip);
- void prepare_buffer();
-
- Peak* get_peak();
- size_t is_active() const;
-
-private:
- MonoReader(ReadSource* source, int sourceChannelCount, int
channelNumber, const QString& fileName);
- ~MonoReader();
-
- ReadSource* m_source;
- RingBufferNPT<float>* m_buffer;
- Peak* m_peak;
- AbstractAudioReader* m_audioReader;
- int m_sourceChannelCount;
- int m_channelNumber;
- uint m_length;
- uint m_bufferSize;
- int m_chunkSize;
-
- nframes_t m_rbFileReadPos;
- nframes_t m_rbRelativeFileReadPos;
- volatile size_t m_syncPos;
- volatile size_t m_rbReady;
- volatile size_t m_needSync;
- volatile size_t m_active;
- volatile size_t m_wasActivated;
- volatile size_t m_bufferUnderRunDetected;
- bool m_syncInProgress;
- int m_prio;
-
- AudioClip* m_clip;
- BufferStatus* m_bufferstatus;
- QString m_fileName;
-
-
- void start_resync(nframes_t position);
- void finish_resync();
- void set_active(bool active);
-
- void recover_from_buffer_underrun(nframes_t position);
-
- friend class ReadSource;
-
-};
-
-inline size_t MonoReader::is_active() const
-{
- return m_active;
-}
-
-
-#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Traverso-commit] traverso/src commands/AudioClipExternalProcessi...,
Remon Sijrier <=