Latest News: u-he releases Sugar and Spice for Hive 2
Additive synthesis in Zebra
- KVRAF
- Topic Starter
- 5234 posts since 25 Feb, 2008
Would it be possible to take a spectrograph such as this:
http://media.soundonsound.com/sos/oct03 ... rum1.l.jpg
and transpose it to Zebra?
I presume that the max. amplitude of partials in Spectroblend mode follows the 1/n rule (so that the second partial's max amplitude is 1/2 of the fundamental's, the third 1/3.. etc), whereas the partials on a spectrograph are all measured relative to the same amplitude, which would make transposition by eye difficult.
Any ideas?
http://media.soundonsound.com/sos/oct03 ... rum1.l.jpg
and transpose it to Zebra?
I presume that the max. amplitude of partials in Spectroblend mode follows the 1/n rule (so that the second partial's max amplitude is 1/2 of the fundamental's, the third 1/3.. etc), whereas the partials on a spectrograph are all measured relative to the same amplitude, which would make transposition by eye difficult.
Any ideas?
- KVRAF
- 23110 posts since 7 Jan, 2009 from Croatia
That sounds exactly like the task for Spectroblend mode.
- KVRAF
- Topic Starter
- 5234 posts since 25 Feb, 2008
Only if there's some way of getting a reasonable approximation for the relative amplitudes of the partials, and if they're quite different scales that might be rather difficult.
- KVRAF
- 5223 posts since 20 Jul, 2010
There aren't enough markings on the graph to go on... If it's a flute I'm guessing those are odd harmonics. From there I don't think it's much of a stretch to try copying that graph into the spectroblend editor, making sure to leave exactly one gap between each bar. The spectroblend editor IS famously fiddly to edit, though... I find it helps if you change the GUI size to something much larger.
http://sendy.bandcamp.com/releases < My new album at Bandcamp! Now pay what you like!
- KVRAF
- Topic Starter
- 5234 posts since 25 Feb, 2008
Here's the text that goes with the spectrum:Sendy wrote:There aren't enough markings on the graph to go on... If it's a flute I'm guessing those are odd harmonics.
"Figure 7 (above) shows the spectrum of a low note such as the bottom 'C'.
Played with moderate force, it is rich in harmonics, with strong contributions from the second, third and fourth harmonics, followed by a reasonably '1/n'-like shape from the fourth upward, until the spectrum disappears"
From there I don't think it's much of a stretch to try copying that graph into the spectroblend editor, making sure to leave exactly one gap between each bar.
You're missing the point about the relative maximum amplitudes of the partials in Spectroblend mode - they seem to follow a 1/n rule such that the max amplitude of the second harmonic is 1/2 of the first, the third is 1/3, and so on. In other words, the amplitude scale is different for each partial.
This does not appear to be the case with the graph for the flute spectrum - here the amplitudes of the partials are measured against the same scale.
It is this difference in scale that makes even approximating that particular spectrum in Spectroblend difficult.
-
- KVRAF
- 3817 posts since 8 Mar, 2006
A bit in a rush .. dunno if I understood correctly but you can approximately draw in the partials using the OSC spectroblend mode and use OSCFX like expander or scale or a combination of both. .... sync also helps I guess as it "transposes" harmonically.hakey wrote:Would it be possible to take a spectrograph such as this:
http://media.soundonsound.com/sos/oct03 ... rum1.l.jpg
and transpose it to Zebra?
I presume that the max. amplitude of partials in Spectroblend mode follows the 1/n rule (so that the second partial's max amplitude is 1/2 of the fundamental's, the third 1/3.. etc), whereas the partials on a spectrograph are all measured relative to the same amplitude, which would make transposition by eye difficult.
Any ideas?
-
- KVRAF
- 3817 posts since 8 Mar, 2006
..hmm I think I get what you are saying but unfortunately I don't know a way around this. ....or some clever combination using the choplift OSCFX?hakey wrote: You're missing the point about the relative maximum amplitudes of the partials in Spectroblend mode - they seem to follow a 1/n rule such that the max amplitude of the second harmonic is 1/2 of the first, the third is 1/3, and so on. In other words, the amplitude scale is different for each partial.
- KVRAF
- 4130 posts since 11 Aug, 2006 from Texas
It's quite possible and in fact pretty simple once you know the trick.
Leveraging on billstei's hard work with blueberry thing I spent some time examining his GNU Octave scripts. At the end of the day you have a template that looks like:
I wrote a simple python program that generates the sequence you mentioned, 1/1, 1/2, 1/3...1/128:
Which generates output:
Now if you save that as a regular zebra preset. Next change OSC1 mode to Spectroblend. Now load the preset in in Zebra you'll see the current preset has changed and the spectroblend waveform 1 to your harmonic sequence:
It's quite simple to extrapolate on this to generate all sorts of programatic partial sequences. You can even run them by hand if you're really serious about getting that sequence exact.
---
Notes: I have no idea about the precision of Zebra so I stuck with billstei's usage of 4 significant digits. I also did not invert the wave into the negative domain but it would be possible to do so. With a little knowledge of programming you should be able to make reasonable guesses as to what to change in the .h2p script to set OSC2 or waveform 3 or even change the type.
Is's also likely that the actually generation of the values 1/n can be done by the .h2p scripting interface; I just used python because I know the syntax and was able to quickly copy billstei's wavetable template.
---
billstei, if you're still around KVR I miss your wacky and informative posts. Please come back.
Leveraging on billstei's hard work with blueberry thing I spent some time examining his GNU Octave scripts. At the end of the day you have a template that looks like:
Code: Select all
#defaults=no
#patchname=no
<?
int OSC_WAVEFORM_SPECTROBLEND = 3;
int i;
float w1[128];
w1[0]=1.000;
.......
w1[127]=0.002;
for( i = 1; i <= 1; i++ )
{
if (Oscillator[i].WaveForm == OSC_WAVEFORM_SPECTROBLEND)
{
Oscillator[i].WaveTable.set(1,w1);
}
}
?>
Code: Select all
#!/usr/bin/env python
import sys
fmt_head = """
#defaults=no
#patchname=no
<?
int OSC_WAVEFORM_SPECTROBLEND = 3;
int i;
float w1[128];
"""
fmt_el = "w1[%d]=%.03f; "
fmt_foot = """
for( i = 1; i <= 1; i++ )
{
if (Oscillator[i].WaveForm == OSC_WAVEFORM_SPECTROBLEND)
{
Oscillator[i].WaveTable.set(1,w1);
}
}
?>
"""[:-1]
if __name__ == "__main__":
w = sys.stdout.write
w(fmt_head)
for n in range(0,128):
partial = 1.0 / (n + 1)
w(fmt_el % (n, partial))
if n > 0 and n % 8 == 0:
w("\n")
w(fmt_foot)
Code: Select all
#defaults=no
#patchname=no
<?
int OSC_WAVEFORM_SPECTROBLEND = 3;
int i;
float w1[128];
w1[0]=1.000; w1[1]=0.500; w1[2]=0.333; w1[3]=0.250; w1[4]=0.200; w1[5]=0.167; w1[6]=0.143; w1[7]=0.125; w1[8]=0.111;
w1[9]=0.100; w1[10]=0.091; w1[11]=0.083; w1[12]=0.077; w1[13]=0.071; w1[14]=0.067; w1[15]=0.062; w1[16]=0.059;
w1[17]=0.056; w1[18]=0.053; w1[19]=0.050; w1[20]=0.048; w1[21]=0.045; w1[22]=0.043; w1[23]=0.042; w1[24]=0.040;
w1[25]=0.038; w1[26]=0.037; w1[27]=0.036; w1[28]=0.034; w1[29]=0.033; w1[30]=0.032; w1[31]=0.031; w1[32]=0.030;
w1[33]=0.029; w1[34]=0.029; w1[35]=0.028; w1[36]=0.027; w1[37]=0.026; w1[38]=0.026; w1[39]=0.025; w1[40]=0.024;
w1[41]=0.024; w1[42]=0.023; w1[43]=0.023; w1[44]=0.022; w1[45]=0.022; w1[46]=0.021; w1[47]=0.021; w1[48]=0.020;
w1[49]=0.020; w1[50]=0.020; w1[51]=0.019; w1[52]=0.019; w1[53]=0.019; w1[54]=0.018; w1[55]=0.018; w1[56]=0.018;
w1[57]=0.017; w1[58]=0.017; w1[59]=0.017; w1[60]=0.016; w1[61]=0.016; w1[62]=0.016; w1[63]=0.016; w1[64]=0.015;
w1[65]=0.015; w1[66]=0.015; w1[67]=0.015; w1[68]=0.014; w1[69]=0.014; w1[70]=0.014; w1[71]=0.014; w1[72]=0.014;
w1[73]=0.014; w1[74]=0.013; w1[75]=0.013; w1[76]=0.013; w1[77]=0.013; w1[78]=0.013; w1[79]=0.013; w1[80]=0.012;
w1[81]=0.012; w1[82]=0.012; w1[83]=0.012; w1[84]=0.012; w1[85]=0.012; w1[86]=0.011; w1[87]=0.011; w1[88]=0.011;
w1[89]=0.011; w1[90]=0.011; w1[91]=0.011; w1[92]=0.011; w1[93]=0.011; w1[94]=0.011; w1[95]=0.010; w1[96]=0.010;
w1[97]=0.010; w1[98]=0.010; w1[99]=0.010; w1[100]=0.010; w1[101]=0.010; w1[102]=0.010; w1[103]=0.010; w1[104]=0.010;
w1[105]=0.009; w1[106]=0.009; w1[107]=0.009; w1[108]=0.009; w1[109]=0.009; w1[110]=0.009; w1[111]=0.009; w1[112]=0.009;
w1[113]=0.009; w1[114]=0.009; w1[115]=0.009; w1[116]=0.009; w1[117]=0.008; w1[118]=0.008; w1[119]=0.008; w1[120]=0.008;
w1[121]=0.008; w1[122]=0.008; w1[123]=0.008; w1[124]=0.008; w1[125]=0.008; w1[126]=0.008; w1[127]=0.008;
for( i = 1; i <= 1; i++ )
{
if (Oscillator[i].WaveForm == OSC_WAVEFORM_SPECTROBLEND)
{
Oscillator[i].WaveTable.set(1,w1);
}
}
?>
It's quite simple to extrapolate on this to generate all sorts of programatic partial sequences. You can even run them by hand if you're really serious about getting that sequence exact.
---
Notes: I have no idea about the precision of Zebra so I stuck with billstei's usage of 4 significant digits. I also did not invert the wave into the negative domain but it would be possible to do so. With a little knowledge of programming you should be able to make reasonable guesses as to what to change in the .h2p script to set OSC2 or waveform 3 or even change the type.
Is's also likely that the actually generation of the values 1/n can be done by the .h2p scripting interface; I just used python because I know the syntax and was able to quickly copy billstei's wavetable template.
---
billstei, if you're still around KVR I miss your wacky and informative posts. Please come back.
Last edited by bmrzycki on Sun Sep 25, 2011 10:50 pm, edited 1 time in total.
- KVRAF
- 4130 posts since 11 Aug, 2006 from Texas
Ok, I opened the original image you had shown with Paint.NET and treated the tallest harmonic as being 1.0. Measuring the length of the red bars I got the following (resolution in pixels):
1 = 142 / 160 = 0.887
2 = 160 / 160 = 1.0
3 = 150 / 160 = 0.938
4 = 160 / 160 = 1.0
I then modified the main loop of the python program:
And generated a new preset:
Which looks like:
1 = 142 / 160 = 0.887
2 = 160 / 160 = 1.0
3 = 150 / 160 = 0.938
4 = 160 / 160 = 1.0
I then modified the main loop of the python program:
Code: Select all
if __name__ == "__main__":
w = sys.stdout.write
w(fmt_head)
# Specify first 3 partials by hand (zero indexed)
w(fmt_el % (0, 142.0/160))
w(fmt_el % (1, 160.0/160))
w(fmt_el % (2, 150.0/160))
w("\n")
# Partials 4 - 128 follow the 1/n algorithm
for n in range(3,128):
partial = 1.0 / (n - 2)
w(fmt_el % (n, partial))
if n > 0 and n % 8 == 0:
w("\n")
w(fmt_foot)
Code: Select all
#defaults=no
#patchname=no
<?
int OSC_WAVEFORM_SPECTROBLEND = 3;
int i;
float w1[128];
w1[0]=0.887; w1[1]=1.000; w1[2]=0.938;
w1[3]=1.000; w1[4]=0.500; w1[5]=0.333; w1[6]=0.250; w1[7]=0.200; w1[8]=0.167;
w1[9]=0.143; w1[10]=0.125; w1[11]=0.111; w1[12]=0.100; w1[13]=0.091; w1[14]=0.083; w1[15]=0.077; w1[16]=0.071;
w1[17]=0.067; w1[18]=0.062; w1[19]=0.059; w1[20]=0.056; w1[21]=0.053; w1[22]=0.050; w1[23]=0.048; w1[24]=0.045;
w1[25]=0.043; w1[26]=0.042; w1[27]=0.040; w1[28]=0.038; w1[29]=0.037; w1[30]=0.036; w1[31]=0.034; w1[32]=0.033;
w1[33]=0.032; w1[34]=0.031; w1[35]=0.030; w1[36]=0.029; w1[37]=0.029; w1[38]=0.028; w1[39]=0.027; w1[40]=0.026;
w1[41]=0.026; w1[42]=0.025; w1[43]=0.024; w1[44]=0.024; w1[45]=0.023; w1[46]=0.023; w1[47]=0.022; w1[48]=0.022;
w1[49]=0.021; w1[50]=0.021; w1[51]=0.020; w1[52]=0.020; w1[53]=0.020; w1[54]=0.019; w1[55]=0.019; w1[56]=0.019;
w1[57]=0.018; w1[58]=0.018; w1[59]=0.018; w1[60]=0.017; w1[61]=0.017; w1[62]=0.017; w1[63]=0.016; w1[64]=0.016;
w1[65]=0.016; w1[66]=0.016; w1[67]=0.015; w1[68]=0.015; w1[69]=0.015; w1[70]=0.015; w1[71]=0.014; w1[72]=0.014;
w1[73]=0.014; w1[74]=0.014; w1[75]=0.014; w1[76]=0.014; w1[77]=0.013; w1[78]=0.013; w1[79]=0.013; w1[80]=0.013;
w1[81]=0.013; w1[82]=0.013; w1[83]=0.012; w1[84]=0.012; w1[85]=0.012; w1[86]=0.012; w1[87]=0.012; w1[88]=0.012;
w1[89]=0.011; w1[90]=0.011; w1[91]=0.011; w1[92]=0.011; w1[93]=0.011; w1[94]=0.011; w1[95]=0.011; w1[96]=0.011;
w1[97]=0.011; w1[98]=0.010; w1[99]=0.010; w1[100]=0.010; w1[101]=0.010; w1[102]=0.010; w1[103]=0.010; w1[104]=0.010;
w1[105]=0.010; w1[106]=0.010; w1[107]=0.010; w1[108]=0.009; w1[109]=0.009; w1[110]=0.009; w1[111]=0.009; w1[112]=0.009;
w1[113]=0.009; w1[114]=0.009; w1[115]=0.009; w1[116]=0.009; w1[117]=0.009; w1[118]=0.009; w1[119]=0.009; w1[120]=0.008;
w1[121]=0.008; w1[122]=0.008; w1[123]=0.008; w1[124]=0.008; w1[125]=0.008; w1[126]=0.008; w1[127]=0.008;
for( i = 1; i <= 1; i++ )
{
if (Oscillator[i].WaveForm == OSC_WAVEFORM_SPECTROBLEND)
{
Oscillator[i].WaveTable.set(1,w1);
}
}
?>
- KVRAF
- 5223 posts since 20 Jul, 2010
Of course , in my own words "Spectroblend is a producer of filtered sawtooths"... I'm wondering if a seperate mode where you can set absolute harmonic levels might be possible/useful for Zebra? When playing with it by manually drawing, it can sometimes be hard to get away from that saw sound, which is why I'm usually more drawn to the Geo modes, at least for animated/interesting sounds.hakey wrote:You're missing the point about the relative maximum amplitudes of the partials in Spectroblend mode - they seem to follow a 1/n rule such that the max amplitude of the second harmonic is 1/2 of the first, the third is 1/3, and so on. In other words, the amplitude scale is different for each partial.
This does not appear to be the case with the graph for the flute spectrum - here the amplitudes of the partials are measured against the same scale.
It is this difference in scale that makes even approximating that particular spectrum in Spectroblend difficult.
There is a spectral FX that scales the levels of the harmonics in a very controlled way, I'm wondering if the right setting on that could be used to bring the volume of the harmonics to a straight level.
Anyway, I think bmrzycki wins the round with his posts
http://sendy.bandcamp.com/releases < My new album at Bandcamp! Now pay what you like!
- KVRAF
- 23110 posts since 7 Jan, 2009 from Croatia
This gets +100 from me!Sendy wrote:I'm wondering if a seperate mode where you can set absolute harmonic levels might be possible/useful for Zebra?
And also the possibility to zoom in the waveform editor!
- KVRAF
- 4130 posts since 11 Aug, 2006 from Texas
I never noticed this before, but you're absolutely right (hakey as well). I tried using the Scale FX to adjust the harmonic levels, but it doesn't work well (scale does multiplication on harmonics where the shift here sounds logarithmic).Sendy wrote:Of course , in my own words "Spectroblend is a producer of filtered sawtooths"...
If Urs can give me the exact volume adjustment per harmonic I can easily adjust for it in my script.
Of course, I'd really love this to be a new mode (HarmoMorph and HarmoBlend?) and +1 to a larger waveform editor like the mmaps.
I hope I didn't geek out too much there, I'm a programmer first and a (poor) amateur musician second...Sendy wrote:Anyway, I think bmrzycki wins the round with his posts
- KVRAF
- 23110 posts since 7 Jan, 2009 from Croatia
HarmoMorph and HarmoBlend sound nice
- KVRAF
- Topic Starter
- 5234 posts since 25 Feb, 2008
Haha! No, it was all good stuff, even though slightly off target.bmrzycki wrote:I hope I didn't geek out too much thereSendy wrote:Anyway, I think bmrzycki wins the round with his posts
If Urs can give me the exact volume adjustment per harmonic I can easily adjust for it in my script.
Pretty sure it's just 1/n for nth partial, so to reverse it double the 2nd partial, triple the third etc.