Loading a .sc file as a SynthDef

Hi all,

I’m trying to create a DX7 Engine using Raph Levien (& Pascal Gauthier) DX7 emulator.

I’m running into trouble with the ~mainCaller = ("./DX7.scd").loadRelative.wrapAt(-1); function.
I’ve changed it to an absolute path to start with

as seen here

~mainCaller = (“/home/we/dust/code/RX7/lib/DX7.scd”).load;`

But whenever I start up my norns I get

The following error
ERROR: syntax error, unexpected '~'
  in file '/home/we/dust/code/RX7/lib/RX7_Engine.sc'
  line 3 char 5:
      ~mainCaller = ("/home/we/dust/code/RX7/lib/DX7.scd").load;
      ^

It’s strange because if I null my engine by changing the suffix to .txt and let norns boot up regularly I can run that line of code in maiden and it seems to work. I can call the DX7.scd file by running ~mainCaller.value(80, 100, 10000); in maiden and it successfully plays a note.

Much appreciated.

The error seems to suggest that for whatever reason SuperCollider is not prepared to let you declare a global variable—that’s what the tilde represents. Try removing it from all of its appearances. Global variables make sense in SCIDE and even Maiden, since they persist across calls. Global variables make less sense in norns engines, since they persist across calls.

Thanks for the response.

That makes sense. I’ve tried making it a local variable but, it just does not want to bite.

Full Engine Here
Engine_RX7 : CroneEngine {

 var mainCaller = ("/home/we/dust/code/RX7/lib/DX7.scd").load;
 



// Supercollider DX7 Clone v1.0
// Implemented by Aziz Ege Gonul for more info go to www.egegonul.com
// Under GNU GPL 3 as per SuperCollider license


		
		
		
		

		// engine.NoteOn(nn,vel)
	this.addCommand("NoteOn", "if", {|msg|
			mainCaller.value(msg[1], msg[2], algo);
    });
    
    
    
		// engine.NoteOff(nn)
	this.addCommand("NoteOff", "i", {|msg|
     mainCaller.value(msg[1], 0);
    });
    
    
    
		
		// To change algorithm 
		
		this.addCommand("algo", "f", { arg msg;
			  algo = msg[1];
		 });

}

Hmm. What if instead you did something like this

Engine_RX7 : CroneEngine {
  var mainCaller;
  
  alloc {
    mainCaller = ("/home/we/dust/code/RX7/lib/DX7.scd").load;

    // the addCommands bit here
  }
}

That way the synthdef and the commands are loaded only when Engine_RX7’s alloc function is called on script init.

I’m basing my suggestions off of my own DX7-alike script, xD1—maybe the engine code might be helpful? You can find it here: xD1/Engine_xD1.sc at main · ryleelyman/xD1 · GitHub

1 Like

That did the trick!
I wonder why SC has a hard time defining the SynthDef on boot up…

Anyway, that’s an excellent workaround and definitely a standard I’ll follow for future engines.

well, I’m not sure why, but it’s definitely good computing etiquette to not load things that aren’t asked for!

2 Likes

the basic issue is that class variables can only be initializd to literals.

(the class definition cannot directly execute any interpreted code, it can only define variables and methods. no execution context exists when the class is compiled to bytecode.)

OkClass { 
  var foo = 2;
  var bar = "230426_084632";
}

BadClass { 
  var foo = 1 + 1;
  var bar = Date.getDate.stamp;
}

NotBadAnymore { 
  var foo;
  var bar;

  // class method to actually construct an object with `NotBadAnymore.new`
  *new { ^super.new.init; }

  init {
    // here a specific object is being initialized
    foo = 1 + 1;
    bar = Date.getDate.stamp;
  }
}
4 Likes

For things you really want to run as early as possible, there is initClass:

http://doc.sccode.org/Reference/initClass.html

3 Likes