Hello Ralph,> Likewise opus_encode() takes 16 bit samples, so you need to extend each > sample from an 8 bit source before encoding.Two questions 1. In opusenc.c which API does the extending the 8-bit to 16-bit? 2. If that is the case then how will 24 bit PCM sample work? Regards Amit On Thu, Jan 7, 2016 at 12:21 PM, Ralph Giles <giles at thaumas.net> wrote:> On 07/01/16 10:04 AM, Amit Ashara wrote: > > > opus_decoder_ctl(sOpusDec, OPUS_SET_LSB_DEPTH(ui32BitsPerSample)); > > OPUS_SET_LSB_DEPTH only affects the encoder. If you check the return > value here you should get OPUS_UNIMPLEMENTED. > > > output_samples = opus_decode(sOpusDec, (const unsigned char > > *)&pcRdBuf[0], len, opi16_out, (ui32SizeOfWrBuf/ui8ScaleFactor), 0); > > I suspect the issue is dividing by ui8ScaleFactor = 1 here. > OPUS_SET_LSB_DEPTH works as a precision hint to the encoder about where > to set the noise floor, but opus_decode still returns 16 bit samples. It > always returns 16 bit samples, regardless of whether the original input > as 8 bit, 16 bit or 24 bit precision (from opus_encode_float). > > To actually output 8-bit wav, you have to keep track of this out-of-band > and truncate each sample before writing it out. > > Likewise opus_encode() takes 16 bit samples, so you need to extend each > sample from an 8 bit source before encoding. > > HTH, > -r >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/opus/attachments/20160107/27b9ecef/attachment.htm
Hello Ralph, I was finally able to get it to work for both 8 and 16 bit PCM data. However the output of the decoder is always 16 bit PCM and never the original 8 bit making the wav file decoded 2x times the original file. This is a restriction for some embedded system. Any idea how to work around or fix the issue? I did try reading out the 8-bit data from the 16 bit output but it does not seem that simple (based on stackoverflow.com) and I am still searching on an easier mechanism. Regards Amit On Thu, Jan 7, 2016 at 12:41 PM, Amit Ashara <ashara.amit at gmail.com> wrote:> Hello Ralph, > > > Likewise opus_encode() takes 16 bit samples, so you need to extend each > > sample from an 8 bit source before encoding. > > Two questions > 1. In opusenc.c which API does the extending the 8-bit to 16-bit? > 2. If that is the case then how will 24 bit PCM sample work? > > Regards > Amit > > On Thu, Jan 7, 2016 at 12:21 PM, Ralph Giles <giles at thaumas.net> wrote: > >> On 07/01/16 10:04 AM, Amit Ashara wrote: >> >> > opus_decoder_ctl(sOpusDec, OPUS_SET_LSB_DEPTH(ui32BitsPerSample)); >> >> OPUS_SET_LSB_DEPTH only affects the encoder. If you check the return >> value here you should get OPUS_UNIMPLEMENTED. >> >> > output_samples = opus_decode(sOpusDec, (const unsigned char >> > *)&pcRdBuf[0], len, opi16_out, (ui32SizeOfWrBuf/ui8ScaleFactor), 0); >> >> I suspect the issue is dividing by ui8ScaleFactor = 1 here. >> OPUS_SET_LSB_DEPTH works as a precision hint to the encoder about where >> to set the noise floor, but opus_decode still returns 16 bit samples. It >> always returns 16 bit samples, regardless of whether the original input >> as 8 bit, 16 bit or 24 bit precision (from opus_encode_float). >> >> To actually output 8-bit wav, you have to keep track of this out-of-band >> and truncate each sample before writing it out. >> >> Likewise opus_encode() takes 16 bit samples, so you need to extend each >> sample from an 8 bit source before encoding. >> >> HTH, >> -r >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/opus/attachments/20160107/c215f47b/attachment.htm
Hello Benjamin, The original WAV file I have is linear 8-bit PCM. I want to ensure that original linear formats are kept as is. Later I will add support for ulaw. Regards Amit On Fri, Jan 8, 2016 at 5:34 PM, Benjamin Schwartz < benjamin.m.schwartz at gmail.com> wrote:> Do you really need linear 8-bit PCM or do you want ulaw? Linear 8-bit is > ... pretty rare. > > On Thu, Jan 7, 2016 at 8:11 PM, Amit Ashara <ashara.amit at gmail.com> wrote: > >> Hello Ralph, >> >> I was finally able to get it to work for both 8 and 16 bit PCM data. >> However the output of the decoder is always 16 bit PCM and never the >> original 8 bit making the wav file decoded 2x times the original file. >> >> This is a restriction for some embedded system. Any idea how to work >> around or fix the issue? >> >> I did try reading out the 8-bit data from the 16 bit output but it does >> not seem that simple (based on stackoverflow.com) and I am still >> searching on an easier mechanism. >> >> Regards >> Amit >> >> On Thu, Jan 7, 2016 at 12:41 PM, Amit Ashara <ashara.amit at gmail.com> >> wrote: >> >>> Hello Ralph, >>> >>> > Likewise opus_encode() takes 16 bit samples, so you need to extend each >>> > sample from an 8 bit source before encoding. >>> >>> Two questions >>> 1. In opusenc.c which API does the extending the 8-bit to 16-bit? >>> 2. If that is the case then how will 24 bit PCM sample work? >>> >>> Regards >>> Amit >>> >>> On Thu, Jan 7, 2016 at 12:21 PM, Ralph Giles <giles at thaumas.net> wrote: >>> >>>> On 07/01/16 10:04 AM, Amit Ashara wrote: >>>> >>>> > opus_decoder_ctl(sOpusDec, OPUS_SET_LSB_DEPTH(ui32BitsPerSample)); >>>> >>>> OPUS_SET_LSB_DEPTH only affects the encoder. If you check the return >>>> value here you should get OPUS_UNIMPLEMENTED. >>>> >>>> > output_samples = opus_decode(sOpusDec, (const unsigned char >>>> > *)&pcRdBuf[0], len, opi16_out, (ui32SizeOfWrBuf/ui8ScaleFactor), 0); >>>> >>>> I suspect the issue is dividing by ui8ScaleFactor = 1 here. >>>> OPUS_SET_LSB_DEPTH works as a precision hint to the encoder about where >>>> to set the noise floor, but opus_decode still returns 16 bit samples. It >>>> always returns 16 bit samples, regardless of whether the original input >>>> as 8 bit, 16 bit or 24 bit precision (from opus_encode_float). >>>> >>>> To actually output 8-bit wav, you have to keep track of this out-of-band >>>> and truncate each sample before writing it out. >>>> >>>> Likewise opus_encode() takes 16 bit samples, so you need to extend each >>>> sample from an 8 bit source before encoding. >>>> >>>> HTH, >>>> -r >>>> >>> >>> >> >> _______________________________________________ >> opus mailing list >> opus at xiph.org >> http://lists.xiph.org/mailman/listinfo/opus >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.xiph.org/pipermail/opus/attachments/20160109/9eb455fa/attachment.htm
opus_decode() produces 16-bit signed linear PCM, and opus_decode_float() produces 32-bit floating point PCM that is useful when you want a higher bit depth. If you need 8-bit linear PCM then a simple solution would be to use only the top 8 bits of each 16-bit sample from opus_decode(). Note that the WAV format uses unsigned rather than signed integers for 8-bit linear PCM. (It uses signed for larger sample sizes and AIFF uses signed for all sizes.) So if you are writing 8-bit linear PCM to WAV then you would need something like (((unsigned short)sample ^ 0x8000) >> 8) to convert from signed to unsigned and get the top 8 bits of each sample. You will achieve better quality, however, if you apply dither. opusdec applies dither by default if the output is not floating point, although it does not support 8-bit output. - Mark