Pi Pico

So I got a cheap Pi Pico as the postage and packaging were more expensive than adding in a Pi Pico to exceed the minimum free P&P limit. It’s about a 2 MB flash drive with a dual computing core and some simple GPIO. It looks like it can do about 500k sample/s ADC over 3 channels at 12 bits, so some audio project seems like a good idea to try.

It has some Amiga “copper” style coprocessors for IO too, so making a video raster scan is likely easy too. It does have enough power to simulate an 8-bit core with a spare CPU left for other purposes. At 133 Mhz that’s quite an efficient bit of silicon area. A 1980’s super-computer with slightly less vector parallelism and a bigger (smaller) storage media. Bargain!

VCV Rack V2

VCV Rack version 2 was released in the new year and the SDK has also been released. I’m making KRTPluginA available for it (as an update 2.25.27), as it is a simple edit update and making some better documentation. I’m in the process of doing the simple API 2 migration. The text to write though is more of a complex decision.

When the phrase “one line description” bumps into a review platform wanting better and perhaps longer description with “\n” literal line splitting (as there is no tool tip wraping). Basically it’s just adding in tool tips and slightly better description and riddance of some spelling mistakes.

So thinking of what I can do for “Z” as I’m going to call it. Something related to some interesting maths so it gives me a reason to read a bit more.

VCV Rack Again

Now that VCV Rack virtual modular synthesizer has stabalized I tried it out for developing C++ modules to add in to the rack. Haven’t decided on the exact nature of the modules yet (2021-7-14), but it does work for the developer better than the older version. First a full source compile is not required. There still appears to be some issues with control alignment in the module GUI which is auto generated which is easily fixed by adding 28 to the Y coordinate of the control. My advice is leave the control “circles” visible until the actual controls cover where you intend them placed.

KRT Plugin A is the repository. So module A seems to be a filter with some strange DSP and input option for a HPF/LPF ring modulation with a metalic on the corner frequency offsetable from the main Q frequency but with tracking added on independantly. Is this the most fun that can be had with 4-poles? An electronic DSP filter joke. So the test basically works, but some DC on none HPF path, but as HPF is by inverse LPF and DC cancels, there must be some DC injected somewhere. OK, found the obvious error at last. Filter A is finished.

And now polyphonic with SIMD. This makes it about 7 times more efficient. Now has graphics. Developing module μ for calculus purposes, then onto a few other niceties. module μ is finished too. Any errors in the calculus should be reported as this module is about a calculated sound, and errors sounding better are for other modules.

