short answer:
yeah, don’t use integer division.

longer answer:
here’s a really, really quick test [bfin_div.c]

#include <fract.h>

fract32 div256 (int x) {
  return x / 256;
}

fract32 div256_shift(int x)  {
  return x >> 8;
}


fract32 div256_shift_intrinsic(int x)  {
  return shr_fr1x32(x, 8);
}

compiled with bfin-elf-gcc -c bfin_div.c -o bfin_div.o -O3
then disassmebled with bfin-elf-objdump -S bfin_div.o

result:

00000000 <_div256>:
   0:    00 e8 00 00     LINK 0x0;        /* (0) */
   4:    08 30           R1 = R0;
   6:    80 0c           CC = R0 < 0x0;
   8:    06 18           IF CC JUMP 0x14 <_div256+0x14>;
   a:    82 c6 c1 01     R0 = R1 >>> 0x8;
   e:    01 e8 00 00     UNLINK;
  12:    10 00           RTS;
  14:    20 e1 ff 00     R0 = 0xff (X);        /*        R0=0xff(255) */
  18:    41 50           R1 = R1 + R0;
  1a:    82 c6 c1 01     R0 = R1 >>> 0x8;
  1e:    01 e8 00 00     UNLINK;
  22:    10 00           RTS;

00000024 <_div256_shift>:
  24:    00 00           NOP;
  26:    00 e8 00 00     LINK 0x0;        /* (0) */
  2a:    40 4d           R0 >>>= 0x8;
  2c:    01 e8 00 00     UNLINK;
  30:    10 00           RTS;
    ...

00000034 <_div256_shift_intrinsic>:
  34:    00 00           NOP;
  36:    00 e8 00 00     LINK 0x0;        /* (0) */
  3a:    40 4d           R0 >>>= 0x8;
  3c:    01 e8 00 00     UNLINK;
  40:    10 00           RTS;
    ...

so it looks like bfin-elf-gcc is smart enough to replace the constant div with a shift, but it is also doing some checking on negative numbers, because it doesn’t know that the blackfin rshift instruction performs sign-extension (or something.)

IIRC, bfin-elf-gcc is also smart enough to use hardware loop counting in some situations, but not in others. in some i was able to squeeze a couple cycles out of some DSP mix loops by writing them as inline assembly. (in other cases the compiler was smarter than me.) but of course this multiplies the coding time by a large factor. in the current structures, there didn’t seem to be any significant gains. but i’ll consider doing this when refactoring the DSP algos for block processing.

it’s always worth looking at the disassembly for your core DSP loops.

BTW:, i apologize that i haven’t made faster progress on this. winter is always a busy time for NAMM and other reasons. the basic proof of concept for block processing is functional; i’ll get back into extending it in a couple weeks.

4 Likes

Just finished testing/fixing some code to do really loooooong lin/log slews for sample-by-sample processing that can be configured to work with small params. Envelope tracking also works good in the simulator now. None of the new goodies are plumbed in yet.

Time to get aquainted with the dissasembly procedure then hammer on the cubic interpolation routine a bit…

2 Likes

quick update:

wasted a lot hacking time this week chasing down a bug introduced ~wednesday by meddling with already-working code away from the device & not testing properly. Craziness was compounded by the fact I’m now close to aleph cpu bottleneck. Git saved the day! Anyway once everything got back on track:

Transient/noise-burst generator - done but needs a decay control
grain envelope trackers - done but still needs to be routed to patch matrix and an attack control
offsettable pitch tracking oscillators using the already-calculated grain pitch & envelopes - done
input selector for mixer channels 3&4 (currently hardwired to ADC 3&4) - done
Route CV inputs to the mixing matrix. - not done
input-switchable envelope detectors for the CV outs - not done
adjustable lowpass IIR filter on grain output - not done

pretty sure I can add the extra controls without adding cpu load, cautiously optimistic there’s enough left for at least basic CV and not convinced even one more audio IIR filter will fit without an overhaul. Maybe a few cycles can be clawed back by reworking patch matrix as an array of pointers to fract32…

2 Likes

if there’s a version without CV i’m all up for testing :slightly_smiling:

Release imminent! All done apart from CV inputs (need to start my final testing) - didn’t see any example in @zebra’s code using the CV in so that feature will have to wait for now. CV outputs should now be routed directly to the audio patch matrix but don’t have a multimeter/scope here to check (or the right cable to loop CV back into an audio in, or any eurorack to plug into for a test)

Just one bug I really want to fix before release - pitch detection works well but rotating pitch shift head not locking on quite right (reasonably sure it was spot-on before moving to cubic interpolation). once i get to the bottom of that…

Also this thing needs some documentation - it’s not an intuitive/fundamental concept like with waves/lines. More like a digital rube-goldberg machine with some canonical use-cases I guess…

2 Likes

i might regret saying so
but

please dont hold back the release for lack of docs…this sounds incredible so far and i’m dying to mess with update

1 Like

Can we assume stuff like pitch detection can be turned on/off easily? Everything has the possibilities to be manipulated by bees right?
And let’s be honest, the Lines documentation was never exactly ‘extensive’ :slight_smile: just a list of parameter descriptions with hardly any guidance about how to use them and no tutorials.

1 Like

