[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src audiofileio/encode/WPAudioWriter.c...
From: |
Remon Sijrier |
Subject: |
[Traverso-commit] traverso/src audiofileio/encode/WPAudioWriter.c... |
Date: |
Wed, 15 Aug 2007 20:07:42 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Remon Sijrier <r_sijrier> 07/08/15 20:07:42
Modified files:
src/audiofileio/encode: WPAudioWriter.cpp WPAudioWriter.h
src/core : AudioClip.cpp AudioClip.h AudioSource.h
DiskIO.cpp Peak.cpp ReadSource.h
WriteSource.cpp WriteSource.h
Log message:
* finished conversion to interleaved audio recording
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/WPAudioWriter.cpp?cvsroot=traverso&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/WPAudioWriter.h?cvsroot=traverso&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.cpp?cvsroot=traverso&r1=1.120&r2=1.121
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioClip.h?cvsroot=traverso&r1=1.56&r2=1.57
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/AudioSource.h?cvsroot=traverso&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/DiskIO.cpp?cvsroot=traverso&r1=1.42&r2=1.43
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/Peak.cpp?cvsroot=traverso&r1=1.40&r2=1.41
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/ReadSource.h?cvsroot=traverso&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/WriteSource.cpp?cvsroot=traverso&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/traverso/src/core/WriteSource.h?cvsroot=traverso&r1=1.17&r2=1.18
Patches:
Index: audiofileio/encode/WPAudioWriter.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/audiofileio/encode/WPAudioWriter.cpp,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- audiofileio/encode/WPAudioWriter.cpp 15 Aug 2007 00:18:50 -0000
1.9
+++ audiofileio/encode/WPAudioWriter.cpp 15 Aug 2007 20:07:41 -0000
1.10
@@ -36,7 +36,7 @@
m_firstBlockSize = 0;
m_tmp_buffer = 0;
m_tmpBufferSize = 0;
- m_qualityFlags = 0;
+ m_configFlags = 0;
}
@@ -60,20 +60,20 @@
{
if (key == "quality") {
// Clear quality before or-ing in the new quality value
- m_qualityFlags &= ~(CONFIG_FAST_FLAG | CONFIG_HIGH_FLAG |
CONFIG_VERY_HIGH_FLAG);
+ m_configFlags &= ~(CONFIG_FAST_FLAG | CONFIG_HIGH_FLAG |
CONFIG_VERY_HIGH_FLAG);
if (value == "fast") {
- m_qualityFlags |= CONFIG_FAST_FLAG;
+ m_configFlags |= CONFIG_FAST_FLAG;
return true;
}
else if (value == "high") {
// CONFIG_HIGH_FLAG (default) ~ 1.5 times slower then
FAST, ~ 20% extra compression then FAST
- m_qualityFlags |= CONFIG_HIGH_FLAG;
+ m_configFlags |= CONFIG_HIGH_FLAG;
return true;
}
else if (value == "very_high") {
// CONFIG_VERY_HIGH_FLAG ~ 2 times slower then FAST, ~
25 % extra compression then FAST
- m_qualityFlags |= CONFIG_VERY_HIGH_FLAG;
+ m_configFlags |= CONFIG_VERY_HIGH_FLAG;
return true;
}
}
@@ -84,11 +84,11 @@
// information that has virtually no effect on the
audio data. While this does technically make the compression
// lossy, it retains all the advantages of floating
point data (>600 dB of dynamic range, no clipping, and 25 bits
// of resolution). This also affects large integer
compression by limiting the resolution to 24 bits.
- m_qualityFlags |= CONFIG_SKIP_WVX;
+ m_configFlags |= CONFIG_SKIP_WVX;
return true;
}
else if (value == "false") {
- m_qualityFlags &= ~CONFIG_SKIP_WVX;
+ m_configFlags &= ~CONFIG_SKIP_WVX;
return true;
}
}
@@ -118,7 +118,7 @@
m_config.channel_mask = (m_channels == 2) ? 3 : 4; // Microsoft
standard (mono = 4, stereo = 3)
m_config.num_channels = m_channels;
m_config.sample_rate = m_rate;
- m_config.flags = m_qualityFlags;
+ m_config.flags = m_configFlags;
WavpackSetConfiguration(m_wp, &m_config, -1);
Index: audiofileio/encode/WPAudioWriter.h
===================================================================
RCS file: /sources/traverso/traverso/src/audiofileio/encode/WPAudioWriter.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- audiofileio/encode/WPAudioWriter.h 15 Aug 2007 00:18:50 -0000 1.6
+++ audiofileio/encode/WPAudioWriter.h 15 Aug 2007 20:07:41 -0000 1.7
@@ -54,7 +54,7 @@
FILE* m_file;
char* m_firstBlock;
int32_t m_firstBlockSize;
- int m_qualityFlags;
+ int m_configFlags;
int32_t* m_tmp_buffer;
nframes_t m_tmpBufferSize;
};
Index: core/AudioClip.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.cpp,v
retrieving revision 1.120
retrieving revision 1.121
diff -u -b -r1.120 -r1.121
--- core/AudioClip.cpp 15 Aug 2007 00:18:51 -0000 1.120
+++ core/AudioClip.cpp 15 Aug 2007 20:07:41 -0000 1.121
@@ -115,7 +115,7 @@
m_track = 0;
m_readSource = 0;
m_recordingStatus = NO_RECORDING;
- m_isSelected = m_invalidReadSource = false;
+ m_isSelected = m_isReadSourceValid = false;
m_isLocked = config().get_property("AudioClip", "LockByDefault",
false).toBool();
fadeIn = 0;
fadeOut = 0;
@@ -395,11 +395,11 @@
Q_ASSERT(m_song);
if (m_recordingStatus == RECORDING) {
-// process_capture(nframes, channel);
+ process_capture(nframes);
return 0;
}
- if (m_invalidReadSource) {
+ if (m_isReadSourceValid) {
return -1;
}
@@ -478,37 +478,32 @@
//
// Function called in RealTime AudioThread processing path
//
-void AudioClip::process_capture( nframes_t nframes, uint channel )
+void AudioClip::process_capture(nframes_t nframes)
{
- if (channel == 0) {
- if ( ! m_track->capture_left_channel() ) {
- return;
- }
- }
-
- if (channel == 1) {
- if ( ! m_track->capture_right_channel()) {
- return;
- }
- }
-
if (!m_captureBus) {
return;
}
- m_length += (nframes / writeSources.size());
+ m_length += nframes;
+ nframes_t written = 0;
- int index = 0;
if (m_track->capture_left_channel() &&
m_track->capture_right_channel()) {
- index = channel;
+ audio_sample_t* buffer[2];
+ buffer[0] = m_captureBus->get_buffer(0, nframes);
+ buffer[1] = m_captureBus->get_buffer(1, nframes);
+ written = m_recorder->rb_write(buffer, nframes);
+ } else if (m_track->capture_left_channel()) {
+ audio_sample_t* buffer[1];
+ buffer[0] = m_captureBus->get_buffer(0, nframes);
+ written = m_recorder->rb_write(buffer, nframes);
+ } else if (m_track->capture_right_channel()) {
+ audio_sample_t* buffer[1];
+ buffer[0] = m_captureBus->get_buffer(1, nframes);
+ written = m_recorder->rb_write(buffer, nframes);
}
- WriteSource* source = writeSources.at(index);
-
- nframes_t written = source->rb_write(m_captureBus->get_buffer(channel,
nframes), nframes);
-
if (written != nframes) {
- printf("couldn't write nframes %d to recording buffer, only
%d\n", nframes, written);
+ printf("couldn't write nframes %d to recording buffer for
channel 0, only %d\n", nframes, written);
}
}
@@ -527,9 +522,14 @@
return -1;
}
- int channelnumber = 0;
- int channelcount = m_captureBus->get_channel_count();
- if (! (m_track->capture_left_channel() &&
m_track->capture_right_channel()) ) {
+ sourceStartFrame = 0;
+ m_isTake = 1;
+ m_recordingStatus = RECORDING;
+ int channelcount;
+
+ if (m_track->capture_left_channel() &&
m_track->capture_right_channel()) {
+ channelcount = 2;
+ } else {
channelcount = 1;
}
@@ -538,32 +538,17 @@
m_name, channelcount, m_song->get_id());
resources_manager()->set_source_for_clip(this, rs);
- QString sourceid = QString::number(rs->get_id());
- for (int chan=0; chan<m_captureBus->get_channel_count(); chan++) {
- if (chan == 0) {
- if ( ! m_track->capture_left_channel() ) {
- continue;
- }
- }
-
- if (chan == 1) {
- if ( ! m_track->capture_right_channel()) {
- continue;
- }
- }
-
- if (m_track->capture_left_channel() &&
m_track->capture_right_channel()) {
- channelnumber = chan;
- }
+ QString sourceid = QString::number(rs->get_id());
ExportSpecification* spec = new ExportSpecification;
spec->exportdir = pm().get_project()->get_root_dir() +
"/audiosources/";
- spec->writerType = "sndfile";
- spec->extraFormat["filetype"] = "wav";
+ spec->writerType = "wavpack";
+ spec->extraFormat["quality"] = "fast";
+// spec->extraFormat["skip_wvx"] = "true";
spec->data_width = 1; // 1 means float
- spec->channels = 1;
+ spec->channels = channelcount;
spec->sample_rate = audiodevice().get_sample_rate();
spec->src_quality = SRC_SINC_MEDIUM_QUALITY;
spec->isRecording = true;
@@ -572,22 +557,15 @@
spec->total_frames = 0;
spec->blocksize = audiodevice().get_buffer_size();
spec->name = m_name + "-" + sourceid;
- spec->dataF = m_captureBus->get_buffer( chan,
audiodevice().get_buffer_size());
+ spec->dataF = m_captureBus->get_buffer(0,
audiodevice().get_buffer_size());
- WriteSource* ws = new WriteSource(spec, channelnumber,
channelcount);
- ws->set_process_peaks( true );
- ws->set_recording( true );
+ m_recorder = new WriteSource(spec);
+ m_recorder->set_process_peaks( true );
+ m_recorder->set_recording( true );
- connect(ws, SIGNAL(exportFinished(WriteSource*)), this,
SLOT(finish_write_source(WriteSource*)));
-
- writeSources.insert(channelnumber, ws);
- m_song->get_diskio()->register_write_source( ws );
- }
-
- sourceStartFrame = 0;
- m_isTake = 1;
- m_recordingStatus = RECORDING;
+ m_song->get_diskio()->register_write_source(m_recorder);
+ connect(m_recorder, SIGNAL(exportFinished()), this,
SLOT(finish_write_source()));
connect(m_song, SIGNAL(transferStopped()), this,
SLOT(finish_recording()));
connect(&audiodevice(), SIGNAL(driverParamsChanged()), this,
SLOT(get_capture_bus()));
@@ -655,14 +633,14 @@
PENTER;
if (!rs) {
- m_invalidReadSource = true;
+ m_isReadSourceValid = true;
return;
}
if (rs->get_error() < 0) {
- m_invalidReadSource = true;
+ m_isReadSourceValid = true;
} else {
- m_invalidReadSource = false;
+ m_isReadSourceValid = false;
}
m_readSource = rs;
@@ -684,6 +662,9 @@
rs->set_audio_clip(this);
+
+ if (m_recordingStatus == NO_RECORDING) {
+
foreach(Peak* peak, m_peaks) {
peak->close();
}
@@ -693,40 +674,33 @@
for (uint chan=0; chan<m_readSource->get_channel_count(); ++chan) {
m_peaks.append(new Peak(rs, chan));
}
+ }
emit stateChanged();
}
-void AudioClip::finish_write_source( WriteSource * ws )
+void AudioClip::finish_write_source()
{
PENTER;
- if (writeSources.contains(ws)) {
- writeSources.removeAll(ws);
- if (ws->m_peak->finish_processing() < 0) {
- PERROR("write source peak::finish_processing()
failed!");
- }
- delete ws;
- } else {
- qFatal("AudioClip: finished writesource not in writesources
list !!");
- }
-
-
- if (writeSources.isEmpty()) {
Q_ASSERT(m_readSource);
- if (m_readSource->set_file(m_readSource->get_filename()) < 0) {
+ if (m_readSource->set_file(m_recorder->get_filename()) < 0) {
PERROR("Setting file for ReadSource failed after
finishing recording");
- }
-
+ } else {
m_song->get_diskio()->register_read_source(m_readSource);
// re-inits the lenght from the audiofile due calling
rsm->set_source_for_clip()
m_length = 0;
- resources_manager()->set_source_for_clip(this, m_readSource);
+ }
+
+ delete m_recorder;
+ m_recorder = 0;
+
m_recordingStatus = NO_RECORDING;
+ resources_manager()->set_source_for_clip(this, m_readSource);
+
emit recordingFinished();
- }
}
void AudioClip::finish_recording()
@@ -734,10 +708,7 @@
PENTER;
m_recordingStatus = FINISHING_RECORDING;
-
- foreach(WriteSource* ws, writeSources) {
- ws->set_recording(false);
- }
+ m_recorder->set_recording(false);
disconnect(m_song, SIGNAL(transferStopped()), this,
SLOT(finish_recording()));
disconnect(&audiodevice(), SIGNAL(driverParamsChanged()), this,
SLOT(get_capture_bus()));
@@ -748,8 +719,8 @@
if (m_readSource) {
return m_readSource->get_channel_count();
} else {
- if (writeSources.size()) {
- return writeSources.size();
+ if (m_recorder) {
+ return m_recorder->get_channel_count();
}
}
@@ -771,7 +742,7 @@
void AudioClip::set_song( Song * song )
{
m_song = song;
- if (m_readSource) {
+ if (m_readSource && !m_isReadSourceValid) {
m_song->get_diskio()->register_read_source( m_readSource );
} else {
PWARN("AudioClip::set_song() : Setting Song, but no ReadSource
available!!");
Index: core/AudioClip.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioClip.h,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -b -r1.56 -r1.57
--- core/AudioClip.h 18 Jul 2007 13:13:05 -0000 1.56
+++ core/AudioClip.h 15 Aug 2007 20:07:41 -0000 1.57
@@ -112,7 +112,7 @@
bool is_selected() const;
bool is_locked() const;
bool has_song() const;
- bool invalid_readsource() const {return m_invalidReadSource;}
+ bool invalid_readsource() const {return m_isReadSourceValid;}
int recording_state() const;
static bool smaller(const AudioClip* left, const AudioClip* right )
@@ -128,7 +128,7 @@
Track* m_track;
Song* m_song;
ReadSource* m_readSource;
- QList<WriteSource* > writeSources;
+ WriteSource* m_recorder;
QList<FadeCurve* > m_fades;
QList<Peak* > m_peaks;
AudioBus* m_captureBus;
@@ -151,7 +151,7 @@
bool m_isTake;
bool m_isMuted;
bool m_isLocked;
- bool m_invalidReadSource;
+ bool m_isReadSourceValid;
RecordingStatus m_recordingStatus;
qint64 m_readSourceId;
@@ -164,7 +164,7 @@
void set_source_start_frame(nframes_t frame);
void set_track_end_frame(nframes_t endFrame);
void set_sources_active_state();
- void process_capture(nframes_t nframes, uint channel);
+ void process_capture(nframes_t nframes);
void calculate_normalization_factor(float targetdB = 0.0);
@@ -183,7 +183,7 @@
public slots:
void finish_recording();
- void finish_write_source(WriteSource* source);
+ void finish_write_source();
void set_left_edge(long frame);
void set_right_edge(long frame);
void track_audible_state_changed();
Index: core/AudioSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/AudioSource.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- core/AudioSource.h 14 Aug 2007 10:49:55 -0000 1.22
+++ core/AudioSource.h 15 Aug 2007 20:07:41 -0000 1.23
@@ -27,6 +27,9 @@
#include <QObject>
#include <QDomDocument>
+#include "RingBufferNPT.h"
+
+
class QString;
/// The base class for AudioSources like ReadSource and WriteSource
@@ -57,6 +60,11 @@
int get_bit_depth() const;
protected:
+ QList<RingBufferNPT<audio_sample_t>*> m_buffers;
+
+ uint m_bufferSize;
+ uint m_chunkSize;
+
int m_channelCount;
qint64 m_origSongId;
QString m_dir;
Index: core/DiskIO.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/DiskIO.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -b -r1.42 -r1.43
--- core/DiskIO.cpp 14 Aug 2007 10:49:55 -0000 1.42
+++ core/DiskIO.cpp 15 Aug 2007 20:07:41 -0000 1.43
@@ -152,8 +152,7 @@
// TODO This is a LARGE buffer, any ideas how to make it smaller ??
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];
+
m_decodebuffer = new DecodeBuffer;
m_decodebuffer->destination = framebuffer;
m_decodebuffer->readBufferSize = 0;
@@ -174,7 +173,6 @@
delete cpuTimeBuffer;
delete [] framebuffer[0];
delete [] framebuffer[1];
- delete [] m_readbuffer;
delete m_decodebuffer;
}
Index: core/Peak.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/Peak.cpp,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- core/Peak.cpp 14 Aug 2007 10:49:55 -0000 1.40
+++ core/Peak.cpp 15 Aug 2007 20:07:42 -0000 1.41
@@ -57,17 +57,16 @@
PENTERCONS;
ReadSource* rs = qobject_cast<ReadSource*>(source);
+
if (rs) {
m_source = resources_manager()->get_readsource(rs->get_id());
- }
-
- if (source->get_channel_count() > 1) {
- PMESG("Peak channel count is %d", source->get_channel_count());
- m_fileName = pm().get_project()->get_root_dir() + "/peakfiles/"
+ source->get_name() + "-ch" + QByteArray::number(m_channel) + ".peak";
} else {
- m_fileName = pm().get_project()->get_root_dir() + "/peakfiles/"
+ source->get_name() + ".peak";
+ m_source = 0;
}
+ m_fileName = source->get_filename() + "-ch" +
QByteArray::number(m_channel) + ".peak";
+ m_fileName = m_fileName.replace(QRegExp("audiosources"), "peakfiles");
+
peaksAvailable = permanentFailure = interuptPeakBuild = false;
m_file = m_normFile = 0;
}
@@ -104,7 +103,7 @@
m_file = fopen(m_fileName.toUtf8().data(),"rb");
if (! m_file) {
- //PERROR("Couldn't open peak file for reading! (%s)",
m_fileName.toAscii().data());
+ PERROR("Couldn't open peak file for reading! (%s)",
m_fileName.toAscii().data());
return -1;
}
@@ -706,10 +705,20 @@
float f = (float) endframe / NORMALIZE_CHUNK_SIZE;
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 = 0;//m_source->file_read(m_channel, buf, endframe - toRead,
toRead, readbuffer);
- maxamp = Mixer::compute_peak(buf, read, maxamp);
+
+ 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[toRead];
+ }
+ DecodeBuffer decodebuffer(buffer, readbuffer, toRead, toRead*2);
+
+ int read = m_source->file_read(&decodebuffer, endframe - toRead,
toRead);
+
+ maxamp = Mixer::compute_peak(buffer[m_channel], read, maxamp);
+
+ for (uint chan=0; chan<m_source->get_channel_count(); ++chan) {
+ delete [] buffer[chan];
+ }
// Now that we have covered both boundary situations,
// read in the cached normvalues, and calculate the highest value!
Index: core/ReadSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/ReadSource.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- core/ReadSource.h 14 Aug 2007 10:49:55 -0000 1.32
+++ core/ReadSource.h 15 Aug 2007 20:07:42 -0000 1.33
@@ -23,8 +23,6 @@
#define READSOURCE_H
#include "AudioSource.h"
-#include "RingBufferNPT.h"
-#include "defines.h"
class AbstractAudioReader;
class AudioClip;
@@ -73,14 +71,11 @@
void output_rate_changed();
private:
- QList<RingBufferNPT<float>*> m_buffers;
AbstractAudioReader* m_audioReader;
AudioClip* m_clip;
int m_refcount;
int m_error;
bool m_silent;
- uint m_bufferSize;
- int m_chunkSize;
nframes_t m_rbFileReadPos;
nframes_t m_rbRelativeFileReadPos;
volatile size_t m_syncPos;
Index: core/WriteSource.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/core/WriteSource.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- core/WriteSource.cpp 15 Aug 2007 00:18:51 -0000 1.32
+++ core/WriteSource.cpp 15 Aug 2007 20:07:42 -0000 1.33
@@ -36,37 +36,24 @@
#include "Debugger.h"
-WriteSource::WriteSource( ExportSpecification * specification )
+WriteSource::WriteSource( ExportSpecification* specification )
: AudioSource(specification->exportdir, specification->name)
, m_spec(specification)
{
- diskio = 0;
- m_buffer = 0;
+ m_diskio = 0;
m_writer = 0;
prepare_export();
}
-WriteSource::WriteSource( ExportSpecification * specification, int
channelNumber, int superChannelCount )
- : AudioSource(specification->exportdir, specification->name)
- , m_spec(specification)
- , m_channelNumber(channelNumber)
-{
- diskio = 0;
- m_buffer = 0;
- m_writer = 0;
- m_channelCount = superChannelCount;
- prepare_export();
-}
-
WriteSource::~WriteSource()
{
PENTERDES;
- if (m_peak) {
- delete m_peak;
+ foreach(Peak* peak, m_peaks) {
+ delete peak;
}
- if (m_buffer) {
- delete m_buffer;
+ for(int i=0; i<m_buffers.size(); ++i) {
+ delete m_buffers.at(i);
}
if (m_spec->isRecording) {
@@ -80,7 +67,7 @@
int WriteSource::process (nframes_t nframes)
{
float* float_buffer = 0;
- uint32_t chn;
+ int chn;
uint32_t x;
uint32_t i;
nframes_t written;
@@ -95,96 +82,96 @@
/* now do sample rate conversion */
- if (sample_rate != (uint)m_spec->sample_rate) {
+ if (m_sampleRate != (uint)m_spec->sample_rate) {
int err;
- src_data.output_frames = out_samples_max / channels;
- src_data.end_of_input = ((m_spec->pos + nframes) >=
m_spec->end_frame);
- src_data.data_out = dataF2;
+ m_src_data.output_frames = m_out_samples_max /
m_channelCount;
+ m_src_data.end_of_input = ((m_spec->pos + nframes) >=
m_spec->end_frame);
+ m_src_data.data_out = m_dataF2;
- if (leftover_frames > 0) {
+ if (m_leftover_frames > 0) {
- /* input data will be in leftoverF rather than
dataF */
+ /* input data will be in m_leftoverF rather
than dataF */
- src_data.data_in = leftoverF;
+ m_src_data.data_in = m_leftoverF;
if (cnt == 0) {
- /* first time, append new data from
dataF into the leftoverF buffer */
+ /* first time, append new data from
dataF into the m_leftoverF buffer */
- memcpy (leftoverF + (leftover_frames *
channels), m_spec->dataF, nframes * channels * sizeof(float));
- src_data.input_frames = nframes +
leftover_frames;
+ memcpy (m_leftoverF +
(m_leftover_frames * m_channelCount), m_spec->dataF, nframes * m_channelCount *
sizeof(float));
+ m_src_data.input_frames = nframes +
m_leftover_frames;
} else {
- /* otherwise, just use whatever is
still left in leftoverF; the contents
+ /* otherwise, just use whatever is
still left in m_leftoverF; the contents
were adjusted using memmove() right
after the last SRC call (see
below)
*/
- src_data.input_frames = leftover_frames;
+ m_src_data.input_frames =
m_leftover_frames;
}
} else {
- src_data.data_in = m_spec->dataF;
- src_data.input_frames = nframes;
+ m_src_data.data_in = m_spec->dataF;
+ m_src_data.input_frames = nframes;
}
++cnt;
- if ((err = src_process (src_state, &src_data)) != 0) {
+ if ((err = src_process (m_src_state, &m_src_data)) !=
0) {
PWARN(("an error occured during sample rate
conversion: %s"), src_strerror (err));
return -1;
}
- to_write = src_data.output_frames_gen;
- leftover_frames = src_data.input_frames -
src_data.input_frames_used;
+ to_write = m_src_data.output_frames_gen;
+ m_leftover_frames = m_src_data.input_frames -
m_src_data.input_frames_used;
- if (leftover_frames > 0) {
- if (leftover_frames > max_leftover_frames) {
+ if (m_leftover_frames > 0) {
+ if (m_leftover_frames > m_max_leftover_frames) {
PWARN("warning, leftover frames
overflowed, glitches might occur in output");
- leftover_frames = max_leftover_frames;
+ m_leftover_frames =
m_max_leftover_frames;
}
- memmove (leftoverF, (char *) (src_data.data_in
+ (src_data.input_frames_used * channels)),
- leftover_frames * channels *
sizeof(float));
+ memmove (m_leftoverF, (char *)
(m_src_data.data_in + (m_src_data.input_frames_used * m_channelCount)),
+ m_leftover_frames * m_channelCount *
sizeof(float));
}
- float_buffer = dataF2;
+ float_buffer = m_dataF2;
} else {
/* no SRC, keep it simple */
to_write = nframes;
- leftover_frames = 0;
+ m_leftover_frames = 0;
float_buffer = m_spec->dataF;
}
- if (output_data) {
- memset (output_data, 0, sample_bytes * to_write *
channels);
+ if (m_output_data) {
+ memset (m_output_data, 0, m_sample_bytes * to_write *
m_channelCount);
}
switch (m_spec->data_width) {
case 8:
case 16:
case 24:
- for (chn = 0; chn < channels; ++chn) {
- gdither_runf (dither, chn, to_write,
float_buffer, output_data);
+ for (chn = 0; chn < m_channelCount; ++chn) {
+ gdither_runf (m_dither, chn, to_write,
float_buffer, m_output_data);
}
/* and export to disk */
- written = m_writer->write(output_data, to_write);
+ written = m_writer->write(m_output_data, to_write);
break;
case 32:
- for (chn = 0; chn < channels; ++chn) {
+ for (chn = 0; chn < m_channelCount; ++chn) {
- int *ob = (int *) output_data;
+ int *ob = (int *) m_output_data;
const double int_max = (float) INT_MAX;
const double int_min = (float) INT_MIN;
for (x = 0; x < to_write; ++x) {
- i = chn + (x * channels);
+ i = chn + (x * m_channelCount);
if (float_buffer[i] > 1.0f) {
ob[i] = INT_MAX;
@@ -200,15 +187,11 @@
}
}
/* and export to disk */
- written = m_writer->write(output_data, to_write);
+ written = m_writer->write(m_output_data, to_write);
break;
default:
- if (processPeaks) {
- m_peak->process( float_buffer, to_write );
- }
-
- for (x = 0; x < to_write * channels; ++x) {
+ for (x = 0; x < to_write * m_channelCount; ++x) {
if (float_buffer[x] > 1.0f) {
float_buffer[x] = 1.0f;
} else if (float_buffer[x] < -1.0f) {
@@ -220,7 +203,7 @@
break;
}
- } while (leftover_frames >= nframes);
+ } while (m_leftover_frames >= nframes);
return 0;
}
@@ -233,15 +216,14 @@
GDitherSize dither_size;
- sample_rate = audiodevice().get_sample_rate();
- channels = m_spec->channels;
- processPeaks = false;
- m_peak = 0;
- diskio = 0;
- dataF2 = leftoverF = 0;
- dither = 0;
- output_data = 0;
- src_state = 0;
+ m_sampleRate = audiodevice().get_sample_rate();
+ m_channelCount = m_spec->channels;
+ m_processPeaks = false;
+ m_diskio = 0;
+ m_dataF2 = m_leftoverF = 0;
+ m_dither = 0;
+ m_output_data = 0;
+ m_src_state = 0;
switch (m_spec->data_width) {
@@ -269,7 +251,7 @@
m_writer = AbstractAudioWriter::create_audio_writer(m_spec->writerType);
m_writer->set_rate(m_spec->sample_rate);
m_writer->set_bits_per_sample(m_spec->data_width);
- m_writer->set_num_channels(m_spec->channels);
+ m_writer->set_num_channels(m_channelCount);
QString key;
foreach (key, m_spec->extraFormat.keys()) {
@@ -280,61 +262,57 @@
/* XXX make sure we have enough disk space for the output */
- QString name = m_fileName;
- if (m_spec->isRecording) {
- name.append("-ch" + QByteArray::number(m_channelNumber));
- }
- name.append(m_writer->get_extension());
+ m_fileName.append(m_writer->get_extension());
- if (m_writer->open(name) == false) {
+ if (m_writer->open(m_fileName) == false) {
return -1;
}
- if ((uint)m_spec->sample_rate != sample_rate) {
+ if ((uint)m_spec->sample_rate != m_sampleRate) {
qDebug("Doing samplerate conversion");
int err;
- if ((src_state = src_new (m_spec->src_quality, channels, &err))
== 0) {
+ if ((m_src_state = src_new (m_spec->src_quality,
m_channelCount, &err)) == 0) {
PWARN("cannot initialize sample rate conversion: %s",
src_strerror (err));
return -1;
}
- src_data.src_ratio = m_spec->sample_rate / (double) sample_rate;
- out_samples_max = (nframes_t) ceil (m_spec->blocksize *
src_data.src_ratio * channels);
- dataF2 = new audio_sample_t[out_samples_max];
-
- max_leftover_frames = 4 * m_spec->blocksize;
- leftoverF = new audio_sample_t[max_leftover_frames * channels];
- leftover_frames = 0;
+ m_src_data.src_ratio = m_spec->sample_rate / (double)
m_sampleRate;
+ m_out_samples_max = (nframes_t) ceil (m_spec->blocksize *
m_src_data.src_ratio * m_channelCount);
+ m_dataF2 = new audio_sample_t[m_out_samples_max];
+
+ m_max_leftover_frames = 4 * m_spec->blocksize;
+ m_leftoverF = new audio_sample_t[m_max_leftover_frames *
m_channelCount];
+ m_leftover_frames = 0;
} else {
- out_samples_max = m_spec->blocksize * channels;
+ m_out_samples_max = m_spec->blocksize * m_channelCount;
}
- dither = gdither_new (m_spec->dither_type, channels, dither_size,
m_spec->data_width);
+ m_dither = gdither_new (m_spec->dither_type, m_channelCount,
dither_size, m_spec->data_width);
/* allocate buffers where dithering and output will occur */
switch (m_spec->data_width) {
case 8:
- sample_bytes = 1;
+ m_sample_bytes = 1;
break;
case 16:
- sample_bytes = 2;
+ m_sample_bytes = 2;
break;
case 24:
case 32:
- sample_bytes = 4;
+ m_sample_bytes = 4;
break;
default:
- sample_bytes = 0; // float format
+ m_sample_bytes = 0; // float format
break;
}
- if (sample_bytes) {
- output_data = (void*) malloc (sample_bytes * out_samples_max);
+ if (m_sample_bytes) {
+ m_output_data = (void*) malloc (m_sample_bytes *
m_out_samples_max);
}
return 0;
@@ -350,75 +328,119 @@
m_writer = 0;
}
- if (dataF2)
- delete dataF2;
- if (leftoverF)
- delete leftoverF;
+ if (m_dataF2)
+ delete m_dataF2;
+ if (m_leftoverF)
+ delete m_leftoverF;
- if (dither) {
- gdither_free (dither);
- dither = 0;
+ if (m_dither) {
+ gdither_free (m_dither);
+ m_dither = 0;
}
- if (output_data) {
- free (output_data);
- output_data = 0;
+ if (m_output_data) {
+ free (m_output_data);
+ m_output_data = 0;
}
- if (src_state) {
- src_delete (src_state);
- src_state = 0;
+ if (m_src_state) {
+ src_delete (m_src_state);
+ m_src_state = 0;
}
-/* if (processPeaks) {
- m_peak->finish_processing();
- }*/
+ foreach(Peak* peak, m_peaks) {
+ if (peak->finish_processing() < 0) {
+ PERROR("WriteSource::finish_export :
peak->finish_processing() failed!");
+ }
+ }
- if (diskio) {
- diskio->unregister_write_source(this);
+ if (m_diskio) {
+ m_diskio->unregister_write_source(this);
}
printf("WriteSource :: thread id is: %ld\n", QThread::currentThreadId
());
PWARN("WriteSource :: emiting exportFinished");
- emit exportFinished( this );
+ emit exportFinished();
return 1;
}
-int WriteSource::rb_write(audio_sample_t* src, nframes_t cnt )
+int WriteSource::rb_write(audio_sample_t** src, nframes_t cnt)
{
- int written = m_buffer->write(src, cnt);
+ int written = 0;
+
+ for (int chan=m_channelCount-1; chan>=0; --chan) {
+ written = m_buffers.at(chan)->write(src[chan], cnt);
+ }
+
return written;
}
void WriteSource::set_process_peaks( bool process )
{
- processPeaks = process;
- if (!processPeaks) {
+ m_processPeaks = process;
+
+ if (!m_processPeaks) {
return;
}
- Q_ASSERT(!m_peak);
+ Q_ASSERT(m_peaks.isEmpty());
- m_peak = new Peak(this, m_channelNumber);
+ for (int chan=0; chan < m_channelCount; ++chan) {
+ Peak* peak = new Peak(this, chan);
- if (m_peak->prepare_processing() < 0) {
+ if (peak->prepare_processing() < 0) {
PERROR("Cannot process peaks realtime");
- delete m_peak;
- m_peak = 0;
- processPeaks = false;
+ m_processPeaks = false;
+ delete peak;
+
+ return;
+ }
+
+ m_peaks.append(peak);
}
}
-int WriteSource::rb_file_write( nframes_t cnt )
+int WriteSource::rb_file_write(nframes_t cnt)
{
- int read = m_buffer->read(m_spec->dataF, cnt);
+ uint read = 0;
+ int chan;
+
+ audio_sample_t* readbuffer[m_channelCount];
+
+ for (chan=0; chan<m_channelCount; ++chan) {
+
+ readbuffer[chan] = new audio_sample_t[cnt * m_channelCount];
+
+ read = m_buffers.at(chan)->read(readbuffer[chan], cnt);
+
+ if (read != cnt) {
+ printf("WriteSource::rb_file_write() : could only
process %d frames, %d were requested!\n", read, cnt);
+ }
+
+ m_peaks.at(chan)->process(readbuffer[chan], read);
+ }
if (read > 0) {
+ if (m_channelCount == 1) {
+ m_spec->dataF = readbuffer[0];
+ } else {
+ // Interlace data into dataF buffer!
+ for (uint f=0; f<read; f++) {
+ for (chan = 0; chan < m_channelCount; chan++) {
+ m_spec->dataF[f * m_channelCount +
chan] = readbuffer[chan][f];
+ }
+ }
+ }
+
process(read);
}
+ for (chan=0; chan<m_channelCount; ++chan) {
+ delete [] readbuffer[chan];
+ }
+
return read;
}
@@ -430,12 +452,11 @@
void WriteSource::process_ringbuffer(audio_sample_t* buffer)
{
m_spec->dataF = buffer;
- int readSpace = m_buffer->read_space();
+ int readSpace = m_buffers.at(0)->read_space();
if (! m_isRecording ) {
- PWARN("Writing remaining (%d) samples to ringbuffer",
readSpace);
+ PMESG("Writing remaining (%d) samples to ringbuffer",
readSpace);
rb_file_write(readSpace);
- PWARN("WriteSource :: calling source->finish_export()");
finish_export();
return;
}
@@ -445,14 +466,16 @@
void WriteSource::prepare_buffer( )
{
- m_buffersize = sample_rate * DiskIO::writebuffertime;
- m_chunksize = m_buffersize / DiskIO::bufferdividefactor;
- m_buffer = new RingBufferNPT<audio_sample_t>(m_buffersize);
+ m_bufferSize = m_sampleRate * DiskIO::writebuffertime;
+ m_chunkSize = m_bufferSize / DiskIO::bufferdividefactor;
+ for (int i=0; i<m_channelCount; ++i) {
+ m_buffers.append(new
RingBufferNPT<audio_sample_t>(m_bufferSize));
+ }
}
void WriteSource::set_diskio( DiskIO * io )
{
- diskio = io;
+ m_diskio = io;
}
//eof
Index: core/WriteSource.h
===================================================================
RCS file: /sources/traverso/traverso/src/core/WriteSource.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -b -r1.17 -r1.18
--- core/WriteSource.h 14 Aug 2007 10:49:55 -0000 1.17
+++ core/WriteSource.h 15 Aug 2007 20:07:42 -0000 1.18
@@ -23,7 +23,7 @@
#define WRITESOURCE_H
#include "AudioSource.h"
-#include "RingBufferNPT.h"
+
#include "gdither.h"
#include <samplerate.h>
@@ -32,22 +32,21 @@
class DiskIO;
class AbstractAudioWriter;
-/// WriteSource is an AudioSource only used for writing (recording, rendering)
purposes
+/// WriteSource is an AudioSource used for writing (recording, rendering)
purposes
class WriteSource : public AudioSource
{
Q_OBJECT
public :
WriteSource(ExportSpecification* spec);
- WriteSource(ExportSpecification* spec, int channelNumber, int
superChannelCount);
~WriteSource();
- int rb_write(audio_sample_t* src, nframes_t cnt);
+ int rb_write(audio_sample_t** src, nframes_t cnt);
int rb_file_write(nframes_t cnt);
void process_ringbuffer(audio_sample_t* buffer);
int get_processable_buffer_space() const;
- int get_chunck_size() const {return m_chunksize;}
- int get_buffer_size() const {return m_buffersize;}
+ int get_chunck_size() const {return m_chunkSize;}
+ int get_buffer_size() const {return m_bufferSize;}
int process(nframes_t nframes);
@@ -59,43 +58,41 @@
size_t is_recording() const;
void set_diskio(DiskIO* io );
- Peak* m_peak;
private:
- RingBufferNPT<audio_sample_t>* m_buffer;
AbstractAudioWriter* m_writer;
ExportSpecification* m_spec;
+ QList<Peak*> m_peaks;
- DiskIO* diskio;
- GDither dither;
- nframes_t out_samples_max;
- nframes_t sample_rate;
- uint channels;
- uint32_t sample_bytes;
- nframes_t leftover_frames;
- SRC_DATA src_data;
- SRC_STATE* src_state;
- nframes_t max_leftover_frames;
- float* leftoverF;
- float* dataF2;
- void* output_data;
- bool processPeaks;
+ DiskIO* m_diskio;
+ GDither m_dither;
+ bool m_processPeaks;
size_t m_isRecording;
- int m_channelNumber;
- int m_buffersize;
- int m_chunksize;
+ nframes_t m_sampleRate;
+ uint32_t m_sample_bytes;
+
+ // Sample rate conversion variables
+ nframes_t m_out_samples_max;
+ nframes_t m_leftover_frames;
+ SRC_DATA m_src_data;
+ SRC_STATE* m_src_state;
+ nframes_t m_max_leftover_frames;
+ float* m_leftoverF;
+ float* m_dataF2;
+ void* m_output_data;
+
int prepare_export();
signals:
- void exportFinished(WriteSource* );
+ void exportFinished();
};
inline int WriteSource::get_processable_buffer_space( ) const
{
- return m_buffer->read_space();
+ return m_buffers.at(0)->read_space();
}
inline size_t WriteSource::is_recording( ) const
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Traverso-commit] traverso/src audiofileio/encode/WPAudioWriter.c...,
Remon Sijrier <=