26 #include <KLocalizedString> 37 #define BUFFER_SIZE 1024 40 #define DEFAULT_BITRATE 64000 44 :m_comments_map(), m_info()
67 if (!info.
contains(property))
continue;
70 vorbis_comment_add_tag(&
m_vc,
72 UTF8(info.
get(property).toString())
87 const unsigned int tracks = info.
tracks();
88 const long int sample_rate =
static_cast<const long int>(info.
rate());
92 i18n(
"This codec supports only mono or stereo files, " 93 "%1 channels are not supported.", tracks));
109 qDebug(
"OggEncoder: ABR=%d...%d...%d Bits/s, VBR=%d%%",
110 bitrate_lower,bitrate_nominal,bitrate_upper,vbr_quality);
112 if ((vbr_quality < 0) && (bitrate_nominal <= 0)) {
115 i18n(
"You have not selected any bitrate for the encoding. " 116 "Do you want to continue and encode with %1 kBit/s " 117 "or cancel and choose a different bitrate?",
127 Q_ASSERT(tracks < 255);
128 if (tracks > 255)
return false;
131 vorbis_info_init(&
m_vi);
133 if ((bitrate_lower > 0) || (bitrate_upper > 0)) {
135 bitrate_nominal = (bitrate_upper + bitrate_lower) / 2;
136 ret = vorbis_encode_init(&
m_vi, tracks, sample_rate,
140 qDebug(
"VorbisEncoder: ABR with %d...%d...%d Bits/s",
141 bitrate_lower, bitrate_nominal, bitrate_upper);
142 }
else if ((vbr_quality < 0) && (bitrate_nominal > 0)) {
144 ret = vorbis_encode_setup_managed(&
m_vi, tracks, sample_rate,
145 -1, bitrate_nominal, -1);
150 vorbis_encode_ctl(&
m_vi, OV_ECTL_RATEMANAGE2_SET, Q_NULLPTR) ||
151 vorbis_encode_setup_init(&
m_vi);
153 qDebug(
"VorbisEncoder: CBR with %d Bits/s", bitrate_nominal);
154 }
else if (vbr_quality >= 0) {
156 ret = vorbis_encode_init_vbr(&
m_vi, tracks, sample_rate,
157 static_cast<float>(vbr_quality) / 100.0f);
158 qDebug(
"OggEncoder: VBR with %d%%", vbr_quality);
161 qWarning(
"unknown Ogg/Vorbis setup: VBR quality=%d%%, " 162 "ABR lower=%d, ABR highest=%d, ABR nominal=%d",
163 vbr_quality, bitrate_lower, bitrate_upper,
173 "parameters are not supported. Please change the " 174 "settings and try again."));
179 vorbis_comment_init(&
m_vc);
190 qsrand(QTime::currentTime().msec() ^ qrand());
191 ogg_stream_init(&
m_os, qrand());
206 ogg_packet header_comm;
207 ogg_packet header_code;
209 vorbis_analysis_headerout(&
m_vd, &
m_vc, &header, &header_comm,
212 ogg_stream_packetin(&
m_os, &header);
213 ogg_stream_packetin(&
m_os, &header_comm);
214 ogg_stream_packetin(&
m_os, &header_code);
218 while (ogg_stream_flush(&
m_os, &
m_og)) {
219 dst.write(reinterpret_cast<char *>(
m_og.header),
221 dst.write(reinterpret_cast<char *>(
m_og.body),
243 vorbis_analysis_wrote(&
m_vd, 0);
249 unsigned int pos = 0;
253 for (
unsigned int track = 0; track < tracks; ++track) {
254 float *p = buffer[track];
255 unsigned int l = src[track]->read(samples, 0, len);
258 const unsigned int block = 8;
260 while (pos + block < l) {
261 for (
unsigned int i = 0; i < block; ++i, ++pos)
273 vorbis_analysis_wrote(&
m_vd, pos);
279 while (vorbis_analysis_blockout(&
m_vd, &
m_vb) == 1) {
281 vorbis_analysis(&
m_vb, Q_NULLPTR);
282 vorbis_bitrate_addblock(&
m_vb);
284 while (vorbis_bitrate_flushpacket(&
m_vd, &
m_op)) {
290 int result = ogg_stream_pageout(&
m_os, &
m_og);
292 dst.write(reinterpret_cast<char*>(
m_og.header),
294 dst.write(reinterpret_cast<char *>(
m_og.body),
300 if (ogg_page_eos(&
m_og)) eos =
true;
312 ogg_stream_clear(&
m_os);
314 vorbis_block_clear(&
m_vb);
315 vorbis_dsp_clear(&
m_vd);
316 vorbis_comment_clear(&
m_vc);
317 vorbis_info_clear(&
m_vi);
virtual bool encode(Kwave::MultiTrackReader &src, QIODevice &dst) Q_DECL_OVERRIDE
bool contains(const FileProperty property) const
virtual bool open(QWidget *widget, const Kwave::FileInfo &info, Kwave::MultiTrackReader &src) Q_DECL_OVERRIDE
void encodeProperties(const Kwave::FileInfo &info)
QVariant get(FileProperty key) const
static int sorry(QWidget *widget, QString message, QString caption=QString())
virtual ~VorbisEncoder() Q_DECL_OVERRIDE
virtual void close() Q_DECL_OVERRIDE
sample_index_t length() const
virtual bool writeHeader(QIODevice &dst) Q_DECL_OVERRIDE
static float sample2float(const sample_t s)
static int warningContinueCancel(QWidget *widget, QString message, QString caption=QString(), const QString buttonContinue=QString(), const QString buttonCancel=QString(), const QString &dontAskAgainName=QString())
unsigned int tracks() const
const sample_t * constData() const
Kwave::VorbisCommentMap m_comments_map