traverso-commit
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]