8-bit looper objects
sptnk/looper/play.axo
sptnk/looper/pos.axo
sptnk/looper/record.axo
sptnk/looper/protect.axo
sptnk/looper/endpos bpm.axo
sptnk/looper/pos2phase.axo
sptnk/looper/pos2ppq.axo
Help file: 4x8bit looper.axh
These objects take advantage of arm functions to write 4 tracks (based on 8-bit packets) on a 32 bit table.
This allows, using all 8 MB of sdram memory, approx 43 seconds per track of playback (for a total of 172 seconds of playback)
The principle behind it:
A 32 bit variable looks something like this: 11001010 11101001 01000111 00001001 (That's -890681591 in binary).
You can think a 32 bit number as an array of 4 8-bit numbers, in this case word1 = 11001010 = ; word2 = 11101001 = -54; word3 = 01000111 = 100; word4 = 00001001 = 9.
It is then possible to use a 32bit table, which is simply a big collection of 32bit variables, to store 4 tracks.
The headroom for such 8-bit tracks is of course much smaller compared to 16bit or 32 bit tracks, but my aim was to obtain a cheap sounding looper (for a higher quality one i'd reccomend checking rbrt's one).
Quickstart: load a table/alloc 32b sdram, call it whatever you want. You can calculate the maximum recording length (per track, in seconds) dividing size by 48000.
Load the other objects in the series, patch them up and write in their boxes the name of the 32bit table.
looper/pos: Pos output provides a driving counter for looper/play and looper/record . The counter increments of 1 for each s-rate cycle, without skipping numbers. This is required to avoid horrible sounds to be recorded. The counter loops around start and end position.
The start and end position are outputted by startpos and endpos outlets.
Play inlet makes the counter go. If play goes to zero, the counter resets. You can pause the playback with hold inlet.
Soo..
Play = 1 Hold = 0 -> counter goes
Play = 1 Hold = 1 -> counter pauses
Play = 0 Hold = 0/1 -> counter stays stopped and goes back to 0
You can do further operations on the loop: multiply it by a fraction (which is numerator/ denominator) and offset it by a factor (mulstart)
This is, by the way, how startpos and endpos are calculated.
looper/protect:
Generates an input for the looper/record object's protect inlet.
You can connect ctrl/toggle objects to i1, i2, i3 and i4 inlets. When an input is activated, the corresponding track is protected from editing.
For example if you protect tracks 1 and 3, the output is -16711936, which corresponds to binary 11111111 00000000 11111111 00000000 .
You can see that ones mean protected, and zeros mean unprotected (so tracks 2 and 4 will be edited, while 1 and 3 will be left untouched).
There are 4 displays to show which track is protected and which is not.
You can override this object and provide a specialized bitmask to distort the sound.
looper/record
Allows to record 4 tracks in the 32 bit table. The track inputs are w1, w2, w3, w4, they are saturated to normal range. Pos must be connected to looper/pos object, in order to avoid clicking.
Mode input must be connected to a ctrl/i radio 8 object or something like that (ctrl/i, sel/sel i ... etc )
When mode is set to 0 no input is recorded
Mode = 1 erases the table at current position
Mode = 2 overwrites the table
Mode = 3 overdubs the table (sums input and table value)
Mode = 4 overdubs the table and halves the value (so you can avoid clipping)
Protect allows to protect some bits of the table (and therefore not edit/erase them)
looper/play:
reads the table at pos position and outputs 4 tracks. You should connect pos to looper/pos object, however you can provide a phase input with an lfo object to play back at different speeds.
looper/length bpm:
Allows to generate a correct length number for looper/pos object.
You can insert a bpm value up to decimal precision, and specify the number of quarters for the loop.
There are two displays in the object: length outputs the approximate length (in seconds) of the loop. Warning warns you if the calculated endpos is bigger than the table length.
The object outputs also the number of quarters of the loop. (will be used to generate 24ppq and 4ppq sync signals)
looper/pos2phase:
Takes in input position, startpos and endpos of the loop and outputs a phasor wave (k-rate) that goes from 0 to 2^27. Can be used as a position reference, or to drive other objects.
looper/pos2ppq:
Kinda like the previous object (same inlets), but outputs a position in 24ppq or 4ppq, to sync other objects to the looper.
Performance considerations:
The help file for the objects (which is a more or less functional looper by itself) uses 7% dsp and the block length of the patch is 7620 (although i expect these numbers to rise with a more populated object pool).
At 88 bpm you can record 64 quarters (16 bars) of music. 4 tracks mono or 2 tracks stereo. The theoretical dynamic range, however is 49.92 dB
For comparison, rbrt's 4 slot loopstation uses 15% dsp load, and the block length of the patch is 16740 (however the patch is much more complex and crammed of logic objects).
Recording at 16bit allows for half of the length, though with 98.08 dB theoretical dynamic range (which really cuts down noise and gives life to transients).