double densed uncounthest hour of allbleakest age with a bad of wind and a barrel of rain
double densed uncounthest hour of allbleakest age with a bad of wind and a barrel of rain is an in-progress piece for resonators and brass. I’m keeping a composition log here as I work on it.
There are sure to be many detours. Getting it in shape might involve:
- more work on libpippi unit generators & integrating streams into astrid
- testing serial triggers with the solenoid tree & relay system built into the passive mixer
- finishing the passive mixer / relay system and firmware (what to do about the enclosure!?)
- general astrid debugging and quality-of-life improvements…
- composing maybe?
Tuesday April 30th
I’ve been working on the external bits of the system now, which I’m a bit worried about being able to finish by mid-June… it’s coming along though. I think I’m going to try to fit everything into a project box I got a while back that’s maybe just big enough to fit:
- The 12v power supply (battery powered & rechargeable!) for the mixer, solenoids and motors (fingers crossed it’s up to the task)
- The arduino mega and the solenoid driver board
- The amplifier board(s) for the exciters
- Five (!) arcade buttons
- A mess of switches and knobs
- The spring tab terminals for the solenoids, motors, and speaker hookups
- Maaaybe a board and I/O with some opamps for basic buffered line level mixing…
I donno, we’ll see. If all I can fit are hookups and controls for the solenoids and 4 channel amp, that’s OK!
Nice to see them back in action again tho. I still haven’t sorted out my transistor board issue but I found a neat one for $10 on adafruit and it’s working great now that I’ve sorted out the inevitable bone-headed wiring mistake. :-)
Update: the voltage drop from the thinner wires is indeed noticeable! I’m actually out of hookup wire amazingly (only took 4 years! :-p) but some more is on the way to make all four as snappy as the first.
Friday April 26th
Astrid is much less leaky now – I wasn’t munmapping the memory
segments that are created to send buffers to the mixer so they were just
piling up and eventually filling /dev/shm
.
There are still some more leaks to fix somewhere tho!
Meanwhile, I’m playing around with adding some beepers into the rain setup…
Edit: they’re a lot of fun to play with as tactile objects.
Sunday April 21st
There’s that memory leak! This little improv is silly but I’m pretty excited that the input sampler is working again in the python instruments. That pesky (and big! bigger than I thought – it ate up all my memory really fast doing lots of renders like this) memory leak is next up.
Saturday April 20th
Slogging along again on the new shared memory sampler – it’s coming along though. I discovered that some weird issues I was having (where sometimes the sampler would copy frames into the ADC and sometimes… blow up with -nan values getting written into the sampler) was – no surprise! – because of some goofs I made in the circular buffer implementation. Some classic writing beyond the boundary situations because I was wrapping on frames instead of samples.
The sampler is sampling! It’s a lot of fun to play with, and feels pretty responsive. I’ll be curious if there’s any noticeable latency with the python instruments, I haven’t tested them again since fixing the overflow bug.
In the meantime though, I’m leaking file descriptors somewhere and after sending 1,024 renders for playback the program blows up again complaining of “too many open files”.
I’m not sure where it’s happening yet, I’m closing all the file
descriptors that get opened with shm_open
, but unlinking
the memory regions is still leaving them dangling… so something is
holding on to a reference somewhere I guess.
I tried out valgrind with the --track-fds=yes
flag but
it isn’t reporting anything… my suspicion is I’m keeping a reference
open to the shared memory segment somewhere and those calls to unlink
the segments are piling up without actually doing anything? I don’t
really know! That’s the current mystery.
update: Well, haha – I did have one dangling unclosed file descriptor. I love it when the mysteries amount to: look again, dummy. The sampler has been chugging along for a few hours now, but seems to be leaking memory…! It’s a slow leak, but some more time with AddressSanitizer is up next I guess.
Wednesday April 17th
Technical processes and conceptual ideas just like individual musical ideas and passages are not sufficient to be an end in itself. On the contrary it is the way that all these elements interact with and are connected to one another that creates a musical result which – transcending stylistic conventions – is in the position to cultivate its own physiognomy, while at the same time remaining ever versatile and – as Im Januar am Nil still shows 30 years later – surprisingly original and new.
Took a detour to finish writing something, but more boring astrid developments will be forthcoming soon… (And maybe some interesting ones, once I push past this current plumbing stage with the shared memory sampler?)
Friday April 5th
It’s been a week of spring cleaning in the astrid world. Lots of
unremarkable cleanup, though I ended up getting bit by garbage-collected
cython strings when I realized that I was passing the instrument name to
astrid_instrument_start
as pointer to a garbage-collected
string. Moving the instrument initiation into the main thread and
passing the wrapped cython Instrument
to the message thread
let me simplify things a bit too, the python and C instruments both call
the same astrid_instrument_tick
function in the main thread
now, which reads a line from the console, relays parsed commands as
messages on the instrument queues, and cleans up spent buffers in shared
memory.
Some remaining plumbing tasks that come to mind:
Use the same serialization routines for async renders in C routines. This is just because it’s waaaaaay easier to debug memory issues with gdb, valgrind and AddressSanitizer using a simple test C instrument that calls the same functions as the python instruments. I want to make sure I’m not leaving dangling resources in the new shared memory interfaces. (I fell asleep to the pulsar test program last night and woke up to kernel messages saying there were too many open files, so something is def not closing a reference somewhere.)
Test out sending serial messages via the trigger / sequencer callbacks. I’d really like to use this for rain and the serial messaging stuff isn’t exposed completely to python yet.
Probably add a DC blocker to the ADC ringbuffer so I don’t have to worry about blowing things up when jack ports aren’t connected etc.
Make sure the python instruments are actually getting samples back from the ADC now. Looks like it! But I just got it running silently at the coffeeshop this morning, so who knows.
Other stuff, I’m sure!
Monday April 1st
Hey, it’s April!
In astrid-land, I’m still debugging issues with the new
lpsampler
interfaces and working on getting the ADC
sampling interface working in the python instruments. The (mostly
stupid, as usual) issues with the shared memory backing are mostly
sorted and libpippi buffers are now using flexible array members as
their last elements.
At the moment I’m trying to avoid more copies and allocations when reading from the sampler in cython. Pippi’s SoundBuffers are still numpy-backed Note 0 and I don’t think there’s any safe way to avoid all copies until they’re libpippi-backed…
I’m trying out creating the numpy array that will be used to back the
output buffer from the sampler first, then (hopefully) giving C a
pointer to the underlying memory there to fill the buffer, and just
wrapping it back into a SoundBuffer
at the end. In other
words copying once into a new array whose memory is managed by
numpy.
The fiddly bits in the middle are where I’m stuck this morning.
The cython docs show this way of getting a pointer to a memoryview:
the_memoryview: cython.double[::1] = numpy_array # this must already be C contiguous / typed as a double
some_c_function_that_wants_a_pointer(cython.address(the_memoryview[0]))
Pippi uses numpy ndarrays typed as double[:,:]
at the
moment. It makes working with arbitrary numbers of channels easier since
you can slice across dimensions and just operate on one channel at a
time without an extra copy for example… but I’m stumbling over the
reshaping here, it might not be possible to get the pointer directly
without another copy?
Allocating a temporary array in the right shape, copying the samples
into it through the C call, and then copying it back into the
double[:,:]
-shaped numpy array is the best idea I have
right now.
It’s fine! I don’t care much about the extra copies I guess, but getting rid of them is probably a project for another time. Once the sampler works the fun stuff can begin: pushing brass tones through astrid into resonators.
Note 0: There are a lot of places where pippi assumes that
SoundBuffer
s have a frames
param which is the
numpy array, and that gets used to do things with the python buffer API
interfaces. The new buffers are backed by libpippi
lpbuffer_t
structs and expose the buffer API directly on
the object – that’s probably the last big pippi project before I take it
out of beta, whatever that means.
Log March 2024
Log February 2024
Log January 2024
Log December 2023