Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Bela support #5295

Merged
merged 2 commits into from
Feb 10, 2021
Merged

Conversation

giuliomoro
Copy link
Contributor

Purpose and Motivation

This PR adds support for Bela, an ultra low-latency platform for audio and sensor processing with a few thousand (not all of them using Sc!) users worldwide. Bela is a headless Linux computer, so one can either run sclang on Bela itself (running an .scd file, without live-coding), or run scsynth on Bela and live-code it from the Sc IDE on the host.

Work on this was started by @danstowell during the Kickstarter launch in 2016. In the following months and the following year, @sensestage added more complete support with help from me and @apmcpherson. Since then we started shipping a Sc build of our Sc fork with our image and I have occasionally rebased our changes on newer versions of the Sc develop branch, somewhere at 3.9beta, somewhere at 3.10, also fixing some bugs (development took place at https://github.com/BelaPlatform/supercollider). More recently @elgiano added support for the Bela Scope (a browser-based oscilloscope with some more features than Sc's own) and tied up some loose ends. Now we are in pretty good shape and we are taking @brianlheim up on his offer from a few months ago to try to merge upstream (i.e.: closes BelaPlatform#73 ). Thanks everyone, we wouldn't be at this stage without you!
All of this has been rebased on top of the latest develop and squashed for your reviewing convenience into 3 commits.

Types of changes

  • New feature

Bela requires a custom (non-ALSA, non-Portaudio, etc) audio backend as well as some Ugens to perform analog and digital I/O. Additionally it has its own oscilloscope. These Ugens need access to the BelaContext, which is owned by the audio backend. This required modifying struct World. Additionally, new Server options were added to deal with Bela specifics (e.g.: number of analog I/O, digital I/O, scope channels, multiplexing analog inputs etc etc).
Xenomai is a real-time co-kernel for Linux, which is used by Bela, but could be in the future be used by other backends. Xenomai offers POSIX-like services that are real-time safe. Calling non-Xenomai services from a Xenomai thread (such as Bela's audio thread), will cause "mode switches", which in turn will make the thread lose its real-time guarantees and ultimately lead to dropouts if running at very low latencies. For this reason, unique_lock and condition_variable_any from the standard C++ library cannot be used without losing real-time guarantees. I therefore had to add Xenomai-compatible equivalents of SC_Lock and SC_SyncCondition.

  • Documentation

README_BELA.md covers building, installation and basics.
New command-line options on the scsynth side have been added and documented in server/scsynth/scsynth_main.cpp. New language-side classes have been added and a new primitive hasBelaSupport has been added. These are documented in HelpSource/.

  • Breaking changes

No breaking changes when building without -DAUDIOAPI=bela. When building with it, as some of the public includes have been modified, externally-hosted UGens (e.g.: sc3) have to be rebuilt.

To-do list

  • Code is tested
  • All tests are passing
  • Updated documentation
  • This PR is ready for review

Copy link
Contributor

@elgiano elgiano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I'll test it soon and see how it works on both Bela and a Linux computer!
Only very minor comments in a few spots.

I have been looking at Bela's SuperCollider fork for a while now, and I don't see anything surprising here, nor any potential damage to other platforms. Still I think it's important for a merge like this that someone else also takes a look :)

common/XenomaiLock.h Show resolved Hide resolved
examples/bela/bela_start_scsynth.scd Outdated Show resolved Hide resolved
@dyfer
Copy link
Member

dyfer commented Dec 21, 2020

Thanks for this @giuliomoro
Just a quick comment: for the new files you could add copyright information, if you'd like (like here, for example)

@giuliomoro
Copy link
Contributor Author

Thanks for this @giuliomoro

thanks for having a look!

Just a quick comment: for the new files you could add copyright information, if you'd like (like here, for example)

Is it OK not to have it in there? I feel like those things tend to get outdated over time and I am never sure what their purpose is ... The commit history will tell who the author(s) have been more in detail.

Copy link
Contributor

@mossheim mossheim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this!

some general notes that i would like you to address before more substantial review:

  1. format the sc code so it is indented in tabs, not spaces, including any code examples in schelp and scd files. follow the other points in our style guide, too, as much as you have time for. especially regarding if, spacing of operators, and argument lists.
  2. rename the folder SCClassLibrary/Common/Audio/bela to Bela
  3. indent all the new cmake code at 4 spaces, except lines 156-158 of server/plugins/CMakeLists.txt
  4. replace the try_or_retry macro in XenomaiLock.cpp with a real function
  5. add #pragma once to all new headers
  6. make sure all your files have an ending newline -- for instance examples/bela/bela_example_analogin_2.scd does not
  7. change the C++ macro BELA to SC_BELA to make clear it comes from our project
  8. remove any vestigial commented-out code, it's especially bad in BELAUgens.cpp
  9. rename both the file and target BELAUGens to "BelaUGens", this is easier to read and more in line with our naming conventions

@mossheim
Copy link
Contributor

I feel like those things tend to get outdated over time and I am never sure what their purpose is ... The commit history will tell who the author(s) have been more in detail.

git author does not necessarily tell you who is the actual author of the code, and it's not a replacement for a copyright claim which as i understand it is primarily to give a person or persons legal standing to sue in the case of a license violation. that said, we don't have a policy as far as i know regarding this. in my experience if the author of a piece of code wishes to name either themself, James McCartney, or the Free Software Foundation as the copyright holder that's generally acceptable, so long as they are ok with it being licensed with GPL3 or another compatible license. AFAIK it's not ok to remove copyright notices without explicit permission of the author.

@mossheim
Copy link
Contributor

also, this is the most co-authors (5) i've ever seen on a commit, cool: 84f24e2

@dyfer dyfer added architecture: arm comp: 3rd party 3rd party libraries/dependencies comp: build CMake build system labels Dec 25, 2020
@giuliomoro
Copy link
Contributor Author

thanks @brianlheim

format the sc code so it is indented in tabs,

and this cannot be done with clang-format, right? Any chance such a feature could be added to it?

indent all the new cmake code at 4 spaces,

even when the surrounding code uses tabs (e.g.: lines 148:153 of server/scsynth/CMakeLists.txt) ? I understand this should hold, but I thought I should ask.

replace the try_or_retry macro in XenomaiLock.cpp with a real function

this would lead to plenty of code duplication, is that really preferable to the current situation?

@mossheim
Copy link
Contributor

thanks @brianlheim

and this cannot be done with clang-format, right? Any chance such a feature could be added to it?

good luck getting llvm devs to accept that PR. :)

you can do this in the SCIDE. no plans right now for having a linter/formatter for sc code but it would be nice.

even when the surrounding code uses tabs (e.g.: lines 148:153 of server/scsynth/CMakeLists.txt) ? I understand this should hold, but I thought I should ask.

yes

this would lead to plenty of code duplication, is that really preferable to the current situation?

i don't understand. there will not be much duplicated code if you replace the macro with a function. and yes, almost anything would be better than that macro.

giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 25, 2020
2. rename the folder SCClassLibrary/Common/Audio/bela to Bela
3. indent all the new cmake code at 4 spaces
5. add #pragma once to all new headers
6. make sure all your files have an ending newline -- for instance examples/bela/bela_example_analogin_2.scd does not
9. rename both the file and target BELAUGens to "BelaUGens", this is easier to read and more in line with our naming conventions
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 25, 2020
As suggested by @brianlheim in supercollider#5295
7. change the C++ macro BELA to SC_BELA to make clear it comes from our project
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 25, 2020
As suggested by @brianlheim in supercollider#5295
8. remove any vestigial commented-out code, it's especially bad in BELAUgens.cpp
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 25, 2020
As suggested by @brianlheim in supercollider#5295:
1. format the sc code so it is indented in tabs, not spaces, including any code examples in schelp and scd files.
@giuliomoro
Copy link
Contributor Author

@brianlheim you can do this in the SCIDE. no plans right now for having a linter/formatter for sc code but it would be nice.

Does this mean:

  • open the file in SCIDE
  • select all
  • go to Edit->Autoindent Line or Region
  • save file
    ?

I tried the above for all the files we created/modified and this is the outcome: 9be6c8c

Most of the changes look OK, but

  • I am not sure if that's all that's needed
  • some of the lines we didn't change were affected in the process

@mossheim
Copy link
Contributor

yeah, the sc code changes look good now, thanks! FYI, the cmake code in the FindX.cmake modules is still indented at 2 instead of 4 spaces

Copy link
Member

@telephon telephon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if the bela-specific functionality would go into a specific folder in the class library, and – unless it is intended to make them work on other platforms – the UGens should have a prefix. The platform is (at least still) not used by so many people, and the common classes should work cross-platform.

Thanks for all this, I'm looking forward to trying out bela with sc!

giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 27, 2020
2. rename the folder SCClassLibrary/Common/Audio/bela to Bela
3. indent all the new cmake code at 4 spaces
5. add #pragma once to all new headers
6. make sure all your files have an ending newline -- for instance examples/bela/bela_example_analogin_2.scd does not
9. rename both the file and target BELAUGens to "BelaUGens", this is easier to read and more in line with our naming conventions
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 27, 2020
As suggested by @brianlheim in supercollider#5295
7. change the C++ macro BELA to SC_BELA to make clear it comes from our project
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Dec 27, 2020
As suggested by @brianlheim in supercollider#5295
8. remove any vestigial commented-out code, it's especially bad in BELAUgens.cpp
@giuliomoro
Copy link
Contributor Author

@brianlheim FYI, the cmake code in the FindX.cmake modules is still indented at 2 instead of 4 spaces

Thanks, fixed that.

@giuliomoro
Copy link
Contributor Author

giuliomoro commented Dec 27, 2020

@elgiano would you have time to act on the comments by @telephon please?

EDIT: I mean, I am not sure what they are referring to.

@telephon
Copy link
Member

EDIT: I mean, I am not sure what they are referring to.

They refer to the sclang classes added in this PR.

giuliomoro added a commit to BelaPlatform/Bela that referenced this pull request Feb 7, 2021
@mossheim
Copy link
Contributor

thanks again @giuliomoro . i've opened a 3rd and final PR to your branch here: https://github.com/BelaPlatform/supercollider/pull/91/files

@giuliomoro
Copy link
Contributor Author

giuliomoro commented Feb 10, 2021

i've opened a 3rd and final PR to your branch here:

merged

Re: BelaScope using a C API instead of C++, is this enough? https://github.com/BelaPlatform/supercollider/tree/topic/bela-scope-c

@mossheim
Copy link
Contributor

thanks @giuliomoro !

Re: BelaScope using a C API instead of C++, is this enough? https://github.com/BelaPlatform/supercollider/tree/topic/bela-scope-c

unfortunately i don't think that's enough, because BelaScope itself is still a C++ class using C++ language features (new, delete, classes, etc.). let's leave this discussion until after the PR is merged please, it is too difficult to keep track of everything going on here. please update the readme when you have time and then i'll approve and merge this :)

@giuliomoro
Copy link
Contributor Author

OK thanks, I will ping you when done.

@Spacechild1
Copy link
Contributor

Spacechild1 commented Feb 10, 2021

unfortunately i don't think that's enough

Agreed. Generally, just use a plain C struct for the public data members that the plugins should see. Then inherit from this struct for the actual private implementation. All operations on the struct that go beyond simple member access have to happen via plugin API methods.

In your case that would probably be:

// in the plugin interface header:
struct BelaScope {
    float* buffer;
    uint32_t maxChannels;
    uint32_t bufferSamples;
    int touched; // no bool!
};

// in the implementation .cpp file
class BelaScopeImp : public BelaScope {
public:
    // methods
private:
    Scope scope;
};

// in InterfaceTable
void (fBelaScopeLogBuffer*)(World *, BelaScope *);

BTW, if you need to add several API methods to the interface table, it might make sense to group them in a seperate Bela interface and put that in the SC InterfaceTable.

struct BelaInterface {
    void (fScopeLogBuffer*)(World *, BelaScope *);
    // other methods...
};

// and in InterfaceTable
BelaInterfaceTable *mBelaInterface;

@giuliomoro
Copy link
Contributor Author

@brianlheim here's the updated README. https://github.com/BelaPlatform/supercollider/blob/bela-ready-to-merge/README_BELA.md

New code is tested and ready to go.
I'd recommend squashing before merging, let me know if you want me to do that, please.

@mossheim
Copy link
Contributor

@giuliomoro I just looked over the readme and it looks good. thanks for that, and for testing the new changes too! yes, could you please squash it?

giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Feb 10, 2021
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Feb 10, 2021
@giuliomoro giuliomoro force-pushed the bela-ready-to-merge branch 2 times, most recently from 0bec501 to 68007f6 Compare February 10, 2021 22:22
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Feb 10, 2021
giuliomoro added a commit to BelaPlatform/supercollider that referenced this pull request Feb 10, 2021
@giuliomoro giuliomoro force-pushed the bela-ready-to-merge branch 2 times, most recently from 8f41d6b to 0be1e36 Compare February 10, 2021 22:36
Co-authored-by: elgiano <elgiano@gmail.com>
Co-authored-by: sensestage <nescivi@gmail.com>
Co-authored-by: Dan Stowell <danstowell@users.sourceforge.net>
Co-authored-by: Andrew McPherson <a.mcpherson@qmul.ac.uk>
Co-authored-by: brianlheim <self@brianlheim.com>
@giuliomoro
Copy link
Contributor Author

pushed!

also, this is the most co-authors (5) i've ever seen on a commit, cool: 84f24e2

that's because you haven't seen the six in b773117 !

Copy link
Contributor

@mossheim mossheim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! just waiting for Appveyor to complete now

@mossheim mossheim merged commit 4989ef9 into supercollider:develop Feb 10, 2021
@mossheim
Copy link
Contributor

thanks to everyone who worked on this! Bela is now in mainline SC 🎉

@giuliomoro
Copy link
Contributor Author

thanks @brianlheim for taking so much time to go through this and improve it a fair bit in the process and thanks everyone else who has contributed to it with precious code and/or precious reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architecture: arm comp: build CMake build system comp: 3rd party 3rd party libraries/dependencies
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Let's merge Bela support into SC!
9 participants