SFXR
Moderator: Moderators
Re: SFXR
Kjell sent me an example that pinpointed the problem. Please update ZGE, it works here now.
Re: SFXR
Thanks, both of you.
So here's my last zsfxr test, which preloads 100 sounds (10 sounds per type, but tone isn't the most interesting).
I deactivated the Random sounds and the Right click mutation.
During the initialization of the sound, as suggested by Kjell, I'm playing them once, all while checking if the Sample index has reached the desired Sample length before moving on to the next sound init. But since I'm not sure what exactly was repaired in the last release of ZGE, I don't know if I still have to do that.
The result is that it takes rather long to initialize 100 sounds. But at least, it is working
Edit:
And here's the APK. It isn't crashing anymore on Android, which is very cool. And if I generate only lasers and explosions, it should be good to go for Omeganaut.
So here's my last zsfxr test, which preloads 100 sounds (10 sounds per type, but tone isn't the most interesting).
I deactivated the Random sounds and the Right click mutation.
During the initialization of the sound, as suggested by Kjell, I'm playing them once, all while checking if the Sample index has reached the desired Sample length before moving on to the next sound init. But since I'm not sure what exactly was repaired in the last release of ZGE, I don't know if I still have to do that.
The result is that it takes rather long to initialize 100 sounds. But at least, it is working
Edit:
And here's the APK. It isn't crashing anymore on Android, which is very cool. And if I generate only lasers and explosions, it should be good to go for Omeganaut.
- Attachments
-
- ZSFXR.0.1.1.apk
- (245.76 KiB) Downloaded 127 times
-
- ZSFXR_preload_samples.zgeproj
- (101.13 KiB) Downloaded 142 times
Re: SFXR
I've started writing a moulinette (= conversion tool, in french) to convert jsfxr sound serialization from :
into something usable for ZGE. Maybe something like:
Here, SoundData is an array that contains the description of one sound.
549 characters + one array size 22 per sound.
I know that declaring arrays like that isn't sexy, but at least I can simply copy/paste the line from my spreadsheet that contains the data and generates this line of code. Or since it's only needed once during the initialization, skip the array and directly convert the serialization to:
Here, SoundData is an int to get the description of the corresponding sound number inside a switch.
500 characters + one int per sound. This should be better.
Apart FilterCutoff and FilterQ, are there other ZGE filters that can be applied in real time to those generated sounds? Like BaseNoteNr or Osc1Waveform? Are those filters instantaneous when playing the sound? I'm a noob when it comes to synth
Code: Select all
{
"oldParams": true,
"wave_type": 3,
"p_env_attack": 0,
"p_env_sustain": 1,
"p_env_punch": 0.35304476503997884,
"p_env_decay": 1,
"p_base_freq": 0.7287884051487694,
"p_freq_limit": 0,
"p_freq_ramp": 0.003089916083175466,
"p_freq_dramp": 0.5464092134956474,
"p_vib_strength": 0.0006601438087948627,
"p_vib_speed": -0.47612845336164744,
"p_arp_mod": -0.18785615002377387,
"p_arp_speed": 0.7628857641806879,
"p_duty": 0.031237783903733884,
"p_duty_ramp": -0.05899195813974674,
"p_repeat_speed": 0.41017668270216534,
"p_pha_offset": 0.011909400002449685,
"p_pha_ramp": 0.009166784366338953,
"p_lpf_freq": 0.12745521184461372,
"p_lpf_ramp": -0.02388602723340759,
"p_lpf_resonance": -0.7126283887429805,
"p_hpf_freq": 2.128612277679578e-12,
"p_hpf_ramp": 0.021328559525873432,
"sound_vol": 0.25,
"sample_rate": 44100,
"sample_size": 8
}
Code: Select all
{SoundData.SizeDim1=22;SoundData[0]=3;SoundData[1]=0;SoundData[2]=1;SoundData[3]=0.35304476;SoundData[4]=1;SoundData[5]=0.72878840;SoundData[6]=0;SoundData[7]=0.00308991;SoundData[8]=0.54640921;SoundData[9]=0.00066014;SoundData[10]=-0.47612845;SoundData[11]=-0.18785615;SoundData[12]=0.76288576;SoundData[13]=0.03123778;SoundData[14]=-0.05899195;SoundData[15]=0.41017668;SoundData[16]=0.01190940;SoundData[17]=0.00916678;SoundData[18]=0.12745521;SoundData[19]=-0.02388602;SoundData[20]=-0.71262838;SoundData[21]=2.12861227;SoundData[22]=0.02132855;}
549 characters + one array size 22 per sound.
I know that declaring arrays like that isn't sexy, but at least I can simply copy/paste the line from my spreadsheet that contains the data and generates this line of code. Or since it's only needed once during the initialization, skip the array and directly convert the serialization to:
Code: Select all
case SoundData:p_env_attack=0;p_env_sustain=1;p_env_punch=0.35304476;p_env_decay=1;p_base_freq=0.72878840;p_freq_limit=0;p_freq_ramp=0.00308991;p_freq_dramp=0.54640921;p_vib_strength=0.00066014;p_vib_speed=-0.47612845;p_arp_mod=-0.18785615;p_arp_speed=0.76288576;p_duty=0.03123778;p_duty_ramp=-0.05899195;p_repeat_speed=0.41017668;p_pha_offset=0.01190940;p_pha_ramp=0.00916678;p_lpf_freq=0.12745521;p_lpf_ramp=-0.02388602;p_lpf_resonance=-0.71262838;p_hpf_freq=2.12861227;p_hpf_ramp=0.02132855;break;
500 characters + one int per sound. This should be better.
Apart FilterCutoff and FilterQ, are there other ZGE filters that can be applied in real time to those generated sounds? Like BaseNoteNr or Osc1Waveform? Are those filters instantaneous when playing the sound? I'm a noob when it comes to synth
Re: SFXR
Hi Ats,
And just to illustrate what that entails .. below are two sine waveforms ( one high frequency & one super-high frequency ) sampled per-frame ( at 100fps ), sampled per-frame using linear interpolation, and sampled per-sample:
A sine-wave at 2750Hz ( which is already pretty high frequency ): linear interpolation is pretty close to per-sample, so in this region i'd say lerp is the best balance between accuracy and performance.
A sine-wave at 11kHz ( which is higher frequency than you'd realistically ever use ): both per-frame and linear interpolation have a significantly different signature from per-sample .. but at least lerp doesn't have the jumps ( causing pops & cracks ) of per-frame.
K
If your Sound component uses a Sample it overrides "Oscillator 1", but aside from that you can still use all other features including Modulators, LFOs and Envelopes. Do keep in mind that most of these features are updated per-frame ( not sub-frame / per-sample ), so any significant changes from frame-to-frame will result in crackling audio artifacts.
And just to illustrate what that entails .. below are two sine waveforms ( one high frequency & one super-high frequency ) sampled per-frame ( at 100fps ), sampled per-frame using linear interpolation, and sampled per-sample:
A sine-wave at 2750Hz ( which is already pretty high frequency ): linear interpolation is pretty close to per-sample, so in this region i'd say lerp is the best balance between accuracy and performance.
A sine-wave at 11kHz ( which is higher frequency than you'd realistically ever use ): both per-frame and linear interpolation have a significantly different signature from per-sample .. but at least lerp doesn't have the jumps ( causing pops & cracks ) of per-frame.
K
Re: SFXR
Thanks for the explanations
Here's a simplified version of ZSFXR that initialize sounds from preset function that is generated by my Google Sheet. By the way, two decimals is enough to define the sound parameters. It works really well! (mouse click the app)
I'm just wondering: I'm attaching the Sample to Sound_SFXR before playing them. So far, there haven't been any issues playing multiple sounds simultaneously. So, should I continue using a single Sound object for all Samples, or should I consider creating multiple Sound objects, one for each Sample?
Here's a simplified version of ZSFXR that initialize sounds from preset function that is generated by my Google Sheet. By the way, two decimals is enough to define the sound parameters. It works really well! (mouse click the app)
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZSFXR" ScreenMode="1" MouseVisible="255" FileVersion="2">
<OnLoaded>
<ZLibrary Comment="GENERATED FUNCTION - SOUNDS" HasInitializer="1">
<Source>
<![CDATA[void initSoundParam(int s){
switch(s){
case 0:
wave_type=3;p_env_attack=0;p_env_sustain=0.2;p_env_punch=0.75;p_env_decay=0.51;p_base_freq=0.14;p_freq_limit=0;p_freq_ramp=-0.13;p_freq_dramp=0;p_vib_strength=0;p_vib_speed=0;p_arp_mod=0.51;p_arp_speed=0.77;p_duty=0;p_duty_ramp=0;p_repeat_speed=0;p_pha_offset=0;p_pha_ramp=0;p_lpf_freq=1;p_lpf_ramp=0;p_lpf_resonance=0;p_hpf_freq=0;p_hpf_ramp=0;
break;
case 1:
wave_type=1;p_env_attack=0;p_env_sustain=0.37;p_env_punch=0;p_env_decay=0.37;p_base_freq=0.54;p_freq_limit=0;p_freq_ramp=0.3;p_freq_dramp=0;p_vib_strength=0;p_vib_speed=0;p_arp_mod=0;p_arp_speed=0;p_duty=1;p_duty_ramp=0;p_repeat_speed=0.47;p_pha_offset=0;p_pha_ramp=0;p_lpf_freq=1;p_lpf_ramp=0;p_lpf_resonance=0;p_hpf_freq=0;p_hpf_ramp=0;
break;
case 2:
wave_type=2;p_env_attack=0;p_env_sustain=0.28;p_env_punch=0.14;p_env_decay=0.38;p_base_freq=0.58;p_freq_limit=0.2;p_freq_ramp=-0.22;p_freq_dramp=0;p_vib_strength=0;p_vib_speed=0;p_arp_mod=0;p_arp_speed=0;p_duty=0.83;p_duty_ramp=-0.55;p_repeat_speed=0;p_pha_offset=0;p_pha_ramp=0;p_lpf_freq=1;p_lpf_ramp=0;p_lpf_resonance=0;p_hpf_freq=0.19;p_hpf_ramp=0;
break;
}
}
Sample getSampleName(int s){
switch(s){
case 0:return Sample_Explosion;
case 1:return Sample_PowerUp;
case 2:return Sample_Laser;
}
}
byte MAXSAMPLES=3;]]>
</Source>
</ZLibrary>
<ZLibrary Comment="SFXR">
<Source>
<![CDATA[//
float SampleLength()
{
return (p_env_attack*p_env_attack+
p_env_sustain*p_env_sustain+
p_env_decay*p_env_decay)*100000;
}
//
void ResetSample(int restart)
{
// Base
if(!restart)phase = 0;
period = 100/(p_base_freq*p_base_freq+0.001);
fperiod = period;
fmaxperiod = 100/(p_freq_limit*p_freq_limit+0.001);
fslide = 1-pow(p_freq_ramp,3)*0.01;
fdslide = pow(p_freq_dramp,3)*-0.000001;
// Square
square_duty = 0.5-p_duty*0.5;
square_slide = p_duty_ramp*-0.00005;
// Arpeggio
arp_time = 0;
arp_limit = p_arp_speed != 1 ? pow(1-p_arp_speed,2)*20000+32 : 0;
arp_mod = p_arp_mod >= 0 ? 1-pow(p_arp_mod,2)*0.9 : 1+pow(p_arp_mod,2)*10;
if(!restart)
{
sampling = 1;
// Filter
fltp = 0;
fltdp = 0;
fltw = pow(p_lpf_freq,3)*0.1;
fltw_d = 1+p_lpf_ramp*0.0001;
fltdmp = 5/(1+pow(p_lpf_resonance,2)*20)*(0.01+fltw);
if(fltdmp > 0.8)fltdmp = 0.8;
fltphp = 0;
flthp = pow(p_hpf_freq,2)*0.1;
flthp_d = 1+p_hpf_ramp*0.0003;
// Vibrato
vib_phase = 0;
vib_speed = pow(p_vib_speed,2)*0.01;
vib_amp = p_vib_strength*0.5;
// Envelope
env_stage = 0;
env_time = 0;
env_length[0] = p_env_attack*p_env_attack*100000;
env_length[1] = p_env_sustain*p_env_sustain*100000;
env_length[2] = p_env_decay*p_env_decay*100000;
// Phaser
fphase = pow(p_pha_offset,2)*1020;
if(p_pha_offset < 0)fphase *= -1;
fdphase = pow(p_pha_ramp,2);
if(p_pha_ramp < 0)fdphase *= -1;
iphase = fphase;
ipp = 0;
// Noise
fnoise = rnd()*2-1;
ppnoise = 0;
// Repeat
rep_time = 0;
rep_limit = p_repeat_speed ? pow(1-p_repeat_speed,2)*20000+32 : 0;
}
}
//
void SynthSample(int start, int end, int quality)
{
// Repeat
float l_rep_time = rep_time;
float l_rep_limit = rep_limit;
// Arpeggio
float l_arp_time = arp_time;
float l_arp_mod = arp_mod;
float l_arp_limit = arp_limit;
// Base
int l_wave_type = wave_type;
float l_phase = phase;
float l_period = period;
float l_fperiod = fperiod;
float l_fmaxperiod = fmaxperiod;
float l_fslide = fslide;
float l_fdslide = fdslide;
// Square
float l_square_duty = square_duty;
float l_square_slide = square_slide;
// Vibrato
float l_vib_phase = vib_phase;
float l_vib_speed = vib_speed;
float l_vib_amp = vib_amp;
// Envelope
float l_env_vol;
float l_env_length;
float l_env_stage = env_stage;
float l_env_time = env_time;
float l_env_punch = p_env_punch;
float l_env_length_0 = env_length[0];
float l_env_length_1 = env_length[1];
float l_env_length_2 = env_length[2];
// Noise
float l_fnoise = fnoise;
int l_ppnoise = ppnoise;
// Phaser
float l_fphase = fphase;
float l_fdphase = fdphase;
int l_iphase = iphase;
int l_ipp = ipp;
// Filter
float l_lpf_freq = p_lpf_freq;
float l_fltp = fltp;
float l_fltdp = fltdp;
float l_fltdmp = fltdmp;
float l_flthp = flthp;
float l_flthp_d = flthp_d;
float l_fltw = fltw;
float l_fltw_d = fltw_d;
float l_fltphp = fltphp;
// Supersampler
float sp = pow(2,quality);
float ss = 8/sp;
// Synth
int l_sampling = sampling;
for(int i=start; i<end; i++)
{
if(!l_sampling)
{
buffer[i] = 0;
continue;
}
// Repeat
if(l_rep_limit)
{
l_rep_time++;
if(l_rep_time >= l_rep_limit)
{
l_rep_time = 0;
ResetSample(1);
// Local
l_period = period;
l_fperiod = fperiod;
l_fslide = fslide;
l_square_duty = square_duty;
l_arp_time = arp_time;
l_arp_limit = arp_limit;
}
}
// Arpeggio
l_arp_time++;
if(l_arp_limit != 0 && l_arp_time >= l_arp_limit)
{
l_arp_limit = 0;
l_fperiod *= l_arp_mod;
}
// Base
l_fslide += l_fdslide;
l_fperiod *= l_fslide;
if(l_fperiod > l_fmaxperiod)
{
l_fperiod = l_fmaxperiod;
l_sampling = 0;
}
// Square
if(l_wave_type == 0)
{
l_square_duty += l_square_slide;
if(l_square_duty < 0)l_square_duty = 0;
if(l_square_duty > 0.5)l_square_duty = 0.5;
}
// Vibrato
float rfperiod = l_fperiod;
if(l_vib_amp > 0)
{
l_vib_phase += l_vib_speed;
rfperiod = l_fperiod*(1+sin(l_vib_phase)*l_vib_amp);
}
l_period = rfperiod;
if(l_period < 8)l_period = 8;
// Envelope
l_env_time++;
switch(l_env_stage)
{
case 0: l_env_length = l_env_length_0; break;
case 1: l_env_length = l_env_length_1; break;
case 2: l_env_length = l_env_length_2; break;
}
if(l_env_time > l_env_length)
{
l_env_time = 0;
l_env_stage++;
}
float tl = l_env_time ? l_env_time/l_env_length : 0;
switch(l_env_stage)
{
case 0: l_env_vol = tl; break;
case 1: l_env_vol = 1+(1-tl)*2*l_env_punch; break;
case 2: l_env_vol = 1-tl; break;
}
// Phaser
if(l_fphase || l_fdphase)
{
l_fphase += l_fdphase;
l_iphase = abs(l_fphase);
if(l_iphase > 1023)l_iphase = 1023;
}
// Filter
if(l_flthp_d != 0)
{
l_flthp *= l_flthp_d;
if(l_flthp < 0.00001)l_flthp = 0.00001;
if(l_flthp > 0.1)l_flthp = 0.1;
}
// Supersampler
float ssample = 0;
for(int si=0; si<sp; si++)
{
float sample = 0;
l_phase += ss;
if(l_phase >= l_period)l_phase = l_phase-floor(l_phase/l_period)*l_period;
float fp = l_phase/l_period;
switch(l_wave_type)
{
case 0: sample = fp < l_square_duty ? -0.5 : 0.5; break;
case 1: sample = 1-fp*2; break;
case 2: sample = sin(fp*PI*2); break;
case 3: int pnoise = fp*32;
if(pnoise != l_ppnoise){l_fnoise = rnd()*2-1; l_ppnoise = pnoise;}
sample = l_fnoise; break;
}
// Filter
float pp = l_fltp;
l_fltw *= l_fltw_d;
if(l_fltw < 0)l_fltw = 0;
if(l_fltw > 0.1)l_fltw = 0.1;
if(l_lpf_freq != 1)
{
l_fltdp += (sample-l_fltp)*l_fltw;
l_fltdp -= l_fltdp*l_fltdmp;
}
else
{
l_fltp = sample;
l_fltdp = 0;
}
l_fltp += l_fltdp;
l_fltphp += l_fltp-pp;
l_fltphp -= l_fltphp*l_flthp;
sample = l_fltphp;
// Phaser
if(l_fphase || l_fdphase)
{
phaser_buffer[l_ipp&1023] = sample;
sample += phaser_buffer[(l_ipp-l_iphase+1024)&1023];
l_ipp = (l_ipp+1)&1023;
}
// Accumulate
ssample += sample;
}
buffer[i] = ssample*l_env_vol*sound_vol*2/sp;
}
// Repeat
rep_time = l_rep_time;
// Arpeggio
arp_time = l_arp_time;
arp_limit = l_arp_limit;
// Base
phase = l_phase;
period = l_period;
fperiod = l_fperiod;
fslide = l_fslide;
// Square
square_duty = l_square_duty;
// Vibrato
vib_phase = l_vib_phase;
// Envelope
env_time = l_env_time;
env_stage = l_env_stage;
// Noise
fnoise = l_fnoise;
ppnoise = l_ppnoise;
// Phaser
fphase = l_fphase;
iphase = l_iphase;
ipp = l_ipp;
// Filter
fltw = l_fltw;
flthp = l_flthp;
fltp = l_fltp;
fltdp = l_fltdp;
fltphp = l_fltphp;
// Synth
sampling = l_sampling;
}
//
void attachSampleToSound(Sample sample)
{
Sound_SFXR.Sample = sample;
Sound_SFXR.Length = sample.Length; // Set the Sound component length
}
//
void initSoundSample(int n)
{
sound_vol = 0.5; // Important to set... this is not Sound_SFXR.Volume
// Init sfxr parameters for the sound (this function is generated from Sheets)
initSoundParam(n);
float S = SampleLength(); // Get the sample length
float L = S / 44100; // Get the sample length in seconds
buffer.SizeDim1 = S + 1; // Set buffer size
MySampleIndex = 0;
Sample sample = getSampleName(n);
sample.Length = L;
sampleSize = S;
//@RefreshContent(Component: sample); // This doesn't do anything? :-O
attachSampleToSound(sample);
@PlaySound(Sound: Sound_SFXR); // Sample needs(!) to be played to be generated ( lazy initialization i guess? )
ResetSample(0); // Reset the synthesizer
SynthSample(0,S,2); // Synthesize the entire sample in buffer
@RefreshContent(Component:sample);
}]]>
</Source>
</ZLibrary>
<SetAppState State="State_Init"/>
</OnLoaded>
<States>
<AppState Name="State_Init" ModelUpdatesEnabled="0" CollisionsEnabled="0">
<Definitions>
<Variable Name="waitForSample" Type="4"/>
<Variable Name="currentSoundNumber" Type="4"/>
<Variable Name="sampleSize" Type="1"/>
</Definitions>
<OnStart>
<ZExpression>
<Expression>
<![CDATA[setRandomSeed(getSystemTime());
currentSoundNumber = 0;
Sound_SFXR.Volume = 0; // set volume to 0 during initialization]]>
</Expression>
</ZExpression>
</OnStart>
<OnUpdate>
<ZExpression>
<Expression>
<![CDATA[if (waitForSample == 0)
{
waitForSample = 1;
trace("Init Sound " + intToStr(currentSoundNumber));
initSoundSample(currentSoundNumber);
}
if (waitForSample == 1)
{
trace(intToStr(MySampleIndex) + "/" + intToStr(sampleSize));
if(MySampleIndex >= sampleSize)
{
waitForSample = 0; // Stop waiting
currentSoundNumber ++;
if (currentSoundNumber == MAXSAMPLES)
{
Sound_SFXR.Volume = 0.25; // reset sound volume
@SetAppState(State:Demo);
}
}
}]]>
</Expression>
</ZExpression>
</OnUpdate>
</AppState>
<AppState Name="Demo">
<OnUpdate>
<KeyPress Comment="mouse click play sound" Keys="{" RepeatDelay="0.2">
<OnPressed>
<ZExpression>
<Expression>
<![CDATA[int snd = floor(rnd() * MAXSAMPLES);
Sample sample = getSampleName(snd);
attachSampleToSound(sample);
@PlaySound(Sound:Sound_SFXR);
trace("Play sound " + intToStr(snd));]]>
</Expression>
</ZExpression>
</OnPressed>
</KeyPress>
</OnUpdate>
</AppState>
</States>
<Content>
<Group Comment="SFXR">
<Children>
<Group Comment="Sample">
<Children>
<Group Comment="Synth">
<Children>
<Variable Name="sampling" Type="1"/>
<Array Name="buffer" SizeDim1="22554"/>
</Children>
</Group>
<Group Comment="Base">
<Children>
<Variable Name="phase"/>
<Variable Name="period"/>
<Variable Name="fperiod"/>
<Variable Name="fmaxperiod"/>
<Variable Name="fslide"/>
<Variable Name="fdslide"/>
</Children>
</Group>
<Group Comment="Square">
<Children>
<Variable Name="square_duty"/>
<Variable Name="square_slide"/>
</Children>
</Group>
<Group Comment="Vibrato">
<Children>
<Variable Name="vib_phase"/>
<Variable Name="vib_speed"/>
<Variable Name="vib_amp"/>
</Children>
</Group>
<Group Comment="Envelope">
<Children>
<Variable Name="env_stage"/>
<Variable Name="env_time"/>
<Array Name="env_length" SizeDim1="3"/>
</Children>
</Group>
<Group Comment="Filter">
<Children>
<Variable Name="fltp"/>
<Variable Name="fltdp"/>
<Variable Name="fltw"/>
<Variable Name="fltw_d"/>
<Variable Name="fltdmp"/>
<Variable Name="fltphp"/>
<Variable Name="flthp"/>
<Variable Name="flthp_d"/>
</Children>
</Group>
<Group Comment="Noise">
<Children>
<Variable Name="fnoise"/>
<Variable Name="ppnoise" Type="1"/>
</Children>
</Group>
<Group Comment="Phaser">
<Children>
<Variable Name="fphase"/>
<Variable Name="fdphase"/>
<Variable Name="iphase" Type="1"/>
<Variable Name="ipp" Type="1"/>
<Array Name="phaser_buffer" SizeDim1="1024"/>
</Children>
</Group>
<Group Comment="Repeat">
<Children>
<Variable Name="rep_time"/>
<Variable Name="rep_limit"/>
</Children>
</Group>
<Group Comment="Arpeggio">
<Children>
<Variable Name="arp_time"/>
<Variable Name="arp_mod"/>
<Variable Name="arp_limit"/>
</Children>
</Group>
</Children>
</Group>
<Group Comment="Parameters">
<Children>
<Group Comment="Base">
<Children>
<Variable Name="wave_type" Type="1"/>
<Variable Name="sound_vol"/>
<Variable Name="p_base_freq"/>
<Variable Name="p_freq_limit"/>
<Variable Name="p_freq_ramp"/>
<Variable Name="p_freq_dramp"/>
</Children>
</Group>
<Group Comment="Square">
<Children>
<Variable Name="p_duty"/>
<Variable Name="p_duty_ramp"/>
</Children>
</Group>
<Group Comment="Vibrato">
<Children>
<Variable Name="p_vib_speed"/>
<Variable Name="p_vib_strength"/>
</Children>
</Group>
<Group Comment="Envelope">
<Children>
<Variable Name="p_env_attack"/>
<Variable Name="p_env_sustain"/>
<Variable Name="p_env_decay"/>
<Variable Name="p_env_punch"/>
</Children>
</Group>
<Group Comment="Filter">
<Children>
<Variable Name="p_lpf_freq"/>
<Variable Name="p_lpf_ramp"/>
<Variable Name="p_lpf_resonance"/>
<Variable Name="p_hpf_freq"/>
<Variable Name="p_hpf_ramp"/>
</Children>
</Group>
<Group Comment="Phaser">
<Children>
<Variable Name="p_pha_offset"/>
<Variable Name="p_pha_ramp"/>
</Children>
</Group>
<Group Comment="Repeat">
<Children>
<Variable Name="p_repeat_speed"/>
</Children>
</Group>
<Group Comment="Arpeggio">
<Children>
<Variable Name="p_arp_speed"/>
<Variable Name="p_arp_mod"/>
</Children>
</Group>
</Children>
</Group>
<Variable Name="MySampleIndex" Type="1"/>
<Sound Name="Sound_SFXR" Length="0.5114" Sample="Sample_Laser" SampleRepeatPosition="-1" UseSampleHz="255"/>
</Children>
</Group>
<Sample Name="Sample_Explosion" Length="0.6778">
<Producers>
<SampleExpression Expression="this.Sample = buffer[MySampleIndex++];"/>
</Producers>
</Sample>
<Sample Name="Sample_PowerUp" Length="0.636">
<Producers>
<SampleExpression Expression="this.Sample = buffer[MySampleIndex++];"/>
</Producers>
</Sample>
<Sample Name="Sample_Laser" Length="0.5114">
<Producers>
<SampleExpression Expression="this.Sample = buffer[MySampleIndex++];"/>
</Producers>
</Sample>
</Content>
</ZApplication>
Last edited by Ats on Mon May 06, 2024 10:16 pm, edited 2 times in total.
Re: SFXR
Hi Ats,
K
You can do what you're doing and only use a single Sound component for all your samples .. as long as you don't enable PlaySound.ByReference.Ats wrote: ↑Sun May 05, 2024 12:45 pmI'm just wondering: I'm attaching the Sample to Sound_SFXR before playing them. So far, there haven't been any issues playing multiple sounds simultaneously. So, should I continue using a single Sound object for all Samples, or should I consider creating multiple Sound objects, one for each Sample?
K
Re: SFXR
Hello, I have a quick question: is it possible to declare a Sample using a ZLibrary instead of manually creating the Sample object? This would greatly simplify how I create sounds from my external spreadsheet.
I tried
It doesn't throw error, but then it gets stuck during the initialization with an access violation error.
I tried
Code: Select all
Sample Sample_Laser;
Re: SFXR
Hi Ats,
What you can do however is use "meta" scripting, like this:
Unfortunately there's no deleteComponent(), so you have to delete the created Samples by hand every time you want to re-import them
K
Yes, but maybe not in the way you expect?
This basically allocates a pointer to a Sample, nothing more. You could use "Sample mySample = @Sample(Length: 0.5);" to actually create a sample and assign it to the pointer variable, but that's not very useful either .. since without a SampleExpression component there's no way to access the Sample data.
What you can do however is use "meta" scripting, like this:
Code: Select all
Component mySample = createComponent(App, "Content", "Sample");
setStringProperty(mySample, "Name", "MySample");
setNumericProperty(mySample, "Length", 0, 0.5);
Component mySampleExpression = createComponent(MySample, "Producers", "SampleExpression");
setStringProperty(mySampleExpression, "Expression", "this.Sample = sin(this.Time*PI*440);");
K