[PD] For sample players based on [line~], [vline~], or [phasor~], how can we be sure all samples are being played?

Thomas Grill gr at grrrr.org
Sat May 14 22:39:54 CEST 2016


Hi Miller,
If the time interval given amounts to let's say 64 samples, the target value is reached at sample index 63, that is, before the block boundary. To me that seems conceptually wrong.
In fact, I found it so hard to work with vline~ (and line~) in a predictable and sample-accurate way that i resorted to biquad~ generated ramps in most of my patches.
best, Thomas

--
Thomas Grill
http://grrrr.org



> Am 14.05.2016 um 18:53 schrieb Miller Puckette <msp at ucsd.edu>:
> 
> I believe that vline~ output is more nearly correct than line~.  It
> seems appropriate to pre-increment the output as vline~ and phasor~
> do.  Note that the previous sample was 0, so that there is in fact a ramp
> from 0 to 64 that lasts exactly 65 samples and has a slope of exactly
> (sample rate).
> 
> cheers
> Miller
> 
> 
> On Sat, May 14, 2016 at 07:12:50PM +0900, Jonghyun Kim wrote:
>> I tested it, if I have 64 samples and how it plays back. It's a bit strange
>> to me. I was preferred to use [vline~], but it's incorrect, neither line~
>> does.
>> 
>> akntk
>> 
>> =====
>> 0,    64    1.451247
>> 
>> vline~ outputs
>> vline~:
>> 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
>> 
>> line~ outputs
>> line~:
>> 0  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
>> 
>> 
>> On Fri, May 13, 2016 at 8:17 AM, Thomas Grill <gr at grrrr.org> wrote:
>> 
>>> As a followup on that old thread:
>>> 
>>> - I strongely advice against the use of line~ to drive tabread4~. Under
>>> the hood, it works with single precision, so that the sample positions are
>>> prone to round off errors pretty quickly.
>>> Make the test and send the output of [line~] to [print~]. In the simplest
>>> case of sending a [0, 44100 1000( message to line (and sending a bang to
>>> [print~] at the same time), the output should show incremented sample
>>> positions by exactly one. It is easy to see that the numbers are off
>>> integers quite quickly.
>>> 
>>> - vline~ works with double precision and doesn't show the same numeric
>>> problems, but has a different issue, which i consider a severe bug.
>>> Doing the same as above, the output of [vline~] starts with 1, not with 0 !
>>> This can be circumvented by delaying the output of vline~ by a sample,
>>> e.g. by sending [0, 44100 1000 0.0226757(, but this is certainly a bad
>>> workaround.
>>> 
>>> 
>>> The test patch is this:
>>> 
>>> #N canvas 68 90 450 300 10;
>>> #X obj 26 98 print~;
>>> #X obj 26 16 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144 -1 -1;
>>> #X msg 58 42 0 \, 44100 1000;
>>> #X obj 58 65 line~;
>>> #X text 99 66 or vline~;
>>> #X connect 1 0 2 0;
>>> #X connect 1 0 0 0;
>>> #X connect 2 0 3 0;
>>> #X connect 3 0 0 0;
>>> 
>>> 
>>> --
>>> Thomas Grill
>>> http://grrrr.org
>>> 
>>> 
>>> 
>>>> Am 23.03.2015 um 05:50 schrieb Reed Perkins <reedperkins32 at gmail.com>:
>>>> 
>>>> Hi Jonathan. Thank you for the reply. I still have a question about
>>> something you wrote, with my original question reproduced below:
>>>> 
>>>> 3. Does the output of [line~] and [vline~] vary due to being asked to
>>> generate a ramp faster or slower? If I ask [line~] to go from 0-555987 in
>>> 3789 milliseconds, will the actual output be the same or different if I
>>> then ask [line~] to go from 0-9876545 in 40 milliseconds
>>>> 
>>>> ​You wrote: "I'm not sure what you're asking.  Are you asking whether
>>> the samples output from 0-555987 will be the same in both cases?  If so,
>>> the answer is no.  The [line~] object is outputting floating point numbers
>>> in the range you specify, over the duration you specify, aligned to block
>>> boundaries."
>>>> 
>>>> What I meant to ask is whether or not [phasor~], [line~], and [vline~]
>>> behave the same in terms of outputting sequential values regardless of the
>>> "speed" they are "driven at".
>>>> 
>>>> From what I understand now, if you "drive" [line~] at the speed of the
>>> sample rate, the output should be a steady stream of numbers that increase
>>> by 1 from number to number.​ However, if you try to "drive" [line~]​ at a
>>> speed that is faster or slower than the sample rate, you'll get dropped
>>> samples or duplicated samples, respectively. So in this example:
>>>> 
>>>> [0, 40999 1000( <--jump to 0, then read from 0-40999 in 1000 ms
>>>> |
>>>> [line~]
>>>> |
>>>> [tabread4~ array1] <--where array1 is a size of 41000
>>>> 
>>>>      • If we were to print the output of the first ten ​numbers of
>>> [line~]​, it should look like this: 0,​ ​1, 2, 3, 4, 5, 6, 7, 8, 9​.​​
>>>>      • If we change the time in the message box to 2000, does the
>>> output of line become 0, 0, 1, 1, 2, 2, 3, 3, 4, because we are now taking
>>> twice as long to read through the table?
>>>>      • If we change the time in the message box to 500, does the output
>>> of the [line~] become 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, because now
>>> [line~] has to skip samples in order to reach the end goal of 40999 in time?
>>>> I did some tests using the patch I outlined above using [print~] and
>>> these stipulations seems to hold true. So now I am curious about what
>>> [tabread4~]​ does. For the second scenario I outlined (2000ms time), does
>>> [tabread4~] change 0, 0, 1, 1, 2, 2, 3, 3, 4, 4... into 0, 0.5, 1, 1.5, 2,
>>> 2.5, 3, 3.5, 4, 4.5...? Or in the third scenario (500ms time), does
>>> [tabread4~] change, 0, 2, 4, 6, 8, 10... into 0, 1, 2, 3, 4, 5, 6...?
>>>> 
>>>>>>>> On Sun, Mar 22, 2015 at 10:43 AM, Jonathan Wilkes via Pd-list <
>>> pd-list at lists.iem.at> wrote:
>>>>> On 03/20/2015 12:57 PM, Reed Perkins wrote:
>>>>> 
>>>>> Hello all,
>>>>> 
>>>>> [line~], [vline~], and [phasor~] are used to generate line ramps in
>>> basic
>>>>> sample-playback patches. The output of these objects is usually
>>> multiplied
>>>>> by the total number of samples in a sound file (that has already been
>>> loaded
>>>>> into an array or table) and fed into the input of something like
>>>>> [tabread4~]. In other words, we use these line-ramp objects to
>>> traverse the
>>>>> indices of a table where a sample is loaded at a given speed.
>>>>> 
>>>>> My questions are these:
>>>>> 
>>>>> 1. Do these line-ramps generate enough numbers such that every sample
>>> in a
>>>>> table will be read?
>>>>> 
>>>>> 
>>>>> No.  (And I assume you are wanting the values of the table to be
>>> output one
>>>>> after the other, in sequence, when you output them as a signal.)
>>>>> 
>>>>> The determining factors for how table values are output: a) ramp
>>> duration
>>>>> (in time units), b) ramp height (end value - start value), c) the
>>> sample
>>>>> rate, and d) whether the object doing the reading is interpolating the
>>> index
>>>>> values.
>>>>> 
>>>>> The sample rate in Pd is fixed, so you are only guaranteed to read
>>> every
>>>>> table value when the ratio of ramp height/duration matches the sample
>>> rate
>>>>> ratio.  If you wanted something like [line~] and [tabread~] to
>>> guarantee
>>>>> that every sample of the table is read/output/whatever, you'd need a
>>> system
>>>>> in which the sample rate changes based on the size of the array being
>>> read.
>>>>> 
>>>>> 
>>>>> 2. Does it matter if, say for example, [tabread4~] receives a decimal
>>> number
>>>>> for an index, like 333987.8, which can be caused by multiplying the
>>> output
>>>>> of [phasor~] (which goes from 0-1) by the total amount of samples
>>> (usually a
>>>>> much larger number).
>>>>> 
>>>>> 
>>>>> Yes, because [tabread4~] does interpolation.  The [tabread~] object
>>> does no
>>>>> interpolation so the number after the decimal point in your index
>>> wouldn't
>>>>> make any difference.
>>>>> 
>>>>> For example:
>>>>> 
>>>>> [0 44099 2000(
>>>>> |
>>>>> [line~]
>>>>> |
>>>>> [tabread~ array1] <-- a table of size 44,100
>>>>> 
>>>>> This will output every value of your table twice in a row, because your
>>>>> taking twice as long to read the entire table.  However, that's
>>> probably not
>>>>> what you want, and if you listen to that results vs. [tabread4~],
>>> you'll
>>>>> hear why interpolation is a good thing in this case.
>>>>> 
>>>>> 
>>>>> 3. Does the output of [line~] and [vline~] vary due to being asked to
>>>>> generate a ramp faster or slower? If I ask [line~] to go from 0-555987
>>> in
>>>>> 3789 milliseconds, will the actual output be the same or different if
>>> I then
>>>>> ask [line~] to go from 0-9876545 in 40 milliseconds
>>>>> 
>>>>> 
>>>>> I'm not sure what you're asking.  Are you asking whether the samples
>>> output
>>>>> from 0-555987 will be the same in both cases?  If so, the answer is
>>> no.  The
>>>>> [line~] object is outputting floating point numbers in the range you
>>>>> specify, over the duration you specify, aligned to block boundaries.
>>>>> 
>>>>> 
>>>>> I realize this is totally theoretical, because in all honestly I
>>> wouldn't be
>>>>> able to hear a difference if samples are being skipped, but I want to
>>> know
>>>>> :)
>>>>> 
>>>>> 
>>>>> But you do.  If the sample rate is 44,100 samples per second, and you
>>> read
>>>>> from 0 to 44,099 in one second with [tabread~] you'll hear all the
>>> samples
>>>>> being output.  But if you read from 0 to 44,099 in _half_ of a second
>>> you'll
>>>>> be skipping every other sample.  You'll certainly perceive the
>>> difference as
>>>>> the sound recording going _twice_ as fast.
>>>>> 
>>>>> Essentially, the [tabread4~] object is for those situations where you
>>> know
>>>>> you'll be playing back at a ramp height/duration ratio that doesn't
>>> match
>>>>> the sample rate ratio.  Or where you'll often be speeding up or slowing
>>>>> down.
>>>>> 
>>>>> -Jonathan
>>>>> 
>>>>> 
>>>>> Thanks for your time.
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> Pd-list at lists.iem.at mailing list
>>>>> UNSUBSCRIBE and account-management ->
>>>>> http://lists.puredata.info/listinfo/pd-list
>>>>> 
>>>>> 
>>>>> 
>>>>> _______________________________________________
>>>>> Pd-list at lists.iem.at mailing list
>>>>> UNSUBSCRIBE and account-management ->
>>>>> http://lists.puredata.info/listinfo/pd-list
>>>>> 
>>>> 
>>>> _______________________________________________
>>>> Pd-list at lists.iem.at mailing list
>>>> UNSUBSCRIBE and account-management ->
>>> http://lists.puredata.info/listinfo/pd-list
>>> 
>>> 
>>> _______________________________________________
>>> Pd-list at lists.iem.at mailing list
>>> UNSUBSCRIBE and account-management ->
>>> https://lists.puredata.info/listinfo/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: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.puredata.info/pipermail/pd-list/attachments/20160514/4dc394a2/attachment.sig>


More information about the Pd-list mailing list