diff options
Diffstat (limited to 'Src/Plugins/Encoder/enc_lame/24bit.cpp')
-rw-r--r-- | Src/Plugins/Encoder/enc_lame/24bit.cpp | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/Src/Plugins/Encoder/enc_lame/24bit.cpp b/Src/Plugins/Encoder/enc_lame/24bit.cpp new file mode 100644 index 00000000..d1b83b1f --- /dev/null +++ b/Src/Plugins/Encoder/enc_lame/24bit.cpp @@ -0,0 +1,147 @@ +#include "MP3Coder.h" +#include <malloc.h> + +static const float const_1_div_128_ = 32768.0 / 128.0; /* 8 bit multiplier */ +static const double const_1_div_2147483648_ = 32768.0 / 2147483648.0; /* 32 bit multiplier */ + +static void Int8_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count) +{ + signed char *src = (signed char*)sourceBuffer; + + while( count-- ) + { + float samp = *src * const_1_div_128_; + *dest = samp; + + src += sourceStride; + dest ++; + } +} + +static void Int24_To_Float32(float *dest, void *sourceBuffer, signed int sourceStride, unsigned int count) +{ + unsigned char *src = (unsigned char*)sourceBuffer; + + while ( count-- ) + { + signed long temp = (((long)src[0]) << 8); + temp = temp | (((long)src[1]) << 16); + temp = temp | (((long)src[2]) << 24); + *dest = (float) ((double)temp * const_1_div_2147483648_); + src += sourceStride * 3; + dest ++; + } +} + +int AudioCoderMP3_24::Encode(int framepos, void *in, int in_avail, int *in_used, void *out, int out_avail) +{ + if (m_err) return -1; + if (!hbeStream) + { + if (beInitStream(&beConfig, &ibuf_size_spls, &obuf_size, (PHBE_STREAM) &hbeStream) != BE_ERR_SUCCESSFUL) + { + m_err++; + return -1; + } + ibuf_size = ibuf_size_spls * bytesPerSample; + + if (is_downmix) ibuf_size *= 2; + + bs = (char*)malloc(ibuf_size); + bs_size = 0; + } + + *in_used = 0; + + int needbytes = ibuf_size - bs_size; + if (needbytes > 0 && in_avail > 0) + { + if (needbytes > in_avail) + needbytes = in_avail; + memcpy(bs + bs_size, in, needbytes); + bs_size += needbytes; + *in_used = needbytes; + } + + if (!done) + { + if (bs_size < (int)ibuf_size) return 0; + } + + if (out_avail < (int)obuf_size) return 0; + + int feedBytes = min(bs_size, (int)ibuf_size); + int feedSamples = feedBytes / bytesPerSample; + bs_size -= feedBytes; + /* + if (is_downmix) + { + int x; + int l = feedBytes / 4; + short *b = (short*)bs; + for (x = 0; x < l; x ++) + { + b[x] = b[x * 2] / 2 + b[x * 2 + 1] / 2; + } + } + */ + DWORD dwo = 0; + + if (feedSamples) + { + if (mono_input) + { + float *float_l = (float *)alloca(sizeof(float) * feedSamples); + switch(bytesPerSample) + { + case 8: + Int8_To_Float32(float_l, bs, 1, feedSamples); + break; + case 24: + Int24_To_Float32(float_l, bs, 1, feedSamples); + break; + } + + + if (beEncodeChunkFloatS16NI(hbeStream, feedSamples, float_l, float_l, (unsigned char *)out, &dwo) != BE_ERR_SUCCESSFUL) + { + m_err++; + return -1; + } + } + else + { + float *float_l = (float *)alloca(sizeof(float) * feedSamples / 2); + float *float_r = (float *)alloca(sizeof(float) * feedSamples / 2); + switch(bytesPerSample) + { + case 1: // 8 bit + Int8_To_Float32(float_l, bs, 2, feedSamples / 2); + Int8_To_Float32(float_r, bs + 1, 2, feedSamples / 2); + break; + case 3: // 24 bit + Int24_To_Float32(float_l, bs, 2, feedSamples / 2); + Int24_To_Float32(float_r, bs + 3, 2, feedSamples / 2); + break; + } + + if (beEncodeChunkFloatS16NI(hbeStream, feedSamples / 2, float_l, float_r, (unsigned char *)out, &dwo) != BE_ERR_SUCCESSFUL) + { + m_err++; + return -1; + } + } + } + + if (!dwo && done == 1) + { + if (beDeinitStream(hbeStream, (unsigned char *)out, &dwo) != BE_ERR_SUCCESSFUL) + { + m_err++; + return -1; + } + done++; + } + + return dwo; +}
\ No newline at end of file |