Ways to improve my "real" synth simulation?

I’m working on a university project on how to use SC to synthesize some data I get, into a realistic sound from various instruments, for now it works somewhat well, but I wanted to ask the community if I can optimize it in some way so that it works better (I run out of memory many times) when there are too many frequencies the program crashes or I have many problems recording the result, please help (╥﹏╥)

Server.killAll;

s.boot;
s.options.sampleRate = 48000;
s.recSampleFormat = "int32";
s.options.memSize = 32*8192

//s.record
//s.stopRecording



(
Routine({
	s.record("/positive.wav",duration:20);
	wait(0.1);
{var frequencies = [1.329824, 4.321928, 7.314032, 9.308769, 11.968417, 13.630697, 18.285081, 19.947361, 38.564898, 481.728771, 486.050700, 496.356836, 499.348940, 532.926998, 567.502424, 583.127857, 773.292700, 775.952348, 794.569885, 943.510181, 950.491758, 980.745256, 985.399640, 994.375952, 997.035600, 1000.027705, 1032.940851, 1121.374152, 1124.033800, 1140.989057, 1154.287297, 1174.567115, 1184.208339, 1250.699543, 1274.303920, 1282.615321, 1294.251281, 1301.565314, 1303.560050, 1344.452140, 1367.391605, 1369.718798, 1500.041557, 1549.577504, 1561.545920, 1584.152930, 1589.472226, 1683.224823, 1756.365148, 1774.982685, 1957.501039, 1981.770328, 2002.715057, 2124.393960, 2158.304474, 2161.296578, 2500.069262, 2565.895553, 2624.407813, 2806.261255, 2813.907743, 2815.902480, 2865.770882, 2868.762987, 2871.090179, 2916.969109, 2918.631389, 2921.955950, 3000.083114, 3037.983100, 3044.632221, 3243.773376, 3295.968971, 3311.594404, 3368.444383, 3419.642610, 3502.424158, 3543.316249, 3565.923258, 3582.878515, 3589.195179, 3606.150436, 3609.474997, 3633.744286, 3642.388142, 3692.256545, 3740.462668, 3747.776700, 3847.181050, 3868.458235, 3919.656462, 4022.052916, 4037.678349, 4042.997645, 4049.979221, 4058.623078, 4222.523895, 4249.785289, 4266.075634, 4368.804544, 4399.722953, 4499.127303, 4606.178141, 4642.748303, 4695.941266, 4723.867572, 4878.792076, 4903.726278, 5077.268320, 5788.724200, 5839.922427, 5912.730295, 5964.925890, 6289.070508, 6657.099321];
 var amplitudes = [0.101696, 0.049795, 0.054296, 0.044215, 0.030289, 0.017742, 0.011820, 0.019873, 0.006103, 0.072020, 0.039964, 0.121973, 0.923403, 0.020790, 0.016751, 0.023896, 0.029381, 0.051165, 0.043558, 0.064251, 0.041908, 0.847759, 0.205845, 0.134188, 0.322230, 1.000000, 0.019545, 0.152089, 0.018394, 0.010405, 0.012449, 0.037262, 0.284223, 0.006635, 0.101414, 0.022723, 0.051148, 0.122155, 0.388880, 0.012376, 0.005857, 0.006551, 0.009901, 0.009080, 0.055301, 0.022191, 0.007166, 0.007690, 0.007902, 0.012198, 0.010469, 0.021518, 0.011204, 0.038732, 0.033377, 0.007911, 0.014466, 0.011212, 0.007500, 0.011521, 0.018482, 0.011950, 0.081531, 0.073321, 0.071157, 0.049759, 0.027232, 0.037514, 0.007648, 0.011703, 0.014786, 0.160931, 0.010681, 0.010455, 0.053765, 0.029295, 0.006271, 0.006364, 0.018121, 0.010338, 0.011644, 0.022697, 0.017555, 0.015951, 0.013147, 0.005663, 0.017332, 0.027455, 0.008753, 0.007595, 0.006109, 0.008318, 0.064482, 0.011233, 0.007931, 0.006260, 0.006533, 0.008775, 0.009326, 0.005420, 0.011876, 0.006324, 0.005714, 0.005128, 0.006403, 0.006522, 0.006493, 0.011139, 0.005362, 0.020800, 0.007724, 0.006859, 0.005202, 0.005806, 0.005733
];


  var signal = Mix.fill(frequencies.size, { |i|
        //posicionamiento central
        Pan2.ar(SinOsc.ar(frequencies[i], 0, amplitudes[i]),pos: 0.0, level: 0.5)
    });

var env = EnvGen.ar(
	envelope: Env.new(
		levels: [0.000972, 0.000847, 0.000789, 0.000752, 0.000705, 0.000727, 0.000767, 0.000756, 0.000720, 0.000716, 0.000704, 0.000673, 0.000789, 0.000940, 0.001035, 0.001065, 0.001074, 0.001032, 0.000942, 0.000820, 0.309120, 0.284854, 0.312766, 0.189330, 0.254038, 0.239966, 0.176438, 0.149255, 0.208320, 0.164643, 0.143789, 0.150347, 0.111246, 0.119986, 0.135989, 0.083813, 0.078363, 0.088786, 0.057458, 0.062038, 0.058851, 0.042084, 0.042660, 0.044310, 0.037952, 0.035536, 0.033584, 0.027949, 0.028164, 0.024015, 0.022330, 0.023050, 0.022785, 0.017683, 0.019141, 0.020378, 0.019799, 0.018210, 0.017888, 0.017680, 0.019859, 0.018704, 0.015298, 0.015179, 0.013664, 0.013813, 0.012572, 0.012345, 0.013801, 0.011278, 0.011421, 0.012176, 0.010898, 0.009606, 0.007935, 0.008728, 0.007531, 0.007138, 0.007128, 0.006383, 0.006448, 0.005159, 0.005348, 0.006614, 0.005988, 0.005704, 0.006498, 0.007813, 0.006916, 0.005970, 0.006371, 0.006424, 0.005329, 0.005056, 0.005168, 0.005150, 0.005235, 0.005190, 0.005126, 0.004606, 0.004485, 0.004468, 0.005363, 0.005242, 0.004963, 0.004330, 0.003458, 0.002854, 0.002745, 0.003348, 0.003461, 0.003891, 0.003790, 0.003297, 0.003651, 0.003518, 0.002894, 0.003527, 0.003642, 0.003291, 0.003152, 0.003070, 0.003174, 0.003925, 0.003969, 0.004418, 0.004878, 0.005217, 0.005255, 0.004932, 0.003932, 0.004315, 0.004364, 0.004099, 0.003986, 0.003656, 0.003280, 0.003358, 0.002902, 0.002482, 0.002808, 0.003231, 0.003009, 0.002630, 0.002496, 0.002298, 0.001656, 0.001821, 0.002653, 0.002735, 0.002745, 0.002679, 0.002505, 0.002535, 0.002675, 0.002523, 0.002172, 0.002090, 0.001321, 0.000886, 0.000319, 0.000000, 0.000643, 0.001650, 0.003207, 0.003769, 0.003937],
		times: [0.002667, 0.001542, 0.002688, 0.003583, 0.002250, 0.001583, 0.001250, 0.002021, 0.003438, 0.000958, 0.003688, 0.002729, 0.002542, 0.002042, 0.000500, 0.002729, 0.001688, 0.002167, 0.002146, 0.003625, 0.006167, 0.015146, 0.010146, 0.017646, 0.000875, 0.021313, 0.017625, 0.010104, 0.016104, 0.026771, 0.009146, 0.022271, 0.027729, 0.006000, 0.026146, 0.023813, 0.010063, 0.026125, 0.022000, 0.032084, 0.020208, 0.023771, 0.026084, 0.026125, 0.016042, 0.026104, 0.032084, 0.010104, 0.018479, 0.025459, 0.006042, 0.026063, 0.016083, 0.032188, 0.009979, 0.036229, 0.010021, 0.040104, 0.018125, 0.014000, 0.032146, 0.030146, 0.042167, 0.016042, 0.056209, 0.032104, 0.030104, 0.016083, 0.030146, 0.070396, 0.003875, 0.040167, 0.030209, 0.030188, 0.058167, 0.010104, 0.046146, 0.030125, 0.014167, 0.044021, 0.046271, 0.050188, 0.014042, 0.036250, 0.050188, 0.042104, 0.012125, 0.024125, 0.054167, 0.026104, 0.010083, 0.030104, 0.060230, 0.014146, 0.038084, 0.006083, 0.046167, 0.003896, 0.038313, 0.003896, 0.036146, 0.016167, 0.016063, 0.018021, 0.020063, 0.020167, 0.020042, 0.036250, 0.014000, 0.020083, 0.016042, 0.010083, 0.034104, 0.014042, 0.010042, 0.014063, 0.030167, 0.016104, 0.007938, 0.022125, 0.014063, 0.022021, 0.014083, 0.014042, 0.016125, 0.010042, 0.014021, 0.018021, 0.006146, 0.025979, 0.014042, 0.004083, 0.010083, 0.010021, 0.016083, 0.014063, 0.003958, 0.012083, 0.024063, 0.010042, 0.010083, 0.003958, 0.012000, 0.014125, 0.006229, 0.013917, 0.020083, 0.009979, 0.006125, 0.014021, 0.001979, 0.018063, 0.003958, 0.010000, 0.002146, 0.011979, 0.006104, 0.009958, 0.006167, 0.012021, 0.008021, 0.016000, 0.008146, 0.009833, 0.006188, 0.003917],
		curve: 'sin'

	), doneAction: 1);
    signal = signal * env;
      Out.ar(0, signal);
}.play;

}).play;
)

