MythTV master
flacencoder.cpp
Go to the documentation of this file.
1// C++
2#include <cstdlib>
3#include <iostream>
4#include <unistd.h>
5
6// Qt
7#include <QString>
8
9// MythTV
13
14// MythMusic
15#include "flacencoder.h"
16
17#include <FLAC/stream_encoder.h>
18#include <FLAC/assert.h>
19
20FlacEncoder::FlacEncoder(const QString &outfile, int qualitylevel,
21 MusicMetadata *metadata)
22 : Encoder(outfile, qualitylevel, metadata),
23 m_encoder(FLAC__stream_encoder_new())
24{
25 bool streamable_subset = true;
26 bool do_mid_side = true;
27 bool loose_mid_side = false;
28 int bits_per_sample = 16;
29 int sample_rate = 44100;
30 int blocksize = 4608;
31 int max_lpc_order = 8;
32 int qlp_coeff_precision = 0;
33 bool qlp_coeff_prec_search = false;
34 bool do_escape_coding = false;
35 bool do_exhaustive_model_search = false;
36 int min_residual_partition_order = 3;
37 int max_residual_partition_order = 3;
38 int rice_parameter_search_dist = 0;
39
40 FLAC__stream_encoder_set_streamable_subset(m_encoder, streamable_subset);
41 FLAC__stream_encoder_set_do_mid_side_stereo(m_encoder, do_mid_side);
42 FLAC__stream_encoder_set_loose_mid_side_stereo(m_encoder, loose_mid_side);
43 FLAC__stream_encoder_set_channels(m_encoder, NUM_CHANNELS);
44 FLAC__stream_encoder_set_bits_per_sample(m_encoder, bits_per_sample);
45 FLAC__stream_encoder_set_sample_rate(m_encoder, sample_rate);
46 FLAC__stream_encoder_set_blocksize(m_encoder, blocksize);
47 FLAC__stream_encoder_set_max_lpc_order(m_encoder, max_lpc_order);
48 FLAC__stream_encoder_set_qlp_coeff_precision(m_encoder, qlp_coeff_precision);
49 FLAC__stream_encoder_set_do_qlp_coeff_prec_search(m_encoder, qlp_coeff_prec_search);
50 FLAC__stream_encoder_set_do_escape_coding(m_encoder, do_escape_coding);
51 FLAC__stream_encoder_set_do_exhaustive_model_search(m_encoder, do_exhaustive_model_search);
52 FLAC__stream_encoder_set_min_residual_partition_order(m_encoder, min_residual_partition_order);
53 FLAC__stream_encoder_set_max_residual_partition_order(m_encoder, max_residual_partition_order);
54 FLAC__stream_encoder_set_rice_parameter_search_dist(m_encoder, rice_parameter_search_dist);
55
56 QByteArray ofile = outfile.toLocal8Bit();
57 int ret = FLAC__stream_encoder_init_file(
58 m_encoder, ofile.constData(), nullptr, nullptr);
59 if (ret != FLAC__STREAM_ENCODER_INIT_STATUS_OK)
60 {
61 LOG(VB_GENERAL, LOG_ERR,
62 QString("Error initializing FLAC encoder. Got return code: %1")
63 .arg(ret));
64 }
65
66 for (auto & chan : m_inputIn)
67 chan.fill(0);
68
69 for (int i = 0; i < NUM_CHANNELS; i++)
70 m_input[i] = m_inputIn[i].data();
71}
72
74{
75 FlacEncoder::addSamples(nullptr, 0); // flush buffer
76
77 if (m_encoder)
78 {
79 FLAC__stream_encoder_finish(m_encoder);
80 FLAC__stream_encoder_delete(m_encoder);
81 }
82
83 if (m_metadata)
85}
86
87int FlacEncoder::addSamples(int16_t *bytes, unsigned int length)
88{
89 if (length == 0)
90 {
91 // Flush buffer (if any)
92 if (m_sampleIndex > 0)
93 return processSamples();
94 return 0;
95 }
96 if (nullptr == bytes)
97 return 0;
98
99 unsigned int index = 0;
100
101 length /= sizeof(int16_t);
102
103 while (index < length)
104 {
105 m_input[0][m_sampleIndex] = (FLAC__int32)(bytes[index++]);
106 m_input[1][m_sampleIndex] = (FLAC__int32)(bytes[index++]);
107 m_sampleIndex += 1;
108
110 {
111 int ret = processSamples();
112 if (ret < 0)
113 return ret;
114 }
115 }
116
117 return 0;
118}
119
121{
122 if (!FLAC__stream_encoder_process(m_encoder,
123 (const FLAC__int32 * const *) m_input.data(),
125 {
126 LOG(VB_GENERAL, LOG_ERR,
127 QString("Failed to write flac data. Aborting."));
128 return EENCODEERROR;
129 }
130 m_sampleIndex = 0;
131 return 0;
132}
MusicMetadata * m_metadata
Definition: encoder.h:26
const QString m_outfile
Definition: encoder.h:23
unsigned int m_sampleIndex
Definition: flacencoder.h:27
FlacEncoder(const QString &outfile, int qualitylevel, MusicMetadata *metadata)
Definition: flacencoder.cpp:20
std::array< std::array< FLAC__int32, MAX_SAMPLES >, NUM_CHANNELS > m_inputIn
Definition: flacencoder.h:29
std::array< FLAC__int32 *, NUM_CHANNELS > m_input
Definition: flacencoder.h:30
~FlacEncoder() override
Definition: flacencoder.cpp:73
int addSamples(int16_t *bytes, unsigned int len) override
Definition: flacencoder.cpp:87
int processSamples()
FLAC__StreamEncoder * m_encoder
Definition: flacencoder.h:26
Read and write Vorbis (Xiph) tags in a FLAC file.
bool write(const QString &filename, MusicMetadata *mdata) override
Writes all metadata back to a file.
#define EENCODEERROR
Definition: encoder.h:7
static constexpr size_t MAX_SAMPLES
Definition: flacencoder.h:11
static constexpr int8_t NUM_CHANNELS
Definition: flacencoder.h:12
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39