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
00017 #include <FLAC/file_encoder.h>
00018 #else
00019
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
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
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);
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