BASICally: a new module for writing code within Rack

My point about naming is about whether or not the things being saved (which hasn’t quite been determined) are semantically different enough that names are useful. For example, I’m certainly glad that VCV modules have names; I’m glad I don’t have to refer to module 231 or 609. On the other hand, having to name all of your array indecies would be bad, too; volt1[“one”] = volt1[“zero”] isn’t always an improvement.

Anyhow, rather than discuss generalities, I’m far more interested in use cases/examples. If you had the ability to save state in BASICally, what code would you use it with?

In my case I usually want it to be available next time I start the patch.

In my case it’s always something tiny.

My BASICally scripts are incredibly simple, so naming is not an issue. :slight_smile:

If the values are dumped somewhere (i.e. “myexport.txt”) then I’d probably manually reshape it to be acceptable for Voxglitch One Point. .

Or I’d just create a new BASICally module with another code. In case of the original example I’d create a new module with this code:

' this is the twinkle super star pattern :)
if in9>2 or start() then pos=-1 end if
volt1[0]={0.00, 0.00, 0.58, 0.58, 0.75, 0.75, 0.58, 0.42, 0.42, 0.33, 
0.33, 0.17, 0.17, 0.00, 0.58, 0.58, 0.42, 0.42, 0.33, 0.33, 
0.17, 0.58, 0.58, 0.42, 0.42, 0.33, 0.33, 0.17, 0.00, 0.58, 
0.58, 0.75, 0.58, 0.42, 0.42, 0.33, 0.33, 0.17, 0.00 } 

' calculating the next step
pos=pos+1

' sending out the first eight of the voltages
out1=volt1[mod(pos,8)]
1 Like
' maybe this for a mydebug.txt?
debug.print volt1

@FiroLFO, A couple questions to drill into your specific instance a bit more:

  1. Is the action of turning a variable’s value into a string something that is initiated:

    1.1 programmatically, that is, some code running causes it to happen?

    1.2 by a human action (say, by selecting something in the context menu)?

    1.3 Something else?

  2. Is the best place to put the resulting text:

    2.1 the copy/paste buffer?

    2.2 Wherever the cursor in the program text is (i doubt this is a good answer)?

    2.3 Some file with a well known name?

    2.4 Some separate place in the module UI?

more “standards” for stuff on the clipboard would not be a bad thing.

2 Likes

Hopefully others will also share their thoughts.


Probably it’s the most practical.

tempvar[0] = {random(0,1),random(1,2)}
debug.print tempvar
' or even debugPrint(tempvar)

That was my original idea but a dedicated routine (like debugPrint) would help to specify the variable to be saved.

Khm… Actually yes. :blush: What about an extension screen on the left? Something like this:

image

I didn’t think of this one but looks like a good idea. Like the clipboard is updated if the cursor is above the module. (Otherwise a routine like debugPrint() in one of the BASICally modules could create problems working with Ctrl-C and Ctrl-P in other modules.)

(I see Bruce’s post about the portable sequence protocol but I don’t think it would be feasible in case of BASICally.)

Nope.

Yes. Like “dump.txt”, or “debug.txt” in one of the standard folders.

I don’t think so.


… just once again: I realize that this isn’t the most important thing. Don’t waste much time on this idea if it seems to be problematic.

Your unutilized programming skills will always find something essentially useful. (Like customizable font size? :nerd_face: )

Oooh, a debugging console off to the side would be really useful for many situations. I love that. Pondering now…

Didn’t Andrew say explicitly that he would be willing for someone to adopt prototype for v2 because demand (low) vs technical complexity (high) meant he didn’t think it was feasible for his business to support?

He did start a v2 branch but I think it needs an owner

I know he said that somewhere which wasn’t a dm : email but I can’t find it.

Also I may be wrong. Bayes etc…

I also vaguely recall something like that. But I also vaguely recall him saying something after that to the effect of him wanting to break out the different supported languages into different modules. Whether he means to do it I don’t know. Sorry, too lazy to search right now :slight_smile:

As a result of the suggestion above from @FiroLFO, there is now a:

  • format for modules to send a receive text along a cable (Tipsy).
  • Support in BASICally for sending text messages.
  • A module (TTY) for displaying received text messages.

Details and links in this post. Or watch this video to see it all in action.

Thanks again to @baconpaul and @pachde for encouraging and materially contributing to this idea.

3 Likes

Thank you again for this module!

I just want you to know that I find BASICally absolutely essential. It’s so useful!

1 Like

I have been having fun with BASICally in various forms, but mostly as parameter remapping/translation between two modules. I was starting to do some scale translations but to do that chromatically would require 12 inputs or 12 channels. Is there a reason that you did not support 16 channel polyphony on IN1? I could probably kludge up a 2 BASICally instance script where the first takes a poly external scale and sends serially as value and index on two BASICally inputs, but that would being quite a kludge.

Have you done or seen anyone do something like this that requires more than 9 channels? Thanks.

Before I get to polyphony, why does note translation require an IN/OUT for each note? That’s what you’re implying with the connection between chromatic scale and the number 12.

In the built-in presets for BASICally, there are some different kinds of quantitizers available. I suspect you could change the values in one of them to get the effect you want.