well I hope the new version lives up to expectations! Think the scrubtap locking is solved - I realised you need to lock onto some multiple of the period of half the detected pitch, because there are two read heads in rotating-head pitchshifter. Needs a listen with fresh ears after sleep I could be fooling myself.

There’s another subtle bug with the sampler functionality - when you flip from stalled one-shot to looped playback it comes in without crossfading so there’s a pop. Don’t want to release without a workaround for that…

1 Like

@rick_monster that’s because cv inputs are connected to the avr32, not the blackfin (ADC operator in bees)

Also, don’t connect cv out to audio in!!! :boom:

2 Likes

a cautious ‘yes’ - everything has the possibility to be manipulated by bees but I have only been tweaking params ‘by hand’ for my testing - the list of module params has been totally unstable so far. Didn’t want to put in any time building bees networks that will be incompatible with tomorrows module build.

I disabled much of the parameter slewing in the belief that slews were eating too many cpu cycles. Kind of wondering now which/how many crucial slews I could put back in for controls that can be usefully driven dynamically. Come to think of it there’s still a crucial param missing: bees->patch_matrix. Currently there would be no way to echo CV in -> CV out.

All that said, this thing is inherently less tweakable than e.g lines. Think of it less like modelling clay and more like a spring-loaded-swiss-army-knife-gadget. Started drawing 2 schematics last night - toplevel & internal to each ‘grain’ (grain is now a complete misnomer). Scans of those will go out with the binary release, along with textual parameter descriptions.

2 Likes

thanks for the heads up! kind of thought this was a bit like patching my oakley modules where you can pretty much randomly just plug everything into everything without damage (as long as the speakers aren’t cranked of course). Will have to be careful with the aleph audio ins when I finally get the modular back I guess…

By the way something that has been troubling me and I got a bit lost sifting through source code/docs for a clue - is there any mechanism to shovel data back from module into bees? As far as I could tell the communication between bees network & bfin module is one-way-only…

for example I might want a bees operator that:

  • waits for a trigger input
  • polls the module for some interesting value (e.g current detected pitch)
  • passes on that value to the next operator in the network

or have a module trigger the network on rising/falling edge of an audio gate signal.

yes. avr32 can get parameter values from the blackfin as well as set them.

protocol:
[ https://github.com/tehn/aleph/blob/dev/common/protocol.h#L20 ]

blackfin SPI state machine:
[ https://github.com/tehn/aleph/blob/dev/bfin_lib/src/spi.c#L115 ]

avr32 library function:
[ https://github.com/tehn/aleph/blob/dev/avr32_lib/src/bfin.c#L350 ]

currently, BEES uses this to populate the initial values of DSP parameters after loading a module.
(here: [ https://github.com/tehn/aleph/blob/dev/apps/bees/src/net.c#L980 ] )

but the idea was to use it for analysis parameters as well; they can be polled any time.

i guess we should make a bees operator to do this explicitly.

Since you point out CV ADCs are hooked up to the avr32, the obvious hack is physically patch one of the CV outs back to CV in - that also lets me use BEES to test whether my patch_matrix->CV_out code is hooked up right.

Once module release is out I’ll be keen to work on BEES op for communicating with a connected laptop via osc (lets me trigger sampler or resonators with my existing boomerang-compatible lisp/linux midi looper). Even better - make any BEES param respond to osc from a host laptop/embedded linux device.

If people like the ad-hoc ‘patch matrix’ paradigm in the new module it would be good to formalise that code and integrate with BEES. BEES module for polling analysis params could index the patch matrix. The bfin module should be able to assign namestring for each patch-matrix-index without building that knowledge into bees.

1 Like

< replies moved to linked topics, above >

YES!!! THIS !!! A DREAM!!!

i put a pretty good amount of work into making sure that polling DSP parameters from bees is already easy to do, as described above. the only reason there is not a polling operator already, is that none of the current modules do anything interesting with their param values in realtime. something simple like tracking amplitude and zero crossings, we could implement right now; seems like rick has already done so; maybe he’d be interested in breaking out that functionality to a separate module.

more complicated/useful analysis, like good pitch/timbre detection, needs more groundwork, which is happening in the background (1st step - block processing, nearly done; 2nd step - FFT, i have some bfin-ready code, but needs the block interface; 3rd step - centroid/flatness extraction, i’ve done it before and it just needs a port.) more updates on that next week after the NAMM crunch.

just… bear in mind that BEES can only poll so fast. it is slow compared to the audio rate. for example, if you literallly implement the gate-triggering scheme described above, you will be effectively downsampling your audio gate input from 48khz to 1khz, and might miss a lot of stuff.

1 Like

yup as soon as grains module docs & binary release are done I can very quickly break amplitude/pitch detection dsp blocks from grains into a trivial analysis-only module for SPI testbench…

3 Likes

cramming in all the features I want is starting to feel impossible without blowing the cpu budget under certain conditions. just rewrote the the patch matrix a bit better and think I made some gains but hammering the sampler functionality really hard still seems to overload the bfin. I need to test with second grain disabled and verify the program logic is definitely correct, and that this is a case of running out of cpu time. Maybe need to refactor so I don’t use fract32 arithmetic where 16 bit would do…

Documentation is done but this module still needs more testing and some optimisations to be release-ready.

1 Like