Added downmuxing support to TranscodingDataStream for audio streams with

> 2 channels. Also added support for mono.
This commit is contained in:
casey langen 2017-05-21 23:10:33 -07:00
parent 167d7acacd
commit ba62116a16
2 changed files with 59 additions and 14 deletions

View File

@ -178,19 +178,62 @@ PositionType TranscodingDataStream::Read(void *buffer, PositionType bytesToRead)
while (hasBuffer && bytesWritten < (size_t) bytesToRead) {
/* calculated according to lame.h */
size_t numSamples = pcmBuffer->Samples() / pcmBuffer->Channels();
size_t channels = pcmBuffer->Channels();
size_t numSamples = pcmBuffer->Samples() / channels;
size_t requiredBytes = (size_t) (1.25 * (float)numSamples + 7200.0);
encodedBytes.realloc(requiredBytes);
/* encode PCM -> MP3 */
int encodeCount =
lame_encode_buffer_interleaved_ieee_float(
lame,
pcmBuffer->BufferPointer(),
numSamples,
encodedBytes.data,
encodedBytes.length);
int encodeCount = -1;
/* stereo is easy, just make sure we send to to the encoder as
interleaved! */
if (pcmBuffer->Channels() == 2) {
encodeCount =
lame_encode_buffer_interleaved_ieee_float(
lame,
pcmBuffer->BufferPointer(),
numSamples,
encodedBytes.data,
encodedBytes.length);
}
/* the non-stereo case needs to be downmuxed. our downmuxing is simple,
we just use the stereo channels. in the case of mono, we duplicate the
to left and right */
else {
downmux.realloc(numSamples * 2);
float* from = pcmBuffer->BufferPointer();
float* to = downmux.data;
if (channels == 1) {
/* mono -> stereo */
for (size_t i = 0; i < numSamples; i++) {
*(to + 0) = *from;
*(to + 1) = *from;
to += 2;
++from;
}
}
else {
/* 3+ channels -> stereo */
for (size_t i = 0; i < numSamples; i++) {
*(to + 0) = *(from + 0);
*(to + 1) = *(from + 1);
to += 2;
from += channels;
}
}
encodeCount =
lame_encode_buffer_interleaved_ieee_float(
lame,
downmux.data,
numSamples,
encodedBytes.data,
encodedBytes.length);
}
if (encodeCount < 0) {
goto internal_error;

View File

@ -78,6 +78,7 @@ class TranscodingDataStream : public musik::core::sdk::IDataStream {
musik::core::sdk::IDecoder* decoder;
musik::core::sdk::IBuffer* pcmBuffer;
template <typename T>
struct ByteBuffer {
ByteBuffer() {
data = nullptr;
@ -89,7 +90,7 @@ class TranscodingDataStream : public musik::core::sdk::IDataStream {
void realloc(size_t newLength) {
if (newLength > rawLength) {
delete[] data;
data = new unsigned char[newLength];
data = new T[newLength];
rawLength = length = newLength;
}
offset = 0;
@ -103,7 +104,7 @@ class TranscodingDataStream : public musik::core::sdk::IDataStream {
size_t avail() {
return (length > offset) ? length - offset : 0;
}
unsigned char* pos() {
T* pos() {
return data + offset;
}
void inc(size_t count) {
@ -114,7 +115,7 @@ class TranscodingDataStream : public musik::core::sdk::IDataStream {
}
void swap(ByteBuffer& with) {
size_t off = offset, len = length, raw = rawLength;
unsigned char* d = data;
T* d = data;
this->data = with.data;
this->length = with.length;
this->rawLength = with.rawLength;
@ -124,12 +125,13 @@ class TranscodingDataStream : public musik::core::sdk::IDataStream {
with.rawLength = raw;
with.offset = offset;
}
unsigned char *data;
T *data;
size_t offset, length, rawLength;
};
ByteBuffer encodedBytes;
ByteBuffer spillover;
ByteBuffer<unsigned char> encodedBytes;
ByteBuffer<unsigned char> spillover;
ByteBuffer<float> downmux;
size_t bitrate;
bool eof;
std::mutex mutex;