But IN/OUT are about signals, not individual notes. Unless you are using a source that puts each note on a different wire? Is that a thing?

M

I am working with diatonic scales of 7 notes from a chromatic scale of 12 semitones. So, the scale is data or signals. Sometimes I have 5 note pentatonic scales. “Poly External Scale” uses 12 channels.

I can and have kludged things together to do what I want to do, but, it would be a lot simpler with polyphony. But, I understand that you may not want polyphony in BASICally for some reason.

I am using BASICally as a mapping or translation layer wherever I might find a use for such. Most things work fine with the current mono inputs and outputs. Occasionally it would work better to be able to send in an array via polyphony.

Thanks.

Ah, I see. The “12” is the number of channels in that output from your module.

The reasons I haven’t thought a lot about supporting polyphony are:

  1. Seems really unlikely that I can use the rack:simd library to do these computations, so it’ll greatly increase the CPU consumed. But maybe that is constrained by knowing the number of channels present.
  2. Not sure how to change the language to support it. No way that I love has come to mind yet.

The use case suggestion you seem to be making, which I find interesting, is:

  • Do the same computation on every channel in IN1, and then apply that to the corresponding channel in OUT1.

That perhaps suggests a new construct, like (spitballing here):

FOR IN1 TO OUT1
  foo = in1 + 1  ' Something simple.
  IF foo > 3 THEN
    out1 = foo - 3
  ELSE
    out1 = foo
  END IF
NEXT

When BASICally is running this loop, it iterates through all of the channels in IN1, and within the confines of the loop, "in1’ refers to the particular channel value.

This could get needlessly slow in your case if, for example, there’s a FOR loop used to compute the corresponding out1 (like I have in the quantizer presets), for two reasons:

  1. It doesn’t really need to run this every cycle; most cycles, the IN1 and OUT1’s will be the same.
  2. FOR loops have a built-in “WAIT 0” in the NEXT, so that FOR loops don’t exceed the cycle’s time budget too easily.

So, stuff to chew on here. But am I understanding the use case better?

M

1 Like

I think of BASICally as more than a signal handler. So, I think of it as general purpose computing. I have not used SIMD, so I am not familiar with the limitations.of this vectorization.

In a general case, IN1 channels are independent of OUT1 channels. I want to supply BASICALLY with an array of 12 “poly external scale” values where the values can be 0.0, 8.0 or 10.8 and for a diatonic scale, only 7 slots will non-zero values or 5 for a pentatonic scale. Then I would want to output a 7 or 5 member array. Right off the bat, I do not see how this would work

I should probably stick with using BASICally as it is as it would probably be very difficult to have a general purpose approach to polyphonic input and output. Of course BASICally can dynamically set the channel count for any output port, as Meander does for chord and bass, but, it might not know this at first and the language would have to support dynamic polyphony.

Thanks for considering this though. If I am able to do what I want with the existing version, I will let you know…

@StochasticTelegraph thanks for this module, that I’ve tried only recently, and I think I still need some time to understand it’s operation fully. By the way, at the moment I’m stcuk in understanding the following things:

  • when a recompilation is triggered. I know that it happens when the text changes, but I don’t understand when exactly. Does it wait for a while (debounce time), does it wait the next trigger? I haven’t found where this is explained in the docs
  • I’m asking becuase I got strange behaviours while editing the code of the “Also Sprach 2” preset. When I changed the value of the pause_length variable, sometimes the timing of the out signal was correct, but sometimes it started to spring at audio rate, like if it picked a very small value for that variable. I though it was because while clearing and writing the new value the compiler kicked in before I entered the final value. But then it didn’t pick the number that I entered in the end. I have a video that explains this in the issue I opened today.

I really love the idea of the Tipsy protocol. It owuld be nice if BASICally could also receive it. We could code it from CV inputs, even from external softwares. It would be great :smiley:

I’m happy to hear you’re trying BASICally! I’ll see if I can answer your questions.

  • when a recompilation is triggered: It doesn’t intentionally wait any length of time. As soon as a textual change occurs, it starts a recompilation in a background thread, once that completes, it starts the program again (and will run any “WHEN start()” code). That recompilation is pretty fast, but will take at least a few milliseconds. Unless your program is quite long, i doubt you’d be able to perceive the delay.
  • strange behaviors: I agree, that is very odd (and annoying). I’ve started communicating with you about it in the bug. Thanks a million for actually filing a bug (with a demo video) instead of just accepting it.
  • Tipsy strings as input: I’ve put a fair bit of thinking into how to do that, actually, but I’m distracted at the moment by an upcoming VCV Rack set of modules I’m working on. I will note that the Tipsy protocol is very sensitive to exact digital voltage values, and so the hope that such messages could pass through physical hardware intact should be pinned onto a different protocol that would be designed with robustness to noise and digital ↔ analog conversions in mind.
1 Like

OK, I see that you spawn a new thread inside the process method any time a change in the code text is detected. I will continue the discussion inside the issue.

Regarding the idea of a Tipsy input, in my case I wouldn’t use from hardware, so no robust analog ↔ digital conversion is required, but I understand that if it was implemented it should also support this use case. My idea was to implement high level abstractions in an external sw (GUI or text based) that could emit BASICAlly code.

Is there a module that lets you do Processing code?