-
Notifications
You must be signed in to change notification settings - Fork 0
/
encoderlame.cpp
126 lines (117 loc) · 3.42 KB
/
encoderlame.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "encoderlame.h"
EncoderLame::EncoderLame(EncoderConfig c)
: Encoder(c)
{
}
EncoderLame::~EncoderLame()
{
if (_lgf) {
lame_close(_lgf);
_lgf = 0;
}
delete[] _buffer;
}
bool EncoderLame::init()
{
if (isInitialized())
return true;
int rc;
_lgf = lame_init();
/*
emit message(QString::number(_config.numInChannels));
emit message(QString::number(_config.sampleRateIn));
emit message(QString::number(_config.sampleRateOut));
emit message(QString::number(_config.bitRate));
*/
lame_set_num_channels(_lgf, _config.numInChannels);
lame_set_in_samplerate(_lgf, _config.sampleRateIn);
lame_set_out_samplerate(_lgf, _config.sampleRateOut);
if (_config.mode == EncoderConfig::CBR)
lame_set_brate(_lgf, _config.quality);
else if (_config.mode == EncoderConfig::VBR) {
lame_set_VBR(_lgf, vbr_mtrh);
lame_set_VBR_quality(_lgf, 10.0 - 10 * _config.quality);
}
if ((rc = lame_init_params(_lgf)) < 0) {
emit error("unable to init lame");
emit error("Channels " + QString::number(_config.numInChannels));
emit error("RateIn " + QString::number(_config.sampleRateIn));
emit error("RateOut " + QString::number(_config.sampleRateOut));
emit error("BitRate " + QString::number(_config.quality));
return false;
}
else {
_initialized = true;
emit message("Lame initialized");
emit message("Version: " + getVersion());
}
// default output buffer size. see lame.h
resize(DSP_BLOCKSIZE);
return true;
}
void EncoderLame::setup()
{
// nothing to do here
}
void EncoderLame::encode(sample_t* buffer, uint32_t samples)
{
int rc;
if (samples == 0 || !isInitialized())
return;
if (_allocedFrames < samples)
resize(samples);
if (_config.numInChannels == 2)
rc = lame_encode_buffer_interleaved_ieee_double(_lgf, buffer, samples / _config.numInChannels, reinterpret_cast<unsigned char*>(_buffer), _bufferSize);
else if (_config.numInChannels == 1)
rc = lame_encode_buffer_ieee_double(_lgf, buffer, buffer, samples, reinterpret_cast<unsigned char*>(_buffer), _bufferSize);
else {
emit error("Lame can't handle more than 2 channels.");
assert(0);
}
if (rc >= 0)
_bufferValid = rc;
else {
_bufferValid = 0;
handleRC(rc);
}
}
void EncoderLame::finalize()
{
}
void EncoderLame::handleRC(int rc) const
{
switch (rc) {
case -1:
emit error("Lame: out buffer to small");
break;
case -2:
emit error("Lame: unable to allocate memory");
break;
case -3:
emit error("Lame: init not called. Should never happen.");
break;
case -4:
emit error("Lame: psycho acoustic problem occurred");
break;
default:
emit error("Lame: unknown error occurred. ");
}
}
void EncoderLame::resize(uint32_t newSize)
{
delete[] _buffer;
_allocedFrames = newSize;
// default output buffer size. see lame.h
_bufferSize = 1.25 * _allocedFrames + 7200;
_buffer = new char[_bufferSize];
}
QString EncoderLame::getVersion() const
{
QString info;
if (!isInitialized()) {
emit error("lame is not initialized. Can't get version info.");
return info;
}
QString lame_version(get_lame_version());
return lame_version;
}