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