SoundPetal icon indicating copy to clipboard operation
SoundPetal copied to clipboard

Different direction project now called SoundPetal

Open zeffii opened this issue 10 years ago • 16 comments

I've been playing with the idea to make FLOW a visual node interface for GNU GPL SuperCollider. SC already is a node based system of SynthDefs and Groups, based on Unit Generators. UGens can be routed into other UGens.

  • Blender can start services from Python (scserver)
  • sclang communicates with scsynth via OSC, so that's not a problem
  • dependency graph for FLOW is pretty stable,
  • Timing is handled by SC, (Blender / Pynodes only sends control info.)

The little experiments so far suggest that it will be possible but I will have to learn SC better first.

Here's a set of milestones I think will need to be completed in order:

  • [ ] starts scsynth (server) from SoundPetal
  • [ ] pipes Post Window from scynth to terminal / STD.out
  • [x] send predefined scd files to scsynth to test
  • [ ] SynthDef shell node (scripted node reappropriated)
    • I think this will involve straight single output for each ugen, where the output is only a string representation of all its settings.

ugens:

  • [ ] EnvGen
  • [x] SinOsc, FSinOsc, SiniOscFB
  • [x] SawOsc
  • [x] RLPF
  • [x] XLine, Line
  • [x] Blip

zeffii avatar Nov 05 '14 14:11 zeffii

image

Streamlining Node Interface, because there should be very little working code inside these node 'shells' all performance happens on SuperCollider's Server

zeffii avatar Nov 13 '14 12:11 zeffii

image

zeffii avatar Nov 13 '14 16:11 zeffii

this is essentially the in_class code now.

class UgenSinOsc(SoundPetalUgen):
    ''' UgenSinOsc '''
    bl_idname = 'UgenSinOsc'
    bl_label = 'SinOsc'
    sp_args = "(freq: 440, phase: 0, mul: 1, add: 0)"

    sp_rate = SoundPetalUgen.sp_rate

    def draw_buttons(self, context, layout):
        row = layout.row()
        row.prop(self, 'sp_rate', expand=True)

    def process(self):
        freq = self.inputs['freq'].fgetx()
        phase = self.inputs['phase'].fgetx()
        mul = self.inputs['mul'].fgetx()
        add = self.inputs['add'].fgetx()

        result = serialize(self, freq, phase, mul, add)
        self.outputs[0].fset(result)

I have not made sound yet.

zeffii avatar Nov 13 '14 18:11 zeffii

image

zeffii avatar Nov 13 '14 19:11 zeffii

further abstraction now to:

class UgenBlip(SoundPetalUgen):
    ''' UgenBlip '''
    bl_idname = 'UgenBlip'
    bl_label = 'Blip'
    sp_args = "(freq: 440, numharm: 200, mul: 1, add: 0)"

    sp_rate = SoundPetalUgen.sp_rate

    def process(self):
        if not len(self.inputs) == 4:
            return

        freq = self.inputs['freq'].fgetx()
        numharm = self.inputs['numharm'].fgetx()
        mul = self.inputs['mul'].fgetx()
        add = self.inputs['add'].fgetx()

        result = serialize(self, freq, numharm, mul, add)
        self.outputs[0].fset(result)

zeffii avatar Nov 13 '14 19:11 zeffii

will add a few more Ugens, including Line before attempting comms with ScSynth

zeffii avatar Nov 13 '14 19:11 zeffii

not sure how to deal with multichannel expansion.. looking forward to solving that.

zeffii avatar Nov 13 '14 19:11 zeffii

actually, most oscillator ugens can be written like

class UgenSinOsc(SoundPetalUgen):
    ''' UgenSinOsc '''
    bl_idname = 'UgenSinOsc'
    bl_label = 'SinOsc'
    sp_args = "(freq: 440, phase: 0, mul: 1, add: 0)"

    sp_rate = SoundPetalUgen.sp_rate

    def process(self):
        if not len(self.inputs) == 4:
            return

        result = serialize(self)
        self.outputs[0].fset(result)

zeffii avatar Nov 13 '14 19:11 zeffii

I think even the process function could be part of the superclass . if all that changes is the number of inputs to count before processing can take place

zeffii avatar Nov 13 '14 20:11 zeffii

woah

class UgenSawOsc(SoundPetalUgen):
    ''' UgenSawOsc '''
    bl_idname = 'UgenSawOsc'
    bl_label = 'Saw'
    sp_args = "(freq: 440, mul: 1, add: 0)"
    sp_rate = SoundPetalUgen.sp_rate


def register():
    bpy.utils.register_class(UgenSawOsc)


def unregister():
    bpy.utils.unregister_class(UgenSawOsc)

the rest is defined in the superclass SountPetalUgen

zeffii avatar Nov 13 '14 20:11 zeffii

included rounding on float types

zeffii avatar Nov 14 '14 07:11 zeffii

OK, Splay has this kind of argument list ar (inArray, spread: 1, level: 1, center: 0, levelComp: true), which the current codebase wont handle nicely. Time to rethink.

zeffii avatar Nov 14 '14 09:11 zeffii

still no sound, but have enough ugens now to start attempting a SynthDef gen

zeffii avatar Nov 14 '14 11:11 zeffii

image

zeffii avatar Nov 14 '14 11:11 zeffii

I'll take a break from this Addon for a while and focus on learning SC.

zeffii avatar Nov 21 '14 13:11 zeffii

I'm about 1/5 of where I want to be, while still a complete novice, the syntax is making more sense. I've started writing a note-to-self-reference

zeffii avatar Dec 03 '14 21:12 zeffii