|
MythTV
0.26-pre
|
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
1.7.6.1