Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Hanns Holger Rutz
    @Sciss
    Hey there. I have recreated this room from ScalaCollider/ScalaCollider to Sciss/ScalaCollider after noticing that creating an organisation for each of my projects would not make sense.
    Hanns Holger Rutz
    @Sciss
    Pushed v1.18.1 (soon to appear in Maven Central). This fixes a problem with server notification under the new SuperCollider v3.7.0
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI

    hello!
    got a little issue when running synth.Server

    i'm running on the v1.18.1 you just published but i got the same issue on v1.18.0

    it's not really an issue since it was working fine yesterday but now i get the "Exception in World_OpenUDP: unable to bind udp socket"

    i tried to found something like synth.Server.kill but i didn't found anything
    Hanns Holger Rutz
    @Sciss
    Yes, you have an orphaned scsynth process. If you are on a Unix like OS, you can execute killall scsynth in a terminal
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI

    good to know thank you!
    anyway thank you for the feedbacks it's very nice to be able to talk to you so easily.

    i'll ask you for further questions about UGens on the gitter but just to be clear. if we want to add extra UGens to your ScalaColliderUGens project we have to create a .xml configuration file right? i'm not sure that I understood everything on the readme..
    We try to add the VBAPUGens to sc3plugin to work with scalacollider but as i said the processus still looks blurry for me..

    So we have the .scx generated by supercollider but it doesn't work (as expected) :)

    Hanns Holger Rutz
    @Sciss
    Technically, you don't have to create xml files and run them through ScalaCollider-UGens/generator. But it has the advantage that we have the meta-data available, and if the API at any future point changes, the class files can still be regenerated. I am happy to add these files to the ScalaColliderUGens project. They would go, like other third-party, into https://github.com/Sciss/ScalaColliderUGens/tree/master/spec/src/main/resources/de/sciss/synth/ugen . Otherwise, you can just look at the generated output and write .scala files directly. In the xml case, have a look at https://github.com/Sciss/ScalaColliderUGens#generating-additional-ugen-class-files
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    So you are going to add them to the lib? If so do you want me to send you the VBAPUGen?
    I'm sorry my english is not so good..
    I don't really understand want you mean by "look at the generated output"
    Hanns Holger Rutz
    @Sciss
    As the readme of the -UGens project explains, you can run a particular task that takes an .xml input and generates .scala source code output. I'd say that is the preferred method to introduce new UGens. The "output" in this case is the .scala files; they are not written by hand but by a code generator. So if at some point I change the API, I don't have to rewrite hundreds of UGen .scala files, but just adapt the generator, perhaps make a few adjustments in the XML. However, for quick testing, you can take those generated .scala output files as a clue on how they look, and you could just copy + paste + edit them for new UGens, if you don't want to go through the process of defining the .xml files. If you come up with xml files for the VBAPUGen plugin, I am happy to include it with the project, so future updates will make the classes available. If you have specific questions about the meaning of the XML fields (they are explained a bit in the readme), I can help with that. Basically one xml file = one plugin (.scx file; collection of related ugens), although that organisation is not mandatory. TJUGens is an example for third-party plugins: https://github.com/Sciss/ScalaColliderUGens/blob/master/spec/src/main/resources/de/sciss/synth/ugen/TJUGens.xml
    Hanns Holger Rutz
    @Sciss

    The generated output is not part of the repository. But if you open the published jars, e.g. you open the sources.jar from http://search.maven.org/#artifactdetails|de.sciss|scalacolliderugens-core_2.11|1.14.0|jar - you will see all the .scala files thus produced. If you are using an IDE such as IntelliJ or Eclipse, you can probably also just jump from a symbol, say SinOsc to its source code (if you selected to include library source code in your project). So you get from this:

        <ugen name="SinOsc">
            <rate name="audio"/>
            <rate name="control"/>
            <arg name="freq" default="440.0">
                <doc>
                    frequency in Hertz
                </doc>
            </arg>
            <arg name="phase" default="0.0">
                <doc>
                    phase offset or modulator in radians
                </doc>
            </arg>
            <doc>
                <text>
                    A sinusoidal (sine tone) oscillator UGen.
                    This is the same as `Osc` except that it uses a built-in interpolating sine table of 8192 entries.
                </text>
                <see>ugen.Osc</see>
                <see>ugen.FSinOsc</see>
            </doc>
        </ugen>

    to this:

    /** A sinusoidal (sine tone) oscillator UGen. This is the same as `Osc` except that
      * it uses a built-in interpolating sine table of 8192 entries.
      * 
      * @see [[de.sciss.synth.ugen.Osc$ Osc]]
      * @see [[de.sciss.synth.ugen.FSinOsc$ FSinOsc]]
      */
    object SinOsc {
      def kr: SinOsc = kr()
    
      /** @param freq             frequency in Hertz
        * @param phase            phase offset or modulator in radians
        */
      def kr(freq: GE = 440.0f, phase: GE = 0.0f): SinOsc = new SinOsc(control, freq, phase)
    
      def ar: SinOsc = ar()
    
      /** @param freq             frequency in Hertz
        * @param phase            phase offset or modulator in radians
        */
      def ar(freq: GE = 440.0f, phase: GE = 0.0f): SinOsc = new SinOsc(audio, freq, phase)
    }
    
    /** A sinusoidal (sine tone) oscillator UGen. This is the same as `Osc` except that
      * it uses a built-in interpolating sine table of 8192 entries.
      * 
      * @param freq             frequency in Hertz
      * @param phase            phase offset or modulator in radians
      * 
      * @see [[de.sciss.synth.ugen.Osc$ Osc]]
      * @see [[de.sciss.synth.ugen.FSinOsc$ FSinOsc]]
      */
    final case class SinOsc(rate: Rate, freq: GE = 440.0f, phase: GE = 0.0f) extends UGenSource.SingleOut {
      protected def makeUGens: UGenInLike = unwrap(Vector(freq.expand, phase.expand))
    
      protected def makeUGen(_args: Vec[UGenIn]): UGenInLike = UGen.SingleOut(name, rate, _args)
    }
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI

    ok so i came up with a partial xml file for VBAPUgen.
    The VBAPUgen contains 3 classes : VBAP, VBAPSpeaker and VBAPSpeakerArray
    VBAPSpeaker and VBAPSpeakerArray only have new() method. what would be the equivalent for the generator to understand on the xml.

    <ugens revision="1"> 
        <ugen name="VBAP">
            <rate name="audio"/>
            <rate name="control"/>
            <arg name="numChans">
                <doc>
                    the number of output channels
                </doc>
            </arg>
            <arg name="in">
                <doc>
                    the input to be panne
                </doc>
            </arg>
            <arg name="bufnum">
                <doc>
                    a buffer or it's bufnum containing data calculated by an instance of VBAPSpeakerArray
                    it's number of channels must correspond to numChans above
                </doc>
            </arg>
            <arg name="azimuth" default="0">
                <doc>
                    +/- 180° from the medium plane
                </doc>
            </arg>
            <arg name="elevation" default="1">
                <doc>
                    +/- 90° from the azimuth plane
                </doc>
            </arg>
            <arg name="spread" default="0">
                <doc>
                    A value from 0-100. When 0, if the signal is panned exactly to a speaker location the signal is only on that speaker.
                    At values higher than 0, the signal will always be on more than one speaker.
                    This can smooth the panning effect by making localisation blur more constant.
                </doc>
            </arg>
        </ugen>
    </ugens>

    And also i have issue trying to generate from sbt this way :
    $ sbt
    $ project scalacolliderugens-gen

    my terminal says :

    project scalacolliderugens-gen
    [error] Not a valid project ID: scalacolliderugens-gen

    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    never mind for the last part
    Hanns Holger Rutz
    @Sciss
    Ok. Hey, auxiliary classes is a problem to represent in the XML at the moment. Klang being another one, so I have a hand written KlangSpec. The XML really just has the UGens. Their arguments are either scalar values, e.g. Int for determining the number of channels (In.ar) or they are graph elements GE. So if your custom aux types can be converted to GE then this approach works. It's not optimal in terms of type-safety, but good enough IMO. Let me have a look at the original VBAP source to refresh my memory
    Hanns Holger Rutz
    @Sciss
    Alright. So basically you just need the meta data for VBAP, like you pasted above. The other classes it appears are only auxiliary classes, for example to calculate speaker angles and such, and are never directly used by the UGen class - if I'm not mistaken. So in order to use the UGen, you just need VBAP. If you want to use the functions of say VBAPSpeakerSet available from Scala, you'll have to translate that class. It's independent of ScalaCollider. Let me know if you need help with this.
    It would be good to have VBAP and some other commonly used 3rd party UGens available in ScalaCollider.
    Hanns Holger Rutz
    @Sciss
    Ajajajaj that class VBAPSpeakerArray is a mess
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    I was waiting for this reaction on VBAPSpeakerArray haha! And actually that's the one we absolutely need! we now work on a 4.1 soul system and we have no choice but create a SpeakerArray of 4 directional speakers and a point one (the sub). I Started trying switching sc to scala code but my scala skills are not good enough yet. I come from Java progr
    *sorry
    programming so them i was thinking of recode it in java and use it as a class but i'm not sure it would be compatible to scala classes
    anyway maths are a mess in java also
    Hanns Holger Rutz
    @Sciss
    I'm looking into it. Problem is this code was translated originally from C to a python'ish SuperCollider. But it should be possible
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    I like people not frightened by challenges :)
    You think of using your generator?
    Because recoding it in scala sounds like a loss time
    Hanns Holger Rutz
    @Sciss
    No, that needs manual rewriting. I'm almost done
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    alright :)
    Hanns Holger Rutz
    @Sciss
    Have to remember how to install the plugins ;)
    Hanns Holger Rutz
    @Sciss
    I'm pushing a new version 1.14.1 of ScalaCollider-UGens that contains the VBAP plugin (in sub-project scalacolliderugens-plugins!). An example is included in the doc of VBAP.
    Hanns Holger Rutz
    @Sciss
    // 8 channel ring
    val a = VBAPSetup(2, Seq(0, 45, 90, 135, 180, -135, -90, -45))
    
    val b = Buffer.alloc(s, a.bufferData.size)
    b.setn(a.bufferData)
    
    val x = play {
      val azi = "azi".kr(0)
      val ele = "ele".kr(0)
      val spr = "spr".kr(0)
      VBAP.ar(8, PinkNoise.ar(0.2), b.id, azi, ele, spr)
    }
    
    // test them out
    x.set("azi" -> a.directions(1).azi)
    x.set("azi" -> a.directions(2).azi)
    x.set("azi" -> a.directions(3).azi)
    // ...
    x.set("azi" -> a.directions(7).azi)
    x.set("azi" -> a.directions(0).azi)
    
    // try the spread
    x.set("spr" -> 20)
    x.set("spr" -> 100) // all speakers
    
    x.free(); b.free();
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI

    that works fine! thank you for this update.

    just a quick question.. I realized that release(float) works on your Swing app but i can't get it from the lib in my code.
    ```

    if (value == 1) Synth.play(ssa.name)
              if (value == 2) {
                ssa release(2)
                println("recu 2")
              }
    Hanns Holger Rutz
    @Sciss

    After I created 'transactional' systems based on ScalaCollider, I wanted to remove the plain side-effecting methods from the basic API. The basic API just supports generating the OSC message; when you call a method such as synth.set(...) or synth.free(...), this is facilitated by an additional import de.sciss.synth.Ops._. So when you look at the README, you have this preamble:

    import de.sciss.synth._
    import ugen._
    import Ops._

    The last import makes the side-effects available. The docs are here: https://sciss.github.io/ScalaCollider/latest/api/#de.sciss.synth.Ops$ - so for release, that is NodeOps: https://sciss.github.io/ScalaCollider/latest/api/#de.sciss.synth.Ops$$NodeOps

    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    ok got it
    had to assign the SynthDef to a new var Synth and apply the release() to the Synth and not the SynthDef
    great thanks
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    server.run(cfg) { serv =>
    
              var synth = Synth()
              ssa.recv(serv)    //previous SynthDef
    
              receiver.action = {
                case (m@osc.Message("/test", value: Int), s) =>
                  if (value == 1) synth = Synth.play(ssa.name)
                  if (value == 2) println("recu 2"); synth.release(2.0)  //synth.free()
              }
    }
    compilation is ok, free() works fine, but release() has no action still :/
    n-chatzi
    @n-chatzi
    Same here. release() does not work for a Synth from a SynthDef. But it works on a var synth = play{...} What type is synth implicitly assigned to here?
    sorry thats val synth = play {}
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    actually in the supercollider doc, release is applied to the Synth's superclass Node
    so logically it could be applied to Synth. idk i'm kinda lost haha
    Hanns Holger Rutz
    @Sciss

    That's the same as in SuperCollider - using play { } will add an envelope that has a control gate that is used by release. release is just a convention for synth.set("gate" -> -1 - releaseTime) (or similar). So if you want to add a similar kind of envelope to a SynthDef you either have to create an EnvGen with a gate argument, or you use the pseudo-UGen WrapOut instead (that's the thing that play {} uses):

    SynthDef.recv("test") {
      val sig = WhiteNoise.ar(Seq(0.2, 0.2))
      WrapOut(sig)  // !
    }
    
    val x = Synth.play("test")
    x.release(10)

    WrapOut creates controls "out" (for bus) and "gate" (for release)

    n-chatzi
    @n-chatzi
    Thanks, so play{} implicitly adds a control gate which is released
    Hanns Holger Rutz
    @Sciss
    exactly
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    is it possible to write a SynthDef passing the VBAP Buffer on a textile? I feel like when reading it SCsynth doesn't recognize the live
    lib* exception in GraphDef_Recv: UGen 'VBAP' not installed.
    val a = VBAPSetup(2, Seq(Polar(-60,0), Polar(60,0), Polar(110,0), Polar(-110,0), 3.35))
    val b = Buffer.alloc(serv, a.bufferData.size)
    b.setn(a.bufferData)
    
    SynthDef.write("synthTest.txt", MySynths.load(b), 1)
    synthDefs = SynthDef.read("synthTest.txt")
    
    val ssa = synthDefs.find(_.name == "soudscape-1").get
    ssa.recv(serv)
    MySynths.load(Buffer) loads a Seq[SynthDef]to store
    Hanns Holger Rutz
    @Sciss
    The exception says the VBAP plugin is not installed. If this works from the SuperCollider IDE, my guess is you have more than one SuperCollider installation and the server you use from Scala does not have access to sc3-plugins. The error message has nothing to do with writing the synth-def to hard-disk or not. I don't understand what you mean by 'on a textile'?
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    yes sorry i meant text file :)
    Hanns Holger Rutz
    @Sciss
    You should be able to write a synth def and load it onto the server. write will always write in the standard binary format of SuperCollider. Therefore, this is not a "text file".
    val sd = SynthDef("test") { ... }
    sd.write(dir = "my-dir")
    SynthDef.load(path = "my-dir/test.scsyndef")
    // ... synchronise! then
    Synth.play("test")
    The buffer required by VBAP you have to allocate and fill again explicitly, resources such as buffers are never stored with a synth def.
    Pierre-Alexandre ADAMSKI
    @PierreAlexandreADAMSKI
    so when i do the following it is not stored?
    WrapOut(FreeVerb.ar(VBAP.ar(4, sig, buffer.id, LFSaw.kr(0.1).madd(90, 90)), wet, rmz, dmp)*amp)