jamshark70's code

Command-line SC utility for MIDI clock out

27 Dec'21 05:52 in midisyncclock

When sending MIDI clock out at a fast tempo, there may be fewer than 10 ms between clock ticks. If you're sending the clock messages from the same sclang that is sequencing musical events, any unexpectedly long-running sclang activity could cause clock messages to be delayed, interfering with timing. One solution is to run the MIDI clock in a separate sclang instance, and sync to the main sclang instance using LinkClock. Command-line: sclang path/to/thisUtility.scd deviceMatch tempo Both parameters, after the code file path, are optional. You can change them in a GUI later. 'deviceMatch' is a partial string match for the MIDI output device. 'tempo' is a float, for BPM. When you click the button next to the device menu, it will wait until just before the next bar line, and then send a MIDI clock start message, and start running ticks on the downbeat. This has been battle-tested in a pub live jam, driving a Digitakt, for an hour without glitches. Note that the MIDI '.connect' stuff is for Linux. You might need to tweak this for Windows or Mac.

GUI: Time-domain continuous vs sampled signals, and FFT representation

Here's a demo I cooked up for a synthesis theory class. Textbooks say that the Nyquist theorem proves there is one only one way to draw a band-limited continuous signal through a set of samples. This GUI lets you see it for yourself. In the multislider for the samples, you can set the sample values arbitrarily and watch the 16x oversampled curve change. (Set only one point, all others 0, and you see a band-limited impulse AKA sinc function. Or, you can programmatically put in a geometrically perfect sawtooth or pulse wave, and see the Gibbs effect.) Or you can adjust the cosine partials' magnitudes and phases directly. And, turn up the volume and listen to the wavetable. If you read the code, you can pick up a lot of tricks for manipulating FFT data on the client side. For instance, I'm doing the 16x oversampling by expanding a 32-point FFT out to 512 points (inserting zeros in the middle, so that the 12th partial is still the 12th partial). The trick that wasn't obvious at first is that the phases of the top half of an FFT (the frequency-aliased mirror image) are inverted. Tricks like that.

Stereo phase scope

31 May'19 08:56 in guistereophaseanalyzer

Very quick-and-dirty hack to show stereo phase. Center = up (12:00). Full left = 10:30, full right = 1:30.

Demo of Model-View-Controller design


This question comes up often: What is the best way to structure GUI code. IMO, Model-View-Controller (when done correctly) gives you the most flexibility while avoiding common bugs. But it's hard to wrap your head around it first. So, here's a quick example using NodeProxies. - Model: This is the thing that is actually doing the work. Here, it's a control proxy representing a frequency value. When something interesting happens in the model (e.g., the frequency changes), it should broadcast a notification (in SC, using the '.changed' method). NodeProxy already does this internally (which is why I'm using it for this example!). - View: The GUI display -- a Slider, in this case. The view knows who its model is, and should respond to user action by updating the model. - Controller: An object that receives notifications from the model and communicates with the view. This SimpleController object is looking for '\source' notifications, and changes the view's displayed value. Benefits: You can make as many views as you want, on the same model, and their separate controllers all receive the notifications and keep everything in sync *without* having to manage exponentially-increasing connections. You can set the model programmatically and all views automatically update. Drawbacks: The model needs to send notifications. Sometimes it's hard to anticipate which notifications will be needed. Bugs can be hard to track down (but when each component is doing its job correctly, it ends up being easier to maintain).

Decode %hex encoded characters

A quick utility function for decoding UTF-8 characters in %hex codes (such as for web URLs). Save the code into a .sc file in your Extensions/ directory, recompile, and then: "%E5%A4%A7%E5%AE%B6%E5%A5%BD".decodeHex; -> 大家好 This probably works only for UTF-8. SC can save the individual bytes of Unicode characters into String objects, and the IDE will print UTF-8 code points correctly, but there is no way to switch the IDE to other Unicode variants.