Some observations

Music is many things to many different people, for example:

As far as musical parameters go, have you looked at the Patterns library? Also the panola quark (GitHub - shimpe/panola: supercollider PAttern NOtation LAnguage (superset of subset of MISPEL ported to supercollider)).

2 Likes

This would mean that there is a Composition object (comparable to the pbind object) that accepts a [Note Series] or a NoteGenerator, a [Timing Series] or a TimingGenerator, and a Timbre (SynthDef) or a TimbreGenerator.
The generators can be preprogrammed by the SC developers to cover the power of the SC system, or programmed by advanced users using the SC language. For realtime control, the generators and series should be updatable, and SC already facilitates this.

Ok, I should have said tones instead of notes. In the context of SC it doesnā€™t matter.

Thatā€™s not quite what I meantā€¦ but thatā€™s alright, I donā€™t mean to argue, just to point out that what music means to you (and what you are trying to achieve with SC) might not be universal. (For example, someone might be into parsing legal documents using occurrences of the letter ā€˜Fā€™ to determine musical timing, modulating the data stream with sensors measuring the electrical activity in a houseplant, using this to control a hardware synthesizer via MIDI, and then granularly processing the resulting sound before streaming it to a website. This is all reasonably straightforward to do using SC.)

Would you like to elaborate on the structures youā€™re imagining and how they might differ from the patterns that already exist? It sounds to me like youā€™ve described a lot of the functionality of patterns, for example:

( // Timbres
SynthDef(\bandura, { |out, freq = 500, gate = 1, amp = 1, pan, decay = 1, rt = 10|
  var sig;
  sig = SelectX.ar(amp.explin(0.25, 1, 0, 1), [PinkNoise.ar(0.5), WhiteNoise.ar(0.5)]);
  sig = Pluck.ar(sig, 1, 0.2, freq.reciprocal, (freq * decay), 0.5);
  sig = sig + (SinOsc.ar(freq / 2) * Env.adsr(0.01, 10, 0.1, rt).kr(0, gate, mul: 0.005));
  sig = sig * amp;
  sig = LeakDC.ar(sig) * 2;
  DetectSilence.ar(sig, doneAction: 2);
  sig = Pan2.ar(sig, pan);
  Out.ar(out, sig);
}).add;

SynthDef(\chaoticwhistle, { |out, pan, amp = 1, freq = 3000, foldlo = 0, gate = 1, at = 5, rt = 10|
  var in = LocalIn.ar(1);
  var inslow = Latch.ar(in, Impulse.ar(in.exprange(1, 10))).lag(in.range(0, 0.1));
  var sig = SinOsc.ar((in.exprange(20, freq)));
  var sig2 = Fold.ar(sig, foldlo * in, inslow.range(0.5, 1));
  LocalOut.ar(sig2);
  sig = sig * amp * Env.adsr(at, 0, 1, rt).kr(2, gate);
  sig = Pan2.ar(sig, pan);
  Out.ar(out, sig);
}).add;
)

(
p = Ppar([
  Pbind(
    \instrument, \chaoticwhistle, // Timbre
    \midinote, Pwhite(30, 80), // Note
    \dur, Pwhite(5, 15) // Timing
  ),  
  Pn(
    Pbind(
      \instrument, \bandura, // Timbre
      \scale, Scale.harmonicMinor, // Note
      \degree, Pbrown(-12, 12, 3), // Note
      \dur, Pgeom(1, 0.9, 100) // Timing
    ),
    inf
  )
]).play;
)

p.stop;

Maybe you could demonstrate what a structure like this might look like in your ideal environment?

1 Like

ā€œMusic is fairly simple: notes, timing and timbres/tonesā€

Thatā€™s rather simplistic or an incomplete list. Music is not fairly simple: notes, articulations, inflections, events, action modes, silence, timing, tempo, metrics tempo and timing changes, different time organizations measured or not, ambiguous perception, variable meaning, culture, perceptual streams or clangs, voicing, texture, timbre defined as another list of concepts, harmony, a hobby, a profession, an expert knowledge, it can be written in different ways or not at all, itā€™s about form, people forget the form so often, history, a lot of it, human-instrument interaction, lutheria, gestures, physical or abstract, motives, themes, phrases, sections, materials and organizations, did i said form, procedures, processes, also the perceptual and symbolic entities that create all that shapes and meaning or not, technology, performance, people, theories, technique, esthetic, praxis, taste, feeling, fascination, whatever and so onā€¦ not to mention it predates computers.

I get the feeling that you are missing the point here, just think about it, why would you waste your time suffering about what SuperCollider is not instead of, letā€™s say, making music?

1 Like

Are you familiar with all the default keys in a Pbind? By this I mean degree, note, mtranspose, ctranspose, legato, etc. etc. etcā€¦ It is hard to imagine a more music-oriented interface with so many ā€œbatteries includedā€. With patterns you can be very expressive, creative, and experimental with very little code. If notes, timing, and timbre are your main focus, I suggest this very common approach of writing SynthDefs and then writing Pbinds to play those SynthDefs. Yes, there are a gajillion other ways to make sound in sclang, which can be daunting and frustrating, but you donā€™t have to learn them all. Just find what works for you. There are very talented SC users who refuse to use patterns, but I think itā€™s a great starting point if you want to work from a conventional musical mindset.