On version 1.2.3 already 😀 as it even took this long to define a suitable versioning number system. At the moment controls are virtually CNC’ed on a grid, and panel graphics are manually kerned (as auto(Tm)ating this is perhaps overkill. v1.3.4 release now include the fat T with some bad disharmony as well as lovely 4th and 5th sync sounds and stuff.

L;D and R are now in planning. And are completed for the 1.6.9 release (2021-07-27). Maybe some speed optimizations and next a more complex module. A nice website is also being made in markdown here as that’s what is expected by default .json tags.

The 1.8.13 release (2021-8-2) includes 8 working modules with the new ones being Ω (a clock distributer with randomness) and V (a VCA triplet). The 1.9.15-rc2 relaease (2021-08-05) includes F a morph filter. Hopefully goes live soon soon when compiled by VCV. The Y gate sequencer is almost ready for 16 channels of triggers.

15 machines up there now (2021-8-19) including some oversampled ones, and some utilities for helping out with problems you didn’t know you had. One minor fix for the F filter will be in the next release, and some slight improvements, plus another 3 modules. 

 

Commander X16

A nice Commodore 64 almost compatible with extensions. Better graphics modes with 128kB of video memory, 512kB of paged system memory, 40kB of main memory, a good emulator, 8 channel FM sound and an FPGA graphics solution.

Good 6502 development tools are available and the ROMs are open source. You can buy nice USB keyboards to help support the project. The 8-bit guy does many YouTube videos on classic microcomputer technology. He has good support of the retro community and if it were not for a design constraint of using as much off the shelf older parts then it would be a single chip thing. But part of it is the hands on experience, as the emulator on a Raspberry Pi would work.

The physical hardware is still under construction. As an 8-bit system without an accelerator it is suitable for new code or conversions of old. The main goal is to prevent scrap by the off shelf requirements and make an easier to code for machine than the Pi. One person can understand it all given time.

I’m doing a factor analysis of the hardware docs now to check how I’d use it. I think a scan limited 512 by 448 graphics 4 bits per pixel mode is one I could use for games and other software development. I’m sure a nice palate of colour can be made for the index and offset constraints of the graphics.

It has 16 hardware sprites and more of the system is becoming finalized. The sound was recently tested and works after sorting out some 8MHz timing issues. Some IO is still in design but it is looking good.

Here’s a community site.

As far as tools to look into Millfork, cc65 and the open repositories such as the VSCode plugin are on my list. It’s all looking quite nice. Getting the directory prepared and a suitable subdirectory for the development of a great library and demo template is going to be handy. It can be kind of a clone of the emulator binary directory as this is where the default loading and saving takes place for the emulator.

This will also keep the emulator relevant for the demo, and updates will be easier to not have to fix things without a schedule as could happen if the “latest” emulator was the default. This also manages postponement of “ROM changes” sufficient for not getting sucked into regression or editing other source and having to wait for pull requests to be merged.

The CTRL+SHIFT+P combination for the VSCode command palette gets access to build commands for millfork with the right configuration. This onlt has to be done for the project once, and a blank main.mfk makes a blank main.prg and so it kind of is setup for further progress. Putting all the right things in the git repo helps to keep the path statement unmodified. The settings are enough to get started.

Here is where I intend to put my development tools and first developments as they become what they become. The low memory and low speed of the system makes for some interesting challenge of design and implementation approximations that will be full of creative potential. Nice!

Happy coding.

UPDATE 2019-10-30: Going quite well. The Millfork works well, and after some errors (simple if you know what the compiler is trying to do), mainly obvious for people who have done assembly. It does indicate that context parsing is done after a dead code tree. The next up is likely a bit of colour in the font, and some file loading of a bitmap.

Arduino Fiddling

So I’ve decided on some Arduino soldering over the next few days. Fitting a fiddly SOIC F-RAM and some other components to a prototype shield. It should be fun. Then I have to fit some more code into the 32KB, and then work out a test bed and a box. I’m sure I saw a MIDI device code for the ATMega which does the USB handling. This could be useful later, but I think it does destroy the ability to connect direct with a terminal console.

The F-RAM adds 64KB of slower but fast enough memory to the Arduino, so that more complex projects can be assembled on this prototype. A display is also planned as is some analog pots and a button. Should be fun.

MaxBLEP Audio DSP

TYPE void DEF blep(int port, float value, bool limit) SUB
	//limit line level
	if(limit) value = clip(value);
	//blep fractal process residual buffer and blep summation buffer
	float v = value;
	value = blb[port] - value - bl[((idx) & 15) + 32 * port + 16];//and + residual
	blb[port] = v;//for next delta
	for(int i = 0; i < 15; i++) {
		bl[((i + idx + 1) & 15) + 32 * port] += value * blepFront[i];
	}
	value += bl[((idx) & 15) + 32 * port];//blep
	float r = value - (float)((int16_t)(value * MAXINT)) / (float)MAXINT;//under bits residual
	bl[((idx) & 15) + 32 * port + 16] = value * (blepFront[15] - 1.0);//residual buffer
	bl[((idx + 1) & 15) + 32 * port] += r;//noise shape
	idx++;
	//hard out
	_OUT(port, value - r);//start the blep
RETURN

Yes an infinite zero crossing BLEP. … Finance and the BLEP reduced noise of micro transactions

VCVRack Build 32 Bit

VCVRack is a virtual modular synth which has open source. The build on Windows is 64 bit only. Challenge accepted.

The dependencies to follow on Google Drive. GNU 7.2.0 BUILD. Quite a bit of libs to -lxxx, in the rack Makefile. Fri 15 Sept 2017 13:00 minor ABI build issue janssen. Now fixed and Rack.exe builds. It will need some plugins compiling.

dep32.zip

The main reason for 32 bit is a cheap tablet PC, and the idea of using it for music playing. I also need a source build to develop plugins for it. I also took the opportunity to use libzip 1.3.0 for bz2 support. The build process involved MSYS2 setup, and usual C find the dependency, with a twist of fork of github and a touch of submodule redo. Some file renaming to convince the rest of the build about x86, x64 was par for the job.

Some modules are planned, but the build to link against and test is essential. It’s seriously cool, and my VST coding may migrate. Very easy to build the plugins with little bampf code, very challenging to use the dep make from source. Try the prebuilt app if you have no C experience. I will make 64 bit versions of anything I make, and perhaps a 32 bit bz2 packed version. Maybe BWT/LZW will get into libzip eventually.

The Rack.exe built. I have yet to build modules so no plugins. The effect is ‘nothing happens’ not even an error. The .dll files load, as removing them makes errors, which is a good sign of loading.

.EXE (32-bit) – No Plugins Alpha Coolish. Now some GUI and imagination … libRack.a

The bad news is ccmalloc fails when starting up. So performance maybe limited or none. It does allow compiling against the libs to develop plugins, although a final 64 bit build would be needed for tests. A semi useful on the go distro.

I’ve started on a domain specific language to assist in the manufacturing of plugins. It’s built in the C pre-processor, so the output of errors is somewhat archaic. This is not an issue for myself, and word namespaces are currently sorted by having a set of macros in each file. Next I guess is abstracting the coordinate system. The coordinates are now fixed.

There is engineered space for 2 LEDs, 6 sockets and 4 dials in the first generic template. The design to be done involves moving some .png resources to .svg for the future. It will involve some redrawing from some older resources.

Sallen-Key ZDF design

As part of the VST I am producing, I have designed an SK filter analog where the loading of the first stage by the second is removed to ease implementation. This only affects the filter Q which then has an easy translation of the poles to compensate. Implementing it as CR filter simulation reduces the basic calculation. This is then expanded on by a Zero Delay design, to better its performance.

ZDF filters rely on making a better integral estimate of the voltage over the sample interval to better calculate the linear current charge delta voltage. More of a trapezoid integration than a sum of rectangles. There is still some non-linear charge effects as the voltage affects the current. The current sample out now not known, just then needs a collection of terms to solve for it. Given a high enough sample rate, the error of linearity is small. Smaller than without it, and the phase response is flat due to the error being symmetric on the simulated capacitor voltage, and drive, and not just the capacitor voltage.

The frequency to the correct resistive constant is a good match, and any further error is equivalent to a high frequency gain reduction. There is a maximum frequency of stability introduced in some filters, but this is not one of those. Stability increases with ZDF. The double pole iteration is best done by considering x+dx terms and shifting the dx calculation till later. Almost the output of pole 1 is used to calculate most of the output of pole 2 multiplied by a factor, added on to pole 1 result, and pole 2 result then finally divided. These dx are then added to make the final outputs to memorize.

More VST ideas and RackAFX

Looking into more instrument ideas, with the new Steinberg SDK and RackAFX. This looks good so far with a graphical design interface and a bit of a curve on Getting Visual Studio up to the compiling. A design the UI and then some fill in the blanks with audio render functions. Looks like it will cut development time significantly. Not a C beginner tool, but close.

It’s likely going to be an all in one 32 bit .dll file with midi triggering the built-in oscillation and a use as a filter mode too. Hopefully some different connected processing on the left and right. I want the maximum flexibility without going beyond stereo audio, as I am daw limited. The midi control may even be quite limited, or even not supported in some daw packages. This is not too bad as the tool is FX oriented, and midi is more VSTi.

Na, scratch that, I think I’ll use an envelope follower and PLL to extract note data. So analog and simplifies the plugin. Everything without an easy default excepting the DSP will not be used. There is no reason to make anymore VSTi, and so just VST FX will be done.

Looks like everytime you use visual studio it updates a few gig, and does nothing better. But it does work. There is a need for a fast disk, and quite a few GB of main memory. There is also a need to develop structure in the design process.

The GUI is now done, and next up is the top down class layout. I’ve included enough flexibility for what I want from this FX, and have simplified the original design to reduce the number of controllers. There is now some source to read through, and perhaps some examples. So far so good. The most complex thing so far (assuming you know your way around a C compiler, is the choice of scale on the custom GUI. You can easily get distracted in the RackAFX GUI, and find the custom GUI has a different size or knob scale. It’s quite a large UI I’m working on, but with big dials and a lot of space. Forty dials to be exact and two switches.

I decided on differing processing on each stereo channel, and an interesting panning arrangement. I felt inspired by the eclipse, and so have called it Moon. An excellent WebKnobMan is good at producing dial graphics for custom knobs. The few backgrounds in RackAFX are good enough, and I have not needed gimp or photoshop. I haven’t needed any fully custom control views, and only one enum label changing on twist.

Verdict is, cheap at the price, is not idiot proof, and does need other tools if the built in knobs are not enough. I do wonder if unused resources are stripped from the .dll size. There are quite a few images in there. I did have problems using other fonts, which were selectable but did not display or make an error. Bitmaps would likely be better.

The coding is underway, with the class .h files almost in the bag, and some of the .cpp files for some process basics. A nice 4 pole filter and a waveshaper. Likely I will not bother with sample rate resetting without a reload. It’s possible, but if your changing rate often, you’re likely weird. Still debating the use of midi and vector joy controller. There is likely a user case. Then maybe After this I’ll try a main synth using PDE oscillators. It is quite addictive VST programming.

I wonder what other nice GUI features there are? There is also the fade bypass I need to do, and this maybe joined with the vector joy. And also pitch and mod wheel perhaps. Keeping this as unified control does look a good idea. Project Moon is looking good.

Polyphony and Voicing

After designing the filter sections which are to be used in the audio VST under construction, the next thing to decide is the oscillator voicing. The calculation of many voices does consume a large proportion of the CPU resources in any soft synthesizer design. There are various options such as used in organs like top octave generation and clock division, so that in essence at most 12 voices are played, but using different dynamic spectra.

The octave range at about 11 octaves, or upto the 2048th harmonic, makes this approach have some possible issues with harmonic construction.

Implementation of Digital Audio filters

An interesting experience. The choice of FIR or IIR is the most primary. As the filtering is modelling classic filters, the shorter coefficient varieties of IIR are the best choice for me. The fact of an infinite impulse response is not of concern with a continuous stream of data, and coefficient rounding is not really an issue when using doubles. IIR also has the advantage of an easy Sallen-Key implementation, due to the subtraction and re-adding of the feedback component, with a very simple CR processing.

The most interesting choices are to do with the anti-alias filtering, as the interpolation filter, on up-sampling is an easy choice. As the ear is not really responsive to phase, all the effort should be on the pass band response levels, and a good stop band non response. A Legendre or Butterworth are the candidates. The concept of a characteristic sound enters the design process at this point, as the cascading of SK filter sections is conceptually useful to improve the -6 dB response at cut off. This is a trade off of 20 kHz to 22.05 kHz in the alias pass band, and greater attenuation in the above 22.05 kHz infinite stop desire. The slight greater desire of alias attenuation above pass band maximal flatness (for audio harmony) implies the Legendre filter is better for the purpose than Butterworth.

In the end, the final choice is one of convenience. and a 9th order filter was decided upon, with 4 times oversampling. The use of 4 times oversampling instead of 8 times oversampling increases the alias by an octave reduction. This fact under the assumption of at least a linear reduction in the amplitude of the frequency of the generator of an alias frequency, with frequency increase, just requires a -12 dB extra gain reduction in the alias filter for an effective equivalence to 8 times oversampling (the up to and the reflection back down to 6 + 6). The amount of GHz processing also halves. These facts then become constructive in the design, with the bulk alias close to the cut off, and the minor reflected alias-alias limit, not being too relevant to overall alias inharmonic distortion.

A triple chain of 3 pole Legendre filter sections is the decided design. The approximate -9 dB at the corner, allows for slightly shifting up the cut off and still maintaining a very effective stop band. Code reuse also aids in the I-cache usage for CPU effective use.  A single 3 pole Legendre is the interpolation up sample filter. The roll off for not using Butterworth does cut some high frequency content from the maximally flat, hence the concept of maximally flat, but it out performs a Bessel filter in this regard. It’s not as though a phasor or flanger needs to operate almost perfectly in the alias band.

Perhaps there is improvement to be made in the up sampling filter, by post up sample 88.2 kHz noise shaped injection to eliminate all error at 44.1 kHz. This may have a potential advantage to map the alias noise into the low frequencies, instead of encroaching from the higher frequencies to the lower, and for creating the alias as a reduction in signal to noise, instead of at certain inharmonic peaks. The main issue with this is the 44.1 kHz wave fundamental, seen as the amplitude ring modulation of the injected phase noise, by the 44.1 kHz stepped waveform between samples input. The 88.2 kHz “carrier” and the sidebands are higher in frequency, and of the same amplitude magnitude.

But as this is following for no 44.1 kHz error, the 88.2 kHz and sidebands are the induced noise, the magnitude of which is of the order of 1 octave up from the -3 dB roll at the corner, plus approximately the octave for a 3 pole filter, or about 36 dB cut of a signal 3/4 of the input amplitude. I’d estimate about -37 dB at 88.1 kHz, and -19 dB at 44.1 kHz. Post processing with a 9 pole filter, provides an extra -54 dB on down sampling, for an estimate of around -73 dB or greater on the noise. That would be about 12 bit resolution at 44.1 kHz increasing with frequency. All estimates, likely errors, but in general not a good idea from first principals. Given that the 44.1 kHz content would be very small though post the interpolation filter, -73 dB down from this would be good, although I don’t think achievable in a sensible manor.

Using the last filtered sample in as the reference for the present sample filtered in as a base line, the signal at 22.05 kHz would be smoothed. It would have a notch filter effect, by injecting quantization offset ringing noise at 88.2 kHz to cancel 22.05 kHz. The notch would likely extend down in frequency for maybe -6 dB at about 11 kHz. Perhaps in the end it is just better to subtract the multiplied difference between two up sample filters using different sinc spreading of a 1000 and a 1100 sample occupancy zero inter fill. Subtracting the alternates up conversion delta as it were.

There is potentially also an argument for having a second order section with damping factor near 0.68 and corner 22.05 kHz to achieve some normalisation from sinc up-sampling. This adds in an amount of Q such as to peak the filter cancelling the sinc droop, which would be about 3% at 4 times oversampling.

EDIT: Some of you may have noticed that the required frequencies for stable filtering are too high at 4 times oversampling. So unfortunate for the CPU load an 8 times oversample has to be used. The sinc error is less than 1% at this oversample, but still corrected in a similar way, and a benefit of 2 extra poles. Following this by a 0.1 dB 3 pole Chebyshev high pass which has been inverted, gives a reasonable 5 pole up sampling filter. The down sampling filter for code efficiency is a triple instance of the sample inverse Chebyshev, with the corner frequencies slightly offset to produce more individual zeros, and some spreading of the “ringing”. These 9 poles are enough to get the stop band ripple to be lower than a 16 bit resolution. Odd order inverse Chebyshev are essential for the reflected spectra to be continually decreasing in amplitude.

Musical Research

I’ve looked into free musical software of late, after helping out setting up a PC for musical use. There’s the usual Audacity, and feature limited, but good LMMS. Then I found SuperCollider, and I am now hooked on building some new synthesis tools. I started with a basic FM synth idea, and moved on to some LFO and sequencing features. It’s very nice. There is some minor annoyance with the SC language, but it works very well, and has access to the nice Qt toolkit for making GUIs. So far I’ve implemented the controls as a MIDI continuous controller bus proxy, so that MIDI in is easy. There will be no MIDI out, as it’s not that kind of be all thing. I’ve settled on a 32 controls per MIDI channel, and one window focus per MIDI channel.

I’ve enjoyed programming it so far. It’s the most musical I’ve been in a long while. I will continue this as a further development focus.

The situation so far https://github.com/jackokring/supercollider-demos

The last three, are just an idea I had to keep the keyboard as a controller, and make all the GUI connection via continuous controllers only. I’ll keep this up to date as it develops.