This document provides useful information for developers and maintainers of SuperCollider. It's a yellow-pages of sorts.
You can find full information about our git workflow
here. In summary, we use the
git-flow branching model with master
as the stable branch, develop
as unstable, and x.y
branches for release
branches.
We use four tags to keep track of issues:
- Next patch (example: "3.9.1")
- Some patch (example: "3.9.x")
- Next minor (example: "3.10")
- Some minor (example: "3.x")
Patch-milestoned issues are those that will require bug fixes, while minor-milestoned issues are things like new features and major changes that are better left for a minor release. The "Next patch"/"Next minor" milestones mark those issues that we've decided must be addressed before the next respective release. They're either the most painful bugs or most requested features.
When, in the example milestones above, 3.10 is released, we would move all 3.9.x-milestoned issues to 3.10.x, and then collectively decide which issues ought to move from 3.x to 3.11 and from 3.10.x to 3.10.1.
SuperCollider class library deprecations are currently made on a case-by-case basis using the Object:-deprecated
method. When a method or class is deprecated, it is moved to SCClassLibrary/deprecated
. Deprecations are removed on a
case-by-case basis with each minor (3.x) release.
UGens proposed for inclusion in the main SuperCollider project should meet more rigorous standards than those found "in the wild." These are standards the community has agreed upon for new UGens:
- General software quality concerns:
- UGens in core should never break backward compatibility.
- UGens should be fully documented, with a clear explanation of what it does and an appropriate collection of examples. Be sure to document which UGen inputs are modulatable at which rates.
- UGens should be efficient. SuperCollider takes pride in being easy on the CPU, and UGens should help support that reputation.
- The UGen should be deemed useful enough to the general SC user base.
- Each UGen should be in a separate C++ source file (or multiple source files if it's really that long).
- Don't leave any unnecessary print statements lying around.
- Safety:
- Check input rates in the sclang class.
- UGens should be real-time safe. Ross Bencina's ["Real-time audio programming 101"]
(http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing) is required reading.
Here is a quick and incomplete blacklist of dangerous features:
malloc
/free
/new
: useRTAlloc
instead.throw
/catch
: use return codes instead.dynamic_cast
- System calls. These are complicated to handle and require use of an NRT thread.
- Any calls to
RTAlloc
should check the result forNULL
. This usually happens when there isn't enough real-time memory left. The server will crash if this check is not made. - The Ctor sample should be initialized. If this is not done, very nasty bugs can occur.
- Zap dangerous values (subnormals, infinities, nans) in feedback loops to zero. SC provides a
zapgremlins
function that does this for you.
- Utility:
- UGens should have both
.ar
and.kr
methods if applicable. - Sample rate and block size independence should be maintained if applicable. For example, audio UGens shouldn't sound radically different if the sample rate is increased.
- For audio UGens, control-rate inputs should be interpolated if applicable.
- Don't arbitrarily make certain inputs nonmodulatable just for programming convenience -- carefully anticipate what's worth modulating. Either way, don't forget to document it.
- UGens should have both
- Modernization and deprecated features:
- When writing a new UGen from scratch, it is recommended to use the modern C++ style seen in
SC_PlugIn.hpp
. - Don't use
mul
andadd
arguments. These were originally introduced for efficiency, but nowFoo.ar * 2 + 1
gets optimized into aMulAdd
. - Don't use a
doneAction
argument. Set the done flag instead.
- When writing a new UGen from scratch, it is recommended to use the modern C++ style seen in
We have CI provided by AppVeyor (Windows) and Travis (Linux, macOS). If a commit changes only
non-schelp documentation, without renaming, adding, or removing files, you may want to consider
adding [skip ci]
to the commit message so it does not waste CI resources.
Builds of all commits to branches on the main project repository are uploaded to Amazon's S3 hosting service. These
builds are available for macOS, Windows x86, and Windows x86-64. To download the latest build of a branch named
topic/foo
, the URLs are of the form:
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/osx/topic/foo-latest.html
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/win32/topicfoo-latest.html
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/win64/topicfoo-latest.html
Note that for the Windows builds only, the branch name is stripped of forward slashes.
To find a build for a specific commit (assuming it exists), use the full SHA hash of the commit. For example, the binaries for commit 8c3563a8065cb623087f267dfe50e228224a4572 are at:
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/osx/SC-8c3563a8065cb623087f267dfe50e228224a4572.zip
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/win32/SC-Windows-x86-8c3563a8065cb623087f267dfe50e228224a4572.zip
- http://supercollider.s3.amazonaws.com/builds/supercollider/supercollider/win64/SC-Windows-x64-8c3563a8065cb623087f267dfe50e228224a4572.zip
A build for a specific commit may not always be available: for instance, if the build was cancelled early or failed to complete.
Location: external_libraries/extract_boost.sh
, external_libraries/boost_sc_changes.patch
Update Boost libraries packaged with SuperCollider, and apply the SuperCollider organization's patches for Boost.
Should be run as soon as possible after a new release of Boost. See instructions in external_libraries/README_BOOST.md
for more information.
Print verbose debug messages while diagnosing issues with the Qt GUI features.
Only enabled on a debug build.
QtGUI.debugLevel_(0) // 0 = no output, 3 = verbose
Unit testing suite for SuperCollider language core library
If developing on a version older than 3.9.0, download UnitTesting
quark separately. Add the test suite folder to your
SuperCollider compile paths. Recompile. Run UnitTest.runAll
, or run tests from the GUI via UnitTest.gui
.
Rather than manually running appropriate tests after editing a library class or a UnitTest
class, you can use
aspiers/guard-sclang which will watch for file changes and automatically run
tests in reaction to them. The steps to set this up are as follows:
- Make sure you have Ruby installed.
- Make sure you have Bundler installed (usually this is as simple as running
gem install bundler
). - Make sure
sclang
is somewhere on your$PATH
. cd $supercollider_source/tools/guard
bundle install
Now you should be ready to launch Guard via:
bundle exec guard
Then start hacking on SuperCollider classes, and enjoy the immediate feedback!
The mapping between implementation classes and test classes is defined in tools/guard/Guardfile
. This is currently by
far from perfect, because it naively assumes a 1:1 mapping between class Foo
and test class TestFoo
. However it
should be easy to make it more intelligent, even if you don't know Ruby; please feel free to contribute improvements!
Render all schelp documents to HTML to check for warnings and errors.
During configuration, pass -DSC_DOC_RENDER=ON
to CMake. This provides a target called doc
which can be built to
render all schelp documents:
cmake .. -DSC_DOC_RENDER=ON # <other options>
cmake --build . --target doc
qpm is a Python-based Quarks package manager and test runner for SuperCollider. It is used by our CI services to run the SuperCollider-based test suite. See https://github.com/scztt/qpm/tree/qpm-unit for more information.
Location: https://gist.github.com/brianlheim/443ae188dee8f7a85e7f34c04cc66d2b
Converts a changelog in markdown format into schelp format. A little extra work required but saves a lot of tedium. See script for usage.
TODO
To update translation files for the IDE, you'll first need to make sure Qt's lupdate
program is in your path, then
build the update_ide_translations
CMake target. This will overwrite the .ts
files in editors/sc-ide/translations
to reflect the most recent source code.
Use Qt Linguist to update the .ts
files in
editors/sc-ide/translations
. Qt Linguist can be included when you install Qt Creator or a general Qt distribution.
If you can't find the language you want to add translations for, first make sure you have lupdate
and Qt Linguist, then:
- Determine its two-letter language code.
- Add a new filename for it in
editors/sc-ide/CMakeLists.txt
, in the section marked# Translation files
. - Re-run the CMake generation phase (in your
build
directory, executecmake ..
) - Build the
update_ide_translations
CMake target to generate a.ts
file - Add translations using Qt Linguist.
These instructions detail how to add functionality to existing QtCollider widgets (such as TreeView and Knob). Each widget typically corresponds to a single Qt class, and the simplest way to add functionality is by providing access to an existing C++ function of the Qt widget.
- Locate the C++ source for the widget in
/QtCollider/widgets/
. - Add the signature for the function in the header file.
- Add the implementation for the function in the implementation file.
- Locate the SC source for the widget in
/SCClassLibrary/Common/GUI/Base/
. - Add a suitably named new method in the class file that calls down to the QtCollider widget using
invokeMethod
. - Document the method in the corresponding schelp file in
/HelpSource/Classes/
.
Technical note: not all types can be transcoded between SuperCollider and QtCollider widgets. However, all primitive
types, some collection types, and a few class types are supported. The code which controls this can be found in
QtCollider::MetaType::find( PyrSlot * )
.
PR #3560 demonstrates how to do this by adding
setColumnWidth
to TreeView
:
- The C++ files are
/QtCollider/widgets/QcTreeWidget.{cpp,h}
- The function signature is:
Q_INVOKABLE void setColumnWidth( int column, int width );
- The implementation simply calls up to
QTreeView
:
void QcTreeWidget::setColumnWidth( int column, int width )
{
QTreeWidget::setColumnWidth( column, width );
}
- The SC file is
/SCClassLibrary/Common/GUI/Base/QTreeView.sc
- The new method simply forwards arguments to
invokeMethod
:
setColumnWidth { arg column, width;
this.invokeMethod( \setColumnWidth, [column, width] )
}
- The documentation is added to
/HelpSource/Classes/TreeView.schelp
:
METHOD:: setColumnWidth
ARGUMENT:: column
The integer index of the column to modify
ARGUMENT:: width
Integer width in pixels
.github
: PR and issue template for GitHub.travis
: scripts for Travis CIcmake_modules
: Find and Config modules for CMakecommon
: C++ files needed by multiple components of the projecteditors
: Files forscide
and editor extensionssc-el
: the SuperCollider Emacs package,scel
sc-ide
: source forscide
sced
: source for the SuperCollidergedit
plugin,sced
scvim
: the SuperCollider Vim package,scvim
examples
: SuperCollider code examples, packaged into release assetsexternal_libraries
: C and C++ third-party librariesboost
: root of Boost C++ sourcesboost_sync
: contains Boost::sync, a synchronization lib which was never integrated into Boost proper.hidapi
: HID API project, whichsclang
uses for HID capability. Our fork is significantly patched for cross-platform compatibility.icu
: IBM's ICU libraryjackey
: a simple header for Jack that makes working with Jack Metadata easier. Used byscsynth
andsupernova
, but not in current builds (only whenSC_JACK_USE_METADATA_API
is defined, may be old work that was never completed)libsndfile
: header forlibsndfile
, for working with audio file formats. Used bysclang
and the serversnova-simd
:nova-simd
, a framework for SIMD vector functionsnova-tt
:nova-tt
, a library for cross-platform thread synchronizationoscpack_1_1_0
: Oscpack, a library for working with OSC packets.portaudio_sc_org
: SC's fork of PortAudio, which has been modded for cross-platform workportmidi
: PortMIDI, a cross-platform library for MIDI I/Osimplejson-2.3.2
: simplejson, a Python package used bysced
yaml-cpp
: yaml-cpp, a C++ library for YAML
HelpSource
: schelp source for SCDocicons
: contains icon files for the projectinclude
: C++ headers for client code, including server pluginslang
: C++ source forsclang
LangSource
: sources for the core of the language, including the interpreterLangPrimSource
: sources for SuperCollider primitive functions. Loosely organized by functionality.
package
: tools for preparing and packaging release assets, including changelog-related scriptsplatform
: various platform-specific bitsQtCollider
: sources for the Qt GUI extensions tosclang
SCClassLibrary
: SuperCollider sources for the core class librarySCDoc
: C++ sources for SCDoc, the .schelp parserserver
: C++ sources forscsynth
,supernova
, and server pluginsplugins
: sources for server plugins (UGens)scsynth
: sources for scsynthsupernova
: sources for supernova
sounds
: sound files, packaged into release assetstestsuite
: test filesclasslibrary
: SuperCollider-language tests for the core class librarysclang
: tests forsclang
server
: C++ tests forscsynth
andsupernova
tools
: various tools useful for maintainers
Important files in the root directory are:
.appveyor.yml
: config file for AppVeyor CI.travis.yml
: config file for Travis CIbuild_sclang_cfg.in
: config file used for the specialSC_DOC_RENDER
build targetCMakeLists.txt
: main CMake fileREADME_*
: readmes for various platformsSCVersion.txt
: the master versioning document. The version number is stored here and nowhere else.travis_test_run_proto.json
: config file used by qpm to run tests in CI