1 Like

Many nice folks develop and developed SC (at this point for love!).

Happily SC is an open source project and so anyone can contribute. Calling out and making demands on ā€œthe developers of SCā€ may not be the most productive way to engage the forum imo.

Just FYI there are many projects that resemble what you are describing built on top of Supercollider (In addition to Pbindā€™s default Events as @PitchTrebler pointed out).

Check out Tidal Cycles, FoxDot and SonicPi for starters

cheers

Perhaps this is a feature not a bug?

Violins do not have ā€œbatteries includedā€ - they do very little to determine what music is made on them - there is no collection of pitches, no notions of rhythm, no necessary articulation, no harmonic language.

The best musical tools allow the player to create a music that doesnā€™t already exist. When software determines the musical metaphors for the user in advance, maybe the software is playing the musician rather than the other way round!

Iā€™m all for ironing out the (many) crazy time sinks in SC (ordering, debugging, problems with asynchrous ops, redundancy to name a few) - but for me the generality (along with a server that actually works) is the whole point. It takes longer to get anything but the range of things you can get is larger and the user and the system can(must) evolve together.

1 Like

Iā€™m a relative beginner. SC is much more verbose to do basic things and more esoteric than anything else Iā€™ve used. I can make full fledged songs in tidal cycles in a few minutes, but if I scour the internet for code examples by the respective codeā€™s user base and listen to what those languages have to offer in terms or versatility and sound quality, there is nothing compared to SC. (Since you like strongly typed, you should try tidal, itā€™s pretty great if you just want to bang out a tune) Not to knock the other platforms out there, but all the music I hear from them is either basic, can easily be done with some other piece of software, or just doesnā€™t sound unique. The things I hear things in SC that are completely different than anything to me. Iā€™m a complete noob with SC, but have been producing music for 20 years, and Iā€™m loving the sounds Iā€™m making. I can see that once I get better, I will be able to flesh out the ideas in my head in SC, where I wouldnā€™t be able to in other languages. Plus the community seems great.

1 Like

Ah, I missed this.

Because of first-class functions in SC, you can define:

+ Function {
	c_for { |test = false, increment, body|
		this.value;  // initializer
		while { test.value } {
			body.value;
			increment.value;
		};
	}
}

Then:

c_for({ i = 0 }, { i < 10 }, { i = i + 1 }) { i.postln };

In SC, we donā€™t have a way to get rid of the function braces (although one could make a preprocessor for that), but this reads essentially the same as C style.

Also:

C: while(test) { body }
SC: while { test } { body }

C: switch(expression) case A: ... break; case B: ... break;
SC: switch(expression) { A } { body A } { B } { body B } ā€¦ which looks confusing this way but itā€™s possible to format for readability:

switch(expression)
{ A } {
	body A
}
{ B } {
	body B
}

(Why is it switch(expression) but while { test }? There is a consistent rule to differentiate them. In switch(expression), the expression is evaluated once. In while { test }, itā€™s evaluated multiple times. In SC, if code needs to be executed in a loop or otherwise out of sequence, it must be in a function, no exceptions.)

Other languages: if(test1) { body1 } elseif(test2) { body2 } elseif(test3) { body 3 }...
SC: case { test1 } { body1 } { test2 } { body2 } { test3 } { body3 } (again, more readable with formatting).

Theyā€™re not pretty, but they exist.

hjh

1 Like

Let me try a slightly different tack:

If we assume that SC will be unsatisfactory for some people (fair enough), then what does one do about that?

  • Option 1: Change SC to suit more people.

  • Option 2: Accept SC as it is and learn to work with it.

  • Option 3: Use a different language that has the features you want, and can communicate with scsynth.

Option 1 has to take backward compatibility into account, so thereā€™s limited room to move.

Option 2 ā€¦ well, this whole thread is about resistance to option 2.

Option 3: There are two relevant parts to SC ā€“ the language design, and the class library features. Class library concepts are independent of the language. If the class libraryā€™s musical and synthesis features are translated into another language, then the other language becomes just as musically powerful as SC. (poison0ak said ā€œif I scour the internet for code examples by the respective codeā€™s user base and listen to what those languages have to offer in terms or versatility and sound quality, there is nothing compared to SCā€ ā€“ this is primarily because the server and SynthDef design makes it a lot easier to express complex synthesis than other environments. This is independent of language design ā€“ there is nothing special in SC syntax that makes these possible in SC and only in SC.)

If this is the case, then what is the point, if somebody strongly dislikes SCā€™s language design, of continuing to learn SC language?

The answer is probably that some of the musical/synthesis features have not been fully translated to other languages. That is, SC has features that other environments donā€™t have.

In that case, then itā€™s rather strange to argue simultaneously that SC should reduce its scope (ā€œSC is far too complex for its purposeā€).

(The chicken/egg problem here is that one wishes for the translation in order to avoid learning SC, but one canā€™t understand what would need to be translated without first learning SC.)

If another language can handle SynthDef building, Events and Patterns, in a REPL, then a lot of this discussion disappears, because you would have the musical power of SC in a language that you agree with better. Thatā€™s a valid development goal.

~~

General purpose ā€“ musical algorithms depend on robust data representation. If you limit the ways in which data can flow through the system be structured (yeah, Iā€™m looking at you, Max/MSP), then you limit the ways in which artists can imagine musical data, and the result is as poison0ak said: ā€œall the music I hear from them is either basic, can easily be done with some other piece of software, or just doesnā€™t sound unique.ā€ So, yes, a language-for-music does need arrays, hash tables, linked lists etc.

hjh

My comparison with the violin was actually a comparison between the violin and the piano.

Where with both instrument one can get as creative as wanted.

The difference is the following:

Put a beginner in front of a piano or give him a violin.

With the piano, one can start expressing himself quasi immediately, playing some note, some chords, creating some melody, some rhythm.
While the violin, youā€™ll need days and hours before you get something decent.

SC is like learning violin. Itā€™s though. Too though. Maybe that in the end it worth it but the learning journey is soooo complicated. I think actually that, unless this is your job or your paid for it, or you are a student with plenty of time, it doesnā€™t worth it.

Despite the hours spent on it since I started SC, Iā€™ve been able to produce only a 3ā€™ sounds that Iā€™m proud ofā€¦

SC is definitely, IMO, not a welcoming musical environment.
I wished it had a smoother and more rewarding learning-curve.

To belabor the metaphor - you can make notes and chords in a piano right away. But you can never find the notes in traditional Persian music. You can never even hear a pure fifth or bend a note!

That said, yes, I agree, SC should be more welcoming. Absolutely.

For me some simple roadblocks are lack of line numbers in stack traces. Node ordering. Inability to create classes without recompiling. Inconsistent syntax.

Efforts to make things easier: jitlib and the default keys in Pbind help somewhat. I use them less the farther I go.

Iā€™m one of few perhaps who find the SmallTalk roots of SC to be a plus. Iā€™d like to see some of the cool parts of SmallTalk that are broken in sclang restored: SmallTalk could modify itā€™s IDE during runtime and had an incredibly minimal syntaxā€¦

Anyhow I think thereā€™s a lot of room for a discussion on how to make SC less of a struggle to learn, I just think that prebuilding familiar musical materials or strategies is exactly not the right way to go. (And Iā€™m a pianist full disclosure)

1 Like

At risk of being immodest, I think my own efforts to make things easier might be more valuable to many incoming users even than jitlib.

Node ordering. What if there were a mixing framework where you could simply write sourceMixer.outbus = targetMixer and the groups would rearrange to ensure correct ordering (or establish a dependency without patching the signal, source.sendsSignalTo(target))? What if you could distinguish between play and playfx so that you donā€™t have to think about addToHead/Tail for effects? What if this also gave you easy volume/pan automation by control synths, and pre/postfader sends?

This exists! But an incoming user is unlikely to find it. So they struggle with groups, buses and node ordering, and then tell their friends that signal routing in SC is a massive pain but the common signal routing cases are already solved for 15 years now. In my work, I almost never have to worry about node ordering at all ā€“ the only time itā€™s a problem is when I have to ensure a specific order for multiple effect synths on the same mixer.

Mapping controls to multiple note synths, while more are being created? One of the many features of Voicer.

Thereā€™s a conflict here: usersā€™ preferred ways to do things may be highly personal. We donā€™t want to be prescriptive by endorsing one solution. But that puts users in the position of redesigning things that have already been done (but they didnā€™t know).

Here is a roadblock that maybe hasnā€™t been mentioned yet: lack of mid-level documentation. We teach the very basics (ā€œGetting Startedā€). We document the basic meaning of some percentage of classes and methods.

We donā€™t teach people how to write a typical subtractive or FM or wavetable synth, or standard effects (eq, compression, chorusā€¦) (i.e. we provide no Rosetta stone between VSTs and SC SynthDefs ā€“ and I donā€™t mean VSTPlugin).

We donā€™t teach how to organize signal flow (no Rosetta stone between DAWs and groups/buses). The Order of Execution helpfile is only one element of organizing signal routing but it isnā€™t a complete picture.

A Rosetta stone between musical notation or piano rolls is getting into that intensely personal territory, but perhaps we could agree that a lot of users would want to place sonic events in specific metrical positions and let the software work out the deltas. We donā€™t really teach how to do that.

We donā€™t do much at all to bridge the gap between SC and most peopleā€™s entry points into computer music. (But donā€™t worry, Pure Data does even lessā€¦ :laughing: )

hjh

Where ? Iā€™d love I found it before I started writing my own (very basic) mixer.

Totally agree. Or templates (in Office applications)/presets(in Synthesizer)/ā€¦ Something people could start with. Have the satisfaction from the begin to produce something. And then evolving towards more personal usage.

Quarks.install("ddwMixerChannel");

hjh

2 Likes