MythTV  0.26-pre
flacencoder.cpp
Go to the documentation of this file.
00001 #include <unistd.h>
00002 
00003 #include <cstdlib>
00004 
00005 #include <iostream>
00006 using namespace std;
00007 
00008 #include <QString>
00009 
00010 #include "metadata.h"
00011 #include "flacencoder.h"
00012 #include "metaioflacvorbis.h"
00013 
00014 #include <FLAC/export.h>
00015 #if !defined(NEWFLAC)
00016   /* FLAC 1.0.4 to 1.1.2 */
00017   #include <FLAC/file_encoder.h>
00018 #else
00019   /* FLAC 1.1.3 and up */
00020   #include <FLAC/stream_encoder.h>
00021 #endif
00022 
00023 #include <FLAC/assert.h>
00024 #include <mythcontext.h>
00025 
00026 FlacEncoder::FlacEncoder(const QString &outfile, int qualitylevel,
00027                          Metadata *metadata)
00028            : Encoder(outfile, qualitylevel, metadata)
00029 {
00030     sampleindex = 0;
00031 
00032     bool streamable_subset = true;
00033     bool do_mid_side = true;
00034     bool loose_mid_side = false;
00035     int bits_per_sample = 16;
00036     int sample_rate = 44100;
00037     int blocksize = 4608;
00038     int max_lpc_order = 8;
00039     int qlp_coeff_precision = 0;
00040     bool qlp_coeff_prec_search = false;
00041     bool do_escape_coding = false;
00042     bool do_exhaustive_model_search = false;
00043     int min_residual_partition_order = 3;
00044     int max_residual_partition_order = 3;
00045     int rice_parameter_search_dist = 0;
00046 
00047     encoder = encoder_new();
00048     encoder_setup(encoder, streamable_subset,
00049                   do_mid_side, loose_mid_side,
00050                   NUM_CHANNELS, bits_per_sample,
00051                   sample_rate, blocksize,
00052                   max_lpc_order, qlp_coeff_precision,
00053                   qlp_coeff_prec_search, do_escape_coding,
00054                   do_exhaustive_model_search,
00055                   min_residual_partition_order,
00056                   max_residual_partition_order,
00057                   rice_parameter_search_dist);
00058 
00059     QByteArray ofile = outfile.toLocal8Bit();
00060 #if !defined(NEWFLAC)
00061     /* FLAC 1.0.4 to 1.1.2 */
00062     FLAC__file_encoder_set_filename(encoder, ofile.constData());
00063 
00064     int ret = FLAC__file_encoder_init(encoder);
00065     if (ret != FLAC__FILE_ENCODER_OK)
00066 #else
00067     /* FLAC 1.1.3 and up */
00068     int ret = FLAC__stream_encoder_init_file(
00069         encoder, ofile.constData(), NULL, NULL);
00070     if (ret != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
00071 #endif
00072     {
00073         LOG(VB_GENERAL, LOG_ERR,
00074             QString("Error initializing FLAC encoder. Got return code: %1")
00075                 .arg(ret));
00076     }
00077 
00078     for (int i = 0; i < NUM_CHANNELS; i++)
00079         input[i] = &(inputin[i][0]); 
00080 }
00081 
00082 FlacEncoder::~FlacEncoder()
00083 {
00084     addSamples(0, 0); // flush buffer
00085 
00086     if (encoder)
00087     {
00088         encoder_finish(encoder);
00089         encoder_delete(encoder);
00090     }
00091 
00092     if (m_metadata)
00093     {
00094         QString filename = m_metadata->Filename();
00095         m_metadata->setFilename(m_outfile);
00096         MetaIOFLACVorbis().write(m_metadata);
00097         m_metadata->setFilename(filename);
00098     }
00099 }
00100 
00101 int FlacEncoder::addSamples(int16_t *bytes, unsigned int length)
00102 {
00103     unsigned int index = 0;
00104 
00105     length /= sizeof(int16_t);
00106 
00107     do {
00108         while (index < length && sampleindex < MAX_SAMPLES) 
00109         {
00110             input[0][sampleindex] = (FLAC__int32)(bytes[index++]);
00111             input[1][sampleindex] = (FLAC__int32)(bytes[index++]);
00112             sampleindex += 1;
00113         }
00114 
00115         if(sampleindex == MAX_SAMPLES || (length == 0 && sampleindex > 0) ) 
00116         {
00117             if (!encoder_process(encoder, (const FLAC__int32 * const *) input,
00118                                  sampleindex))
00119             {
00120                 LOG(VB_GENERAL, LOG_ERR,
00121                     QString("Failed to write flac data. Aborting."));
00122                 return EENCODEERROR;
00123             }
00124             sampleindex = 0;
00125         }
00126     } while (index < length);
00127 
00128     return 0;
00129 }
00130 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends