Set of simple generic utilities (type check, common math functions, etc.)
npm install @ircam/sc-utilsSimple generic utilities (type check, common math functions, etc.)
```
npm install --save @ircam/sc-utils
* [almostEqual][1]
* [almostEqualArray][2]
* [atodb][3]
* [counter][4]
* [dbtoa][5]
* [decibelToLinear][6]
* [decibelToPower][7]
* [delay][8]
* [exponentialScale][9]
* [frequencyToMidi][10]
* [ftom][11]
* [getTime][12]
* [hertzToNormalised][13]
* [idGenerator][14]
* [isBrowser][15]
* [isDefined][16]
* [isFunction][17]
* [isNumber][18]
* [isPlainObject][19]
* [isSequence][20]
* [isString][21]
* [isTouchDevice][22]
* [isTypedArray][23]
* [isURL][24]
* [linearScale][25]
* [linearToDecibel][26]
* [logarithmicScale][27]
* [midiToFrequency][28]
* [modulo][29]
* [mtof][30]
* [normalisedToHertz][31]
* [normalizedToTableScale][32]
* [powerToDecibel][33]
* [sleep][34]
* [tableToNormalizedScale][35]
Checks if two numeric values are approximately equal within a given
tolerance.
* value [number][36] The first value to compare.reference
* [number][36] The second value to compare.tolerance
* [number][36] The tolerance withinNumber.EPSILON
which the values are considered equal.
Note: tolerance must take into account the sum of all relative and
absolute errors. (optional, default )
`javascript`
import { almostEqual } from '@ircam/sc-utils';
almostEqual(0.1 + 0.2, 0.3); // true
almostEqual(0.1 + 0.2, 1e-18); // false
almostEqual(0.1, 0.11, 0.02); // true
Returns [boolean][37] Returns true if the values are approximatelyfalse
equal, otherwise .
* See: [almostEqual][1]
Checks if two arrays of numeric values are approximately equal element-wise
within a given tolerance.
* value [Array][38]<[number][36]> The first array to compare.reference
* [Array][38]<[number][36]> The second array to compare.tolerance
* [number][36] The tolerance within which theNumber.EPSILON
values are considered equal.
Note: tolerance must take into account the sum of all relative and
absolute errors. (optional, default )
`javascript`
import { almostEqualArray } from '@ircam/sc-utils';
almostEqualArray([0.1, 0.1 + 0.2], [0.1, 0.3]); // true
Returns [boolean][37] Returns true if the arrays have got the same size, andfalse
if every value of the same index are approximately equal. Otherwise .
Convert a linear gain into dB
Alias: linearToDecibel
* val [number][36] Value to convert
`javascript`
import { atodb } from '@ircam/sc-utils';
atodb(0);
// > 1
Returns [number][36]
Create a counter function.
* from [number][36] Start of the counter, included (optional, default 0)to
* [number][36] End of the counter, included (optional, default Number.MAX_SAFE_INTEGER)step
* [number][36] Increment / decrement step, if 0 returns from forever (optional, default 1)
`javascript`
import { counter } from '@ircam/sc-utils';
const myCounter = counter(0.1, 0.3, 0.1);
counter(); // 0.1
counter(); // 0.2
counter(); // 0.3
counter(); // 0.1
Returns [Function][39]
Convert a dB into linear gain
Alias: decibelToLinear
* val [number][36] Value to convert
`javascript`
import { dbtoa } from '@ircam/sc-utils';
dbtoa(0);
// > 1
Returns [number][36]
Convert a dB into linear gain (i.e. gain)
Alias: dbtoa
* val [number][36] Value to convert
`javascript`
import { decibelToLinear } from '@ircam/sc-utils';
decibelToLinear(0);
// > 1
Returns [number][36]
Convert a dB into power gain
* val [number][36] Value to convert
`javascript`
import { decibelToPower } from '@ircam/sc-utils';
decibelToPower(0);
// > 1
Returns [number][36]
Wait for a given number of milliseconds.
See also sleep
* ms [Number][36] Number of milliseconds to wait
`javascript`
import { delay } from '@ircam/sc-utils';
// wait for 1 second
await delay(1000);
Returns [Promise][40]
Create an exponential scale function.
* inputStart [number][36] Start value of input rangeinputEnd
* [number][36] End value of input rangeoutputStart
* [number][36] Start value of output rangeoutputEnd
* [number][36] End value of output rangebase
* [number][36] Base value for exponential scaling, default to 2 (optional, default 2)clip
* [boolean][37] Clip output to output range, default to false (optional, default false)
`javascript`
const { exponentialScale } = utils;
const midiToFreq = exponentialScale(69, 81, 440, 880);
midiToFreq(57);
// > 220
Convert a frequency in Hz to a MIDI note
* freq [number][36] Frequency to convert
`javascript`
import { frequencyToMidi } from '@ircam/sc-utils';
const freq = frequencyToMidi(440);
// > 69
Returns [number][36]
Convert a frequency in Hz to a MIDI note
Alias: frequencyToMidi
* freq [number][36] Frequency to convert
`javascript`
import { ftom } from '@ircam/sc-utils';
const freq = ftom(440);
// > 69
Returns [number][36]
Provide a unified clock in seconds accross platforms, with an origin defined by
the start of the process.
`javascript
import { getTime } from '@ircam/sc-utils';
setInterval(() => {
const now = getTime();
// ...
}, 1000);
`
Returns [number][36]
Convert a frequency in Hertz to a normalised one in \[0, 1].
Normalised frequency of 1 is half the sample-rate (Nyquist frequency).
* frequencyHertz [number][36] Frequency in Hertz to convertsampleRate
* [number][36] Twice the Nyquist frequency (optional, default {})
* sampleRate.sampleRate (optional, default 2)
`javascript`
import { hertzToNormalised } from '@ircam/sc-utils';
hertzToNormalised(12000, {sampleRate: 48000});
// > 0.5
Returns [number][36]
Create a iterator of incrementing ids
DEPRECATED Use the more generic and user friendly counter instead.
`javascript`
import { idGenerator } from '@ircam/sc-utils';
const generator = idGenerator();
const id = generator.next().value
Returns Iterator
Check if the platform is a browser or a node process
`javascript`
import { isBrowser } from '@ircam/sc-utils';
isBrowser();
// > true|false
Returns [boolean][37]
Check if the value is defined.
* val any Value to check
`javascript`
import { isDefined } from '@ircam/sc-utils';
isDefined(42); // true
isDefined(undefined); // false
isDefined(); // false
isDefined(null); // true
isDefined(NaN); // true
isDefined(0); // true
Returns [boolean][37]
Check if the value is a function
* val any Value to check
`javascript`
import { isFunction } from '@ircam/sc-utils';
isFunction(() => {});
// > true
Returns [boolean][37]
Check if the value is a number, including Infinity.
If you want to excluse Infinity, check the native Number.isFinite function
* val any Value to check
`javascript`
import { isNumber } from '@ircam/sc-utils';
isNumber(42);
// > true
Returns [boolean][37]
Check if the value is a Plain Old Javascript Object (POJO)
* val any Value to check
`javascript`
import { isPlainObject } from '@ircam/sc-utils';
isPlainObject({ a: 1 });
// > true
Returns [boolean][37]
Check if the value is a sequence (Array or TypedArray) of finite numbers
* val any Value to check
`javascript`
import { isSequence } from '@ircam/sc-utils';
isSequence([1, 2, 3]);
// > true
Returns [boolean][37]
Check if the value is a string
* val any Value to check
`javascript`
import { isString } from '@ircam/sc-utils';
isString('test');
// > true
Returns [boolean][37]
Check if the device supports touch events
`javascript`
import { isTouchDevice } from '@ircam/sc-utils';
isTouchDevice();
// > true|false
Returns [boolean][37]
Check if the value is a TypedArray
* val any Value to check
`javascript`
import { isTypedArray } from '@ircam/sc-utils';
isTypedArray(new Float32Array([1, 2, 3]));
// > true
Returns [boolean][37]
Check if the value is a valid URL
* url val
* any Value to check
`javascript`
import { isURL } from '@ircam/sc-utils';
isURL('http://sub.my-site.org/abcd?test=123');
// > true
Returns [boolean][37]
Create a linear scale function.
* inputStart [number][36] Start value of input rangeinputEnd
* [number][36] End value of input rangeoutputStart
* [number][36] Start value of output rangeoutputEnd
* [number][36] End value of output rangeclip
* [boolean][37] Clip output to output range, default to false (optional, default false)
`javascript`
import { linearScale } from '@ircam/sc-utils';
const myScale = linearScale(0, 1, 50, 100);
myScale(0.5);
// > 75
Returns [Function][39]
Convert a linear gain into dB
Alias: atodb
* val [number][36] Value to convert
`javascript`
import { decibelToPower } from '@ircam/sc-utils';
decibelToPower(0);
// > 1
Returns [number][36]
Create a logarithmic scale function.
* inputStart [number][36] Start value of input rangeinputEnd
* [number][36] End value of input rangeoutputStart
* [number][36] Start value of output rangeoutputEnd
* [number][36] End value of output rangebase
* [number][36] Base value for logarithmic scaling, default to 2 (optional, default 2)clip
* [boolean][37] Clip output to output range, default to false (optional, default false)
`javascript`
const { logarithmicScale } = utils;
const freqToMidi = logarithmicScale(440, 880, 69, 81);
freqToMidi(220);
// > 57
Convert a MIDI note to frequency
* midiNote [number][36] MIDI Note to convert
`javascript`
import { midiToFrequency } from '@ircam/sc-utils';
const freq = midiToFrequency(69);
// > 440
Returns [number][36]
* See: [https://en.wikipedia.org/wiki/Modulo][41]
Calculates the modulo operation with an optional offset.
* value [number][36] The value to apply the modulo operation to.modulus
* [number][36] The modulus divisor.offset
* [number][36] Optional offset to apply before and after the modulo operation. (optional, default 0)
`javascript`
modulo(-1, 360); // returns 359
modulo(1, 360); // returns 1
modulo(-1, -360); // returns -1
modulo(1, -360); // returns -359
`javascript`
modulo(-1, 360, -180); // returns -1
modulo(1, 360, -180); // returns 1
modulo(-1, -360, 180); // returns -1
modulo(1, -360, 180); // returns 1
Returns [number][36] The result of the modulo operation adjusted by the offset.
without offset:
result in \[0, modulus] for modulus > 0
result in \[modulus, 0] for modulus < 0with offset:
result in \[offset, offset + modulus] for modulus > 0
result in \[modulus + offset, offset] for modulus < 0
Convert a MIDI note to frequency
Alias: midiToFrequency
* midiNote [number][36] MIDI Note to convert
`javascript`
import { mtof } from '@ircam/sc-utils';
const freq = mtof(69);
// > 440
Returns [number][36]
Convert a normalised frequency, in \[0, 1], to a frequency in Hertz.
Normalised frequency of 1 is half the sample-rate (Nyquist frequency).
* frequencyNormalised [number][36] Normalised frequency to convertsampleRate
* [number][36] Twice the Nyquist frequency (optional, default {})
* sampleRate.sampleRate (optional, default 2)
`javascript`
import { normalisedToHertz } from '@ircam/sc-utils';
normalisedToHertz(0.5, {sampleRate: 48000});
// > 12000
Returns [number][36]
Create a scale function that returns a linearly interpolated value from the given
transfert table according to the given normalized position.
* transfertTable [Array][38]<[number][36]> Sequence of finite numbers to use as lookup table
`javascript`
import { normalizedToTableScale } from '@ircam/sc-utils'
const scale = normalizedToTableScale([1, 2, 4])
scale(0); // 1
scale(0.25); // 1.5
scale(0.5); // 2
scale(0.75); // 3
scale(1); // 4
Returns [function][39]
Convert a linear gain into dB
* val [number][36] Value to convert
`javascript`
import { decibelToPower } from '@ircam/sc-utils';
decibelToPower(0);
// > 1
Returns [number][36]
Wait for a given number of seconds.
See also delay
* sec [Number][36] Number of seconds to wait
`javascript`
import { sleep } from '@ircam/sc-utils';
// wait for 1 second
await sleep(1);
Returns [Promise][40]
Create a scale function that returns a normalized position in the transfert
table according to the given value.
* transfertTable [Array][38]<[number][36]> Sequence of finite numbers to use as lookup table
`javascript``
import { tableToNormalized } from '@ircam/sc-utils'
const scale = tableToNormalized([1, 2, 4])
scale(1); // 0
scale(1.5); // 0.25
scale(2); // 0.5
scale(3); // 0.75
scale(4); // 1
Returns [function][39]
[1]: #almostequal
[2]: #almostequalarray
[3]: #atodb
[4]: #counter
[5]: #dbtoa
[6]: #decibeltolinear
[7]: #decibeltopower
[8]: #delay
[9]: #exponentialscale
[10]: #frequencytomidi
[11]: #ftom
[12]: #gettime
[13]: #hertztonormalised
[14]: #idgenerator
[15]: #isbrowser
[16]: #isdefined
[17]: #isfunction
[18]: #isnumber
[19]: #isplainobject
[20]: #issequence
[21]: #isstring
[22]: #istouchdevice
[23]: #istypedarray
[24]: #isurl
[25]: #linearscale
[26]: #lineartodecibel
[27]: #logarithmicscale
[28]: #miditofrequency
[29]: #modulo
[30]: #mtof
[31]: #normalisedtohertz
[32]: #normalizedtotablescale
[33]: #powertodecibel
[34]: #sleep
[35]: #tabletonormalizedscale
[36]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
[37]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[38]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array
[39]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function
[40]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise
[41]: https://en.wikipedia.org/wiki/Modulo