@l0calh05t thanks for the update. I always hope that I'll find the time to dig into Rust at some point! The changes in the BelaInitSettings
struct
have been made so that it maintains binary compatibility with the older versions. Not sure if that helps with your effort, because the only related change I seem to see is that here https://github.com/l0calh05t/bela-rs/commit/a32aacdae50f712d9aee17eafe7fd3091a0f2bf9 you commented out all the lines that were actually setting the settings ...
Realtime audio drivers in Rust
giuliomoro yes, I removed them as the fields didn't appear to exist anymore in the new BelaInitSettings
struct
. I assume
int unused1;
char unused2[MAX_UNUSED2_LENGTH];
is where they used to be? Since @andrewcsmith 's bela-sys
generates the Rust structs directly from the header, binary compatibility wasn't helpful. It may work with @padenot 's bela-sys
since that one doesn't auto-generate the Rust code, in that case I could add them back in (but everything would have to be binary compatible and it could silently break in the future).
- Edited
In any case, the bela-sys
hello
seems to run (although I haven't dared plug anything in yet see EDIT below)
root@bela:~# ./hello
Bela_initAudio()
Starting in high-performance mode
Starting with period size 16 ;analog enabled
DAC level 0.000000 dB; ADC level 0.000000 dB; headphone level -6.000000 dB
Detected hardware: CtagBeastBela
Hardware specified by user:
Hardware specified in belaconfig:
Hardware to be used: CtagBeastBela
Bela_getHwConfig()
fifoFactor: 1
core audioFrames: 16
PRU memory mapped to ARM:
digital: 0xb6316000 0xb6316400
audio: 0xb6317000 0xb6317200 0xb6317400 0xb6317500
analog: 0xb6307000 0xb6307080 0xb6307100 0xb6307180
analog offset: 0xffff2000 0xffff2080 0xffff2100 0xffff2180
Bela_startAudio
startAudioInilne
Using embedded PRU code
_________________Audio Thread!
^Caudio thread ended
Stopping audio...
Bela_cleanupAudio()
On the other hand, the bela-rs
examples only output Setting up
, except the sample
example which stops at an assertion (probably because it didn't expect to find a Bela BEAST combo)
root@bela:~# ./sample
Setting up
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
left: `16`,
right: `2`', examples\sample.rs:26:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 9
Aborted
EDIT:
Sound seems to work. The difference regarding the output of the bela-rs
hello
comes down to not doing bela_sys::Bela_setVerboseLevel(1);
l0calh05t yes, I removed them as the fields didn't appear to exist anymore in the new BelaInitSettings struct.
I see!
enableBelaCapeButtonMonitoring
has become stopButtonPin
, codecI2CAddress
, receivePort
, transmitPort
, serverName
have been removed because they had been unused for ages. Some of those became unused
, some others have been replaced with something that has been added in the mean time (namely at least audioThreadDone
, not sure if anything else).
l0calh05t (but everything would have to be binary compatible and it could silently break in the future)
I am aiming to keep binary compatibility going ahead.
l0calh05t the bela-sys hello seems to run
great!
l0calh05t except the sample example which stops at an assertion (probably because it didn't expect to find a Bela BEAST combo)
that's it by the looks of things!
giuliomoro
enableBelaCapeButtonMonitoring
has becomestopButtonPin
Okay, but that substitution implies different semantics, right? bela-rs
considered it a boolean and stopButtonPin
can be -1
or some pin number. Is there any way to check which ones are valid? Otherwise calling the method "safe" would be a lie (but checking of setting invariants is already quite incomplete). In any case
/// How many audio input channels [ignored]
int numAudioInChannels;
/// How many audio out channels [ignored]
int numAudioOutChannels;
seem to be obsolete? audioThreadDone
, board
and projectName
appear to be new. Supporting audioThreadDone
would be the most complex of the additions.
- Edited
giuliomoro that's it by the looks of things!
Yes, but indirectly it is due to a limitation of the dasp
(formerly sample
crate) which appears to only support fixed-size (at compile time) frames (if I'm reading the documentation correctly).
Urghh... You could run board_detect
which returns the board name and infer the channel count from that at compile time ... Hackish ...
giuliomoro That wouldn't work for cross-compilation. dasp
is a separate crate anyway, so that can be ignored for now
l0calh05t Okay, but that substitution implies different semantics, right?
that's correct, but as far as I knew no one was actually setting it to anything else than default, so this was sort of a compromise: keep ABI compatibility for everything else while changing the meaning for this (to my knowledge) unused flag. Yeah, pretty poor, but ultimately AFAIK the only thing that relied on dynamically linking to Bela is Supercollider, which I also maintain and which didn't set that specific flag.
l0calh05t Supporting audioThreadDone would be the most complex of the additions.
that's an optional function callback, you are unlikely to need it for anything. It was required for Supercollider, as it didn't have a way of being notified and gracefully shutdown if the audio thread ended because the button was pressed.
l0calh05t s there any way to check which ones are valid?
you mean which values are valid for stopButtonPin
? Any value is "valid". -1 or any number >= 128 are considered "off", values between 0 and 127 are considered "on" and the value is the pin number that will get monitored.
l0calh05t /// How many audio input channels [ignored]
int numAudioInChannels;
/// How many audio out channels [ignored]
int numAudioOutChannels;
seem to be obsolete?
You seem right. I may have left them there in case i actually wanted to use them ... it could be helpful to specify manually how many of the available I/O one wants to actually use ... currently you can do it only in a limited way by setting e.g: --board=Bela
(or .board = BelaHw_CtagFace
) to only use 4in/8out when a CTAG Beast is also connected... But as usual there are other higher-priority things going on :-(
giuliomoro the only thing that relied on dynamically linking to Bela is Supercollider, which I also maintain and which didn't set that specific flag.
Rust links shared libraries by default AFAIK, but it should be possible to change this. The allocation functions for the settings struct aren't used yet though, but doing that shouldn't be to complicated either.
giuliomoro you mean which values are valid for stopButtonPin? Any value is "valid". -1 or any number >= 128 are considered "off", values between 0 and 127 are considered "on" and the value is the pin number that will get monitored.
Ok, but can any value in [0, 128) actually be used? What if something else is assigned to the pin as well?
giuliomoro currently you can do it only in a limited way by setting e.g: --board=Bela (or .board = BelaHw_CtagFace) to only use 4in/8out when a CTAG Beast is also connected... But as usual there are other higher-priority things going on
What happens if you set a board that isn't present / available (i.e., Bela when only a Beast/Face is used or BelaMini on a Bela)?
l0calh05t What happens if you set a board that isn't present / available (i.e., Bela when only a Beast/Face is used or BelaMini on a Bela)?
it will fail and not start. See https://github.com/BelaPlatform/Bela/blob/master/core/RTAudio.cpp#L452-L479
l0calh05t Ok, but can any value in [0, 128) actually be used? What if something else is assigned to the pin as well?
It will let you do that ... if you end up picking one of the pins that the Bela Digital channels are on and you set it to an output, this will affect the readings, but if it's used as an input, it will work. There are no checks to avoid any such clashes, we just make sure it doesn't crash. It's up to the user to select a pin that makes sense. Again, most likely this is just for those who want to spin their own board or something like that, not really for day-to-day usage ...
giuliomoro Thanks for the info!
Just a quick update: bela-sys
now uses a BELA_SYSROOT
environment variable instead of having to place subsets of files into a Cargo-internal folder. So just extract partition 1
(/
) of the Bela image to a folder of your choice and point BELA_SYSROOT
at it (in theory it should also build on the Bela itself, assuming cargo and rustc work on it). This should work much better when crates depend on bela-sys
. Furthermore, static vs dynamic linking of bela
is now switchable via a crate feature static
and the hello
-example is now a proper example (meaning its dependencies are now dev-dependencies!) and not the main.rs
of a "hybrid" executable/library crate.
bela-rs
now supports the new APIs (BelaHw
/board
and stopButtonPin
)
- Edited
If you want to try out my branches of bela-sys
or bela-rs
, add
[patch.'https://github.com/andrewcsmith/bela-sys.git'.bela-sys]
git = "https://github.com/l0calh05t/bela-sys.git"
branch = "bela0.3.8b_rust1.52.0"
[patch.'https://github.com/andrewcsmith/bela-rs.git'.bela-rs]
git = "https://github.com/l0calh05t/bela-rs.git"
branch = "bela0.3.8b_rust1.52.0"
to your Cargo.toml
and add the original version to your dependencies. (I didn't change any of the URLs in case @andrewcsmith is interested in merging these patches)
Would you mind doing a PR for this so we can get it merged upstream? I'm not sure Andrew is looking at this forum.
I'm on other parts of my project (doing all the analog bits), so I didn't update the board and didn't recompile anything for quite some time now, so this went unnoticed.
fwiw, cargo and rustc work well on bela, but it's horribly slow. I was doing it on the device initially, but since it's so easy to cross-compile with rust, I ended up compiling on my laptops and sending the binary.
We can also figure out the dasp situation, surely there is a way to sort it out.
padenot Would you mind doing a PR for this so we can get it merged upstream? I'm not sure Andrew is looking at this forum.
Done
padenot fwiw, cargo and rustc work well on bela, but it's horribly slow. I was doing it on the device initially, but since it's so easy to cross-compile with rust, I ended up compiling on my laptops and sending the binary.
Yeah, I suspected as much and decided against trying it
padenot We can also figure out the dasp situation, surely there is a way to sort it out.
With the new min_const_generics
feature, it should be possible to have a generic implementation where the proper compile-time channel counts is selected at run-time from a fixed set of known channel counts. Without such workarounds AFAICT not without changing dasp
itself to support run-time variable channel counts.
I also started looking into getting bindings for the Midi support library: https://github.com/andrewcsmith/bela-rs/issues/12 / https://github.com/l0calh05t/bela-sys/tree/midi
An update for anyone interested: Midi support is in (both bela-sys
and bela-rs
, although only one with a merged PR) https://github.com/l0calh05t/bela-rs/tree/midi
After noticing a number of safety issues, I also started (and pretty much finished aside from documentation) what is pretty much a full redesign of bela-rs
: https://github.com/l0calh05t/bela-rs/tree/next
Hey @l0calh05t ! Is your next
branch a good starting place? I'm new to Rust and looking forward to learning