[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Traverso-commit] traverso/src audiofileio/audiofileio.pro audiof...
From: |
Ben Levitt |
Subject: |
[Traverso-commit] traverso/src audiofileio/audiofileio.pro audiof... |
Date: |
Sun, 23 Sep 2007 02:58:33 +0000 |
CVSROOT: /sources/traverso
Module name: traverso
Changes by: Ben Levitt <benjie> 07/09/23 02:58:33
Modified files:
src/audiofileio: audiofileio.pro
src/audiofileio/encode: AbstractAudioWriter.cpp
LameAudioWriter.cpp
VorbisAudioWriter.cpp
src/traverso : ExportWidget.cpp
Added files:
src/audiofileio/encode: FlacAudioWriter.cpp FlacAudioWriter.h
Log message:
Add initial FLAC export support using libFLAC.
Remon and anyone else: what FLAC encoding parameters should be exposed
through the ui?
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/audiofileio.pro?cvsroot=traverso&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/AbstractAudioWriter.cpp?cvsroot=traverso&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/LameAudioWriter.cpp?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/VorbisAudioWriter.cpp?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/FlacAudioWriter.cpp?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/audiofileio/encode/FlacAudioWriter.h?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/traverso/ExportWidget.cpp?cvsroot=traverso&r1=1.58&r2=1.59
Patches:
Index: audiofileio/audiofileio.pro
===================================================================
RCS file: /sources/traverso/traverso/src/audiofileio/audiofileio.pro,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- audiofileio/audiofileio.pro 21 Sep 2007 17:01:06 -0000 1.11
+++ audiofileio/audiofileio.pro 23 Sep 2007 02:58:32 -0000 1.12
@@ -20,6 +20,7 @@
encode/AbstractAudioWriter.cpp \
encode/SFAudioWriter.cpp \
encode/WPAudioWriter.cpp \
+ encode/FlacAudioWriter.cpp \
encode/VorbisAudioWriter.cpp \
encode/LameAudioWriter.cpp
@@ -33,6 +34,7 @@
encode/AbstractAudioWriter.h \
encode/SFAudioWriter.h \
encode/WPAudioWriter.h \
+ encode/FlacAudioWriter.h \
encode/VorbisAudioWriter.h \
encode/LameAudioWriter.h
macx{
Index: audiofileio/encode/AbstractAudioWriter.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/audiofileio/encode/AbstractAudioWriter.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- audiofileio/encode/AbstractAudioWriter.cpp 21 Sep 2007 17:01:06 -0000
1.8
+++ audiofileio/encode/AbstractAudioWriter.cpp 23 Sep 2007 02:58:32 -0000
1.9
@@ -24,11 +24,13 @@
#include "WPAudioWriter.h"
#include "LameAudioWriter.h"
#include "VorbisAudioWriter.h"
+#include "FlacAudioWriter.h"
#include <QString>
RELAYTOOL_WAVPACK
RELAYTOOL_MP3LAME
+RELAYTOOL_FLAC
// Always put me below _all_ includes, this is needed
// in case we run with memory leak detection enabled!
@@ -139,9 +141,9 @@
else if (type == "vorbis") {
return new VorbisAudioWriter();
}
- /*else if (type == "flac") {
+ else if (libFLAC_is_present && type == "flac") {
return new FlacAudioWriter();
- }*/
+ }
return 0;
}
Index: audiofileio/encode/LameAudioWriter.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/audiofileio/encode/LameAudioWriter.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- audiofileio/encode/LameAudioWriter.cpp 22 Sep 2007 19:26:20 -0000
1.3
+++ audiofileio/encode/LameAudioWriter.cpp 23 Sep 2007 02:58:32 -0000
1.4
@@ -26,6 +26,8 @@
#include <QString>
+RELAYTOOL_MP3LAME
+
// Always put me below _all_ includes, this is needed
// in case we run with memory leak detection enabled!
#include "Debugger.h"
Index: audiofileio/encode/VorbisAudioWriter.cpp
===================================================================
RCS file:
/sources/traverso/traverso/src/audiofileio/encode/VorbisAudioWriter.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- audiofileio/encode/VorbisAudioWriter.cpp 21 Sep 2007 23:51:41 -0000
1.2
+++ audiofileio/encode/VorbisAudioWriter.cpp 23 Sep 2007 02:58:32 -0000
1.3
@@ -32,6 +32,8 @@
#include <QString>
+RELAYTOOL_VORBISFILE
+
// Always put me below _all_ includes, this is needed
// in case we run with memory leak detection enabled!
#include "Debugger.h"
@@ -262,13 +264,13 @@
// uninterleave samples
if (m_channels == 1) {
- for (int i = 0; i < frameCount; i++) {
+ for (nframes_t i = 0; i < frameCount; i++) {
// FIXME: Currently assumes 16bit audio
writeBuffer[0][i]=( (data[i*4+1]<<8) |
(0x00ff&(int)data[i*4]) ) / 32768.f;
}
}
else {
- for (int i = 0; i < frameCount; i++) {
+ for (nframes_t i = 0; i < frameCount; i++) {
// FIXME: Currently assumes 16bit audio
writeBuffer[0][i]=( (data[i*4+1]<<8) |
(0x00ff&(int)data[i*4]) ) / 32768.f;
writeBuffer[1][i]=( (data[i*4+3]<<8) |
(0x00ff&(int)data[i*4+2]) ) / 32768.f;
Index: traverso/ExportWidget.cpp
===================================================================
RCS file: /sources/traverso/traverso/src/traverso/ExportWidget.cpp,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -b -r1.58 -r1.59
--- traverso/ExportWidget.cpp 22 Sep 2007 19:26:20 -0000 1.58
+++ traverso/ExportWidget.cpp 23 Sep 2007 02:58:33 -0000 1.59
@@ -214,25 +214,28 @@
void ExportWidget::audio_type_changed(int index)
{
- if (audioTypeComboBox->itemData(index).toString() == "mp3") {
+ QString newType = audioTypeComboBox->itemData(index).toString();
+
+ if (newType == "mp3") {
oggOptionsGroupBox->hide();
mp3OptionsGroupBox->show();
-
bitdepthComboBox->setCurrentIndex(bitdepthComboBox->findData(16));
- channelComboBox->setCurrentIndex(channelComboBox->findData(2));
- bitdepthComboBox->setDisabled(true);
- channelComboBox->setDisabled(true);
}
- else if (audioTypeComboBox->itemData(index).toString() == "ogg") {
+ else if (newType == "ogg") {
mp3OptionsGroupBox->hide();
oggOptionsGroupBox->show();
-
bitdepthComboBox->setCurrentIndex(bitdepthComboBox->findData(16));
- channelComboBox->setCurrentIndex(channelComboBox->findData(2));
- bitdepthComboBox->setDisabled(true);
- channelComboBox->setDisabled(true);
}
else {
mp3OptionsGroupBox->hide();
oggOptionsGroupBox->hide();
+ }
+
+ if (newType == "mp3" || newType == "ogg" || newType == "flac") {
+ channelComboBox->setCurrentIndex(channelComboBox->findData(2));
+ channelComboBox->setDisabled(true);
+
bitdepthComboBox->setCurrentIndex(bitdepthComboBox->findData(16));
+ bitdepthComboBox->setDisabled(true);
+ }
+ else {
bitdepthComboBox->setEnabled(true);
channelComboBox->setEnabled(true);
}
@@ -306,8 +309,13 @@
m_exportSpec->extraFormat["filetype"] = "aiff";
}
else if (audioType == "flac") {
- m_exportSpec->writerType = "sndfile";
- m_exportSpec->extraFormat["filetype"] = "flac";
+ m_exportSpec->writerType = "flac";
+ if
(bitdepthComboBox->itemData(channelComboBox->currentIndex()).toInt() == 1) {
+ // Change from float to int32
+ // FIXME: Need to do this _Before_ the user starts
encoding
+ // (i.e. disable the float option when flac is selected)
+
bitdepthComboBox->setCurrentIndex(bitdepthComboBox->findData(32));
+ }
}
else if (audioType == "wavpack") {
m_exportSpec->writerType = "wavpack";
@@ -333,7 +341,7 @@
}
}
- m_exportSpec->data_width =
bitdepthComboBox->itemData(channelComboBox->currentIndex()).toInt();
+ m_exportSpec->data_width =
bitdepthComboBox->itemData(bitdepthComboBox->currentIndex()).toInt();
m_exportSpec->channels =
channelComboBox->itemData(channelComboBox->currentIndex()).toInt();
m_exportSpec->sample_rate =
sampleRateComboBox->itemData(sampleRateComboBox->currentIndex()).toInt();
Index: audiofileio/encode/FlacAudioWriter.cpp
===================================================================
RCS file: audiofileio/encode/FlacAudioWriter.cpp
diff -N audiofileio/encode/FlacAudioWriter.cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ audiofileio/encode/FlacAudioWriter.cpp 23 Sep 2007 02:58:32 -0000
1.1
@@ -0,0 +1,222 @@
+/*
+Copyright (C) 2007 Ben Levitt
+ * Based on the ogg encoder module for K3b.
+ * Copyright (C) 1998-2007 Sebastian Trueg <address@hidden>
+
+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 "FlacAudioWriter.h"
+
+#include <stdio.h>
+#include "FLAC/export.h"
+
+#if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 6
+#define LEGACY_FLAC
+#include "FLAC/file_encoder.h"
+#else
+#undef LEGACY_FLAC
+#include "FLAC/stream_encoder.h"
+#endif
+
+RELAYTOOL_FLAC
+
+#include <QString>
+
+// Always put me below _all_ includes, this is needed
+// in case we run with memory leak detection enabled!
+#include "Debugger.h"
+
+
+class FlacAudioWriter::Private
+{
+public:
+ Private()
+ : encoder(0),
+ quality(5),
+ buffer(0),
+ bufferSize(0) {
+ }
+ ~Private() {
+ if (buffer) {
+ delete [] buffer;
+ }
+ }
+
+#ifdef LEGACY_FLAC
+ FLAC__FileEncoder *encoder;
+#else
+ FLAC__StreamEncoder *encoder;
+#endif
+ int quality;
+
+ int32_t *buffer;
+ long bufferSize;
+};
+
+
+FlacAudioWriter::FlacAudioWriter()
+ : AbstractAudioWriter()
+{
+ d = new Private();
+}
+
+
+FlacAudioWriter::~FlacAudioWriter()
+{
+ cleanup();
+ delete d;
+}
+
+
+const char* FlacAudioWriter::get_extension()
+{
+ return ".flac";
+}
+
+
+bool FlacAudioWriter::set_format_attribute(const QString& key, const QString&
value)
+{
+ if (key == "quality") {
+ d->quality = value.toInt();
+ return true;
+ }
+
+ return false;
+}
+
+
+bool FlacAudioWriter::open_private()
+{
+ cleanup();
+
+ /* allocate the encoder */
+#ifdef LEGACY_FLAC
+ if ((d->encoder = FLAC__file_encoder_new()) == NULL) {
+#else
+ if ((d->encoder = FLAC__stream_encoder_new()) == NULL) {
+#endif
+ PERROR("ERROR: allocating encoder");
+ return 1;
+ }
+
+ bool ok = true;
+
+#ifdef LEGACY_FLAC
+ //ok &= FLAC__file_encoder_set_compression_level(d->encoder,
d->quality);
+ ok &= FLAC__file_encoder_set_channels(d->encoder, m_channels);
+ ok &= FLAC__file_encoder_set_bits_per_sample(d->encoder, m_sampleWidth);
+ ok &= FLAC__file_encoder_set_sample_rate(d->encoder, m_rate);
+ ok &= FLAC__file_encoder_set_total_samples_estimate(d->encoder, 0); //
Set when done
+ ok &= FLAC__file_encoder_set_filename(d->encoder,
m_fileName.toUtf8().data());
+#else
+ ok &= FLAC__stream_encoder_set_compression_level(d->encoder,
d->quality);
+ ok &= FLAC__stream_encoder_set_channels(d->encoder, m_channels);
+ ok &= FLAC__stream_encoder_set_bits_per_sample(d->encoder,
m_sampleWidth);
+ ok &= FLAC__stream_encoder_set_sample_rate(d->encoder, m_rate);
+ ok &= FLAC__stream_encoder_set_total_samples_estimate(d->encoder, 0);
// Set when done
+#endif
+
+ /* initialize encoder */
+ if (ok) {
+#ifdef LEGACY_FLAC
+ FLAC__FileEncoderState init_status;
+ init_status = FLAC__file_encoder_init(d->encoder);
+ if (init_status != FLAC__FILE_ENCODER_OK) {
+ PERROR("ERROR: initializing encoder: %s",
FLAC__FileEncoderStateString[init_status]);
+ ok = false;
+ }
+#else
+ FLAC__StreamEncoderInitStatus init_status;
+ init_status = FLAC__stream_encoder_init_file(d->encoder,
m_fileName.toUtf8().data(), NULL, /*client_data=*/NULL);
+ if (init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK) {
+ PERROR("ERROR: initializing encoder: %s",
FLAC__StreamEncoderInitStatusString[init_status]);
+ ok = false;
+ }
+#endif
+ }
+
+ return ok;
+}
+
+
+nframes_t FlacAudioWriter::write_private(void* buffer, nframes_t frameCount)
+{
+ FLAC__byte *data = (FLAC__byte *)buffer;
+
+ if (d->bufferSize < frameCount * m_channels) {
+ if (d->buffer) {
+ delete [] d->buffer;
+ }
+ d->bufferSize = frameCount * m_channels;
+ d->buffer = new int32_t[d->bufferSize];
+ }
+
+ if (m_sampleWidth == 8) {
+ for (nframes_t i = 0; i < frameCount * m_channels; i++) {
+ d->buffer[i] = data[i];
+ }
+ }
+ else if (m_sampleWidth == 16) {
+ for (nframes_t i = 0; i < frameCount * m_channels; i++) {
+ d->buffer[i] =
(FLAC__int32)(((FLAC__int16)(FLAC__int8)data[2*i+1] << 8) |
(FLAC__int16)data[2*i]);
+ }
+ }
+ else if (m_sampleWidth == 24 || m_sampleWidth == 32) {
+ for (nframes_t i = 0; i < frameCount * m_channels; i++) {
+ d->buffer[i] =
(FLAC__int64)(((FLAC__int32)(((FLAC__int16)(FLAC__int8)data[4*i+1] << 8) |
(FLAC__int16)data[4*i]) << 16) |
+ (FLAC__int64)(((FLAC__int16)(FLAC__int8)data[4*i+3] <<
8) | (FLAC__int16)data[4*i+2]));
+ }
+ }
+
+#ifdef LEGACY_FLAC
+ bool ok = FLAC__file_encoder_process_interleaved(d->encoder, d->buffer,
frameCount);
+#else
+ bool ok = FLAC__seekable_stream_encoder_process_interleaved(d->encoder,
d->buffer, frameCount);
+#endif
+
+ return frameCount;
+}
+
+
+void FlacAudioWriter::cleanup()
+{
+ if (d->encoder) {
+#ifdef LEGACY_FLAC
+ FLAC__file_encoder_delete(d->encoder);
+#else
+ FLAC__stream_encoder_delete(d->encoder);
+#endif
+ d->encoder = 0;
+ }
+}
+
+
+void FlacAudioWriter::close_private()
+{
+#ifdef LEGACY_FLAC
+ FLAC__file_encoder_finish(d->encoder);
+#else
+ FLAC__stream_encoder_finish(d->encoder);
+#endif
+
+ // FIXME: Rewrite the header to store the real length (num samples)
+
+ cleanup();
+}
+
Index: audiofileio/encode/FlacAudioWriter.h
===================================================================
RCS file: audiofileio/encode/FlacAudioWriter.h
diff -N audiofileio/encode/FlacAudioWriter.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ audiofileio/encode/FlacAudioWriter.h 23 Sep 2007 02:58:32 -0000
1.1
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 2007 Ben Levitt
+
+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 FLACAUDIOWRITER_H
+#define FLACAUDIOWRITER_H
+
+#include "AbstractAudioWriter.h"
+#include "defines.h"
+
+
+class QString;
+
+class FlacAudioWriter : public AbstractAudioWriter
+{
+ Q_OBJECT
+
+public:
+ FlacAudioWriter();
+ ~FlacAudioWriter();
+
+ bool set_format_attribute(const QString& key, const QString& value);
+ const char* get_extension();
+
+protected:
+ bool open_private();
+ nframes_t write_private(void* buffer, nframes_t frameCount);
+ void cleanup();
+ void close_private();
+
+ class Private;
+ Private* d;
+};
+
+#endif