signal.release(1);


s.quit;
1 Like

Hello,

Where does this data, and this lookup table, come from? It sounds good.

Your code creates Synths with hundreds of UGens. But not much CPU here. How much memory is it consuming in your machine? Maybe it’s because of the recording part?

Hi!
I get data from another python code that I made, where I extract it from a small instrumental recording, and as you say when I was monitoring the resources of the PC SC does not spend much but still at the moment before starting the recording sometimes when I have many frequencies or more complex envelopes this one crashes and throws me without enough memory inside the program and I have to kill the server and restart server

first you can move the Pan2.ar outside the Mix.fill - this reduces the number of UGens by about a third…

var signal = Pan2.ar(
	Mix.fill(frequencies.size, { |i|
		//posicionamiento central
		SinOsc.ar(frequencies[i], 0, amplitudes[i])
	}), 0, level:0.5 
);

on my system though

		Klang.ar(`[frequencies, amplitudes])

is even more more efficient.

note that for tweaking the memsize of the server changes only takes effect on reboot. So if you run the code above right after starting sclang you will be using the default memsize (unless you have specified soomething different in your startup.scd. 32*8192k is not so big - I use 2**20 atm…you can also try increasing the number of wirebufs…

and finally, for your particular sound you could also precompute all the sinewaves and put them in a Buffer for playback.

First Wavetable.sineFill then Buffer.loadCollection finally PlayBuf.ar

2 Likes

A strategy often used to improve the computational efficiency of modal synthesizers is to omit quieter partials inaudible due to auditory masking.

4 Likes

I haven’t seen any change in memory use in my machine (checked just looking at htop). I’m not sure what the problem is.

I also made a variant that increases the number of UGens, which hasn’t changed much either.

  var signal = Mix.fill(frequencies.size, { |i|
        //posicionamiento estéreo con salsa
            Pan2.ar(SinOsc.ar(frequencies[i], rrand(-pi,pi), amplitudes[i] + LFNoise2.ar(2, Line.kr(0.8, 0, 5))),pos: rrand(-0.6,0.6), level: 0.5)
    });

EDIT: Maybe the problem is how you’re scheduling SynthDef, Synth creation and Recording? I feel your synthesis code should not be a problem with today’s computers.

for example i increased the ugen generators (well like 1000 now) and this was the error (I used 2**20 and SC closed):

FAILURE IN SERVER /s_new alloc failed, increase server’s memory allocation (e.g. via ServerOptions)

I tried to implement klang but it seems that I have skills issue since I couldn’t get it to work, I will try

Wavetable.sineFill

, thank you very much

Is there an equivalent in SC to do it in between?

  • real-time extracting partials in the flow of time and return as an array
  • extracting partials of a sound file.

@Sadskyg
How did you extract the each partial with amplitude and envelope in python?

1 Like