[PD] convert signal to 16bit stream

cyrille henry ch at chnry.net
Wed Nov 23 11:29:24 CET 2016

oh, and to answer about the why do you need a [t b b] to generate your table :
it's because you bang 1st the switch~.
I would bang it last.
but since you've got an other switch~ in a subpatch (for the elegant upsampling), the correct order is in attachment.


Le 23/11/2016 à 10:59, Roman Haefeli a écrit :
> Hey all
> Thanks for your submissions, Cyrille and Patrice. I put my 4 versions
> and yours into a single patch to make it easy for comparing. It turns
> out I'm not clearly in favor of any of them. All work fine and none is
> perfect. In netpd, I went for table_lookup, however, it later turned
> out that CPU wise, it's not that significantly faster than the others
> and may not justify to use 2x4x65536 (which is a half MB!) of memory.
> All of them are significantly faster than the message based version,
> which is not that surprising.
> Cyrilly, I think the table_lookup variant is what you described in your
> mail.
> It turns out that the difficult part is to find a way to implement an
> [int~] with Pd-vanilla objects. Once, you have an [int~], you have a
> [div~], and when you have [div~], you have a [mod~]. However, making a
> good [int~] is not that trivial. One can make one with [wrap~], but it
> exhibits the strange behaviour that it outputs '1' with '0' as input.
> To work-around that, I add an integer constant to the input of [wrap~]
> so that its input is always greater than 0. But because we're dealing
> with floating point numbers, the fractional part of [wrap~] output is
> less precise than the fractional part of its input (before constant was
> added), which leads to rounding errors.
> uint8_table uses a pre-computed table with values from 0 to 255, which
> can be used as [int~] for said range.
> float_rounding implements an [int~] by adding (and subsequently
> subtracting) a constant which is high enough so that the fractional
> part of the floating point number disappears. This approach might be
> interesting for the purpose of this exercise, but it shoudln't be used.
> It would break in an environment with a different floating point number
> format.
> Cyrille Henry's approach assumes the receiving side automatically wraps
> negative numbers around. It turns out to be true for the object classes
> I'm interested in ([packOSC], [tcpclient], [netsend -b]), so his
> version is quite clean and because of the lack of implementing another
> [mod], it uses less arithmetic operations than my 'wrap' approach. It
> totally lacks divisions. Thumbs up!
> Patrice Colet's version uses [expr~] for some parts, which is fine, I
> think. Somehow, for positive inputs the LSB is always higher by one
> compared to the others. This leads to even more severe side effect for
> input 1: 127 0 (should be 127 255).
> Please share your opinions. I now think Cyrille's version is the best.
> Roman
> On Tue, 2016-11-08 at 12:06 +0100, cyrille henry wrote:
>> hello,
>> in your patch, the input signal is truncated, so strange things
>> append near 0.
>> I think rounding to inferior value will gives better result.
>> here is a version done with 2 wrap~.
>> the result for negative number is a bit different than in your
>> example for 2 reason :
>> - it round to inferior value and not truncate the input.
>> - it return negative int, but in uint8 : 255 and -1 are the same
>> number anyhow.
>> sometimes rounding error result in 1 being 0.9999. So i guess this
>> patch is useless.
>> The other easy solution I can think of is using 2 tables with 65K
>> point each, and reading the tables with tabread~.
>> it is easy to populate the table with the value you want.
>> sorry, i don't have time to provide a patch.
>> cheers
>> Cyrille
>> Le 07/11/2016 à 16:24, Roman Haefeli a écrit :
>>> Hi all
>>> In order to store audio data more efficiently in netpd presets and
>>> also
>>> to transmit live audio through OSC, I'm thinking of ways to convert
>>> an
>>> signal to a 16-bit stream represented as two signals, one for each
>>> byte, the first for MSB and the second for LSB. I already came up
>>> with
>>> a few solutions, but I'm not totally happy with any of them because
>>> they are not very efficient or/and have strange edge cases. It
>>> turns
>>> out what seems a simple task is a bit more complex and probably has
>>> quiet a few totally different solutions.
>>> I would be interested to see with what solutions people come up
>>> with.
>>> Consider it a puzzle, a brain teaser (in case you're done writing
>>> your
>>> paper for pdcon and need some distraction).
>>> Requirements:
>>>  * It must be done in signal domain (I was doing it in message
>>> domain
>>>    yet, but performance is obviously bad)
>>>  * Only vanilla objects are allowed.
>>>  * Input is in the range -1 to 1. Input outside this range should
>>> be
>>>    clipped and not wrapped around.
>>>  * Output is two signals, each consisting of an integer value
>>> between
>>>    0 and 255
>>>  * The two bytes represent a 16-bit _signed_ integer
>>> You can compare your output with the message version in attached
>>> patch.
>>> If this generates interest and makes some people participate, I'll
>>> disclose my solutions after people submitted their solutions.
>>> _______________________________________________
>>> Pd-list at lists.iem.at mailing list
>>> UNSUBSCRIBE and account-management -> https://lists.puredata.info/l
>>> istinfo/pd-list
>>> _______________________________________________
>>> Pd-list at lists.iem.at mailing list
>>> UNSUBSCRIBE and account-management -> https://lists.puredata.info/listinfo/pd-list
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 16bit-converter-challenge.pd
Type: application/puredata
Size: 11651 bytes
Desc: not available
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20161123/a2383de9/attachment-0001.bin>

More information about the Pd-list mailing list