long GetSampleSize(){ long bytearraylength = 0; // Lets calculate how big the bytearray must be... ResetSample(false); playing_sample=true; while(playing_sample) bytearraylength += CalcSampleSize(256); return bytearraylength; }
bool SDLPlaySound(const char *filename, bool sfxr) { ResetParams(); bool ok = SDLSoundInit() && LoadSound(filename, sfxr); if (ok) { if (cursnd.sfxr) { ResetSample(false); } else { cursndpos = cursnd.buf; } SDL_PauseAudioDevice(audioid, 0); playing_sample=true; } return ok; }
void SynthSample(int length, float* buffer, FILE* file) { for(int i=0;i<length;i++) { if(!playing_sample) break; rep_time++; if(rep_limit!=0 && rep_time>=rep_limit) { rep_time=0; ResetSample(true); } // frequency envelopes/arpeggios arp_time++; if(arp_limit!=0 && arp_time>=arp_limit) { arp_limit=0; fperiod*=arp_mod; } fslide+=fdslide; fperiod*=fslide; if(fperiod>fmaxperiod) { fperiod=fmaxperiod; if(p_freq_limit>0.0f) playing_sample=false; } float rfperiod=fperiod; if(vib_amp>0.0f) { vib_phase+=vib_speed; rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp); } period=(int)rfperiod; if(period<8) period=8; square_duty+=square_slide; if(square_duty<0.0f) square_duty=0.0f; if(square_duty>0.5f) square_duty=0.5f; // volume envelope env_time++; if(env_time>env_length[env_stage]) { env_time=0; env_stage++; if(env_stage==3) playing_sample=false; } if(env_stage==0) env_vol=(float)env_time/env_length[0]; if(env_stage==1) env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*p_env_punch; if(env_stage==2) env_vol=1.0f-(float)env_time/env_length[2]; // phaser step fphase+=fdphase; iphase=abs((int)fphase); if(iphase>1023) iphase=1023; if(flthp_d!=0.0f) { flthp*=flthp_d; if(flthp<0.00001f) flthp=0.00001f; if(flthp>0.1f) flthp=0.1f; } float ssample=0.0f; for(int si=0;si<8;si++) // 8x supersampling { float sample=0.0f; phase++; if(phase>=period) { // phase=0; phase%=period; if(wave_type==3) for(int i=0;i<32;i++) noise_buffer[i]=frnd(2.0f)-1.0f; } // base waveform float fp=(float)phase/period; switch(wave_type) { case 0: // square if(fp<square_duty) sample=0.5f; else sample=-0.5f; break; case 1: // sawtooth sample=1.0f-fp*2; break; case 2: // sine sample=(float)sin(fp*2*PI); break; case 3: // noise sample=noise_buffer[phase*32/period]; break; } // lp filter float pp=fltp; fltw*=fltw_d; if(fltw<0.0f) fltw=0.0f; if(fltw>0.1f) fltw=0.1f; if(p_lpf_freq!=1.0f) { fltdp+=(sample-fltp)*fltw; fltdp-=fltdp*fltdmp; } else { fltp=sample; fltdp=0.0f; } fltp+=fltdp; // hp filter fltphp+=fltp-pp; fltphp-=fltphp*flthp; sample=fltphp; // phaser phaser_buffer[ipp&1023]=sample; sample+=phaser_buffer[(ipp-iphase+1024)&1023]; ipp=(ipp+1)&1023; // final accumulation and envelope application ssample+=sample*env_vol; } ssample=ssample/8*master_vol; ssample*=2.0f*sound_vol; if(buffer!=NULL) { if(ssample>1.0f) ssample=1.0f; if(ssample<-1.0f) ssample=-1.0f; *buffer++=ssample; } if(file!=NULL) { // quantize depending on format // accumulate/count to accomodate variable sample rate? ssample*=4.0f; // arbitrary gain to get reasonable output volume... if(ssample>1.0f) ssample=1.0f; if(ssample<-1.0f) ssample=-1.0f; filesample+=ssample; fileacc++; if(wav_freq==44100 || fileacc==2) { filesample/=fileacc; fileacc=0; if(wav_bits==16) { short isample=(short)(filesample*32000); fwrite(&isample, 1, 2, file); } else { unsigned char isample=(unsigned char)(filesample*127+128); fwrite(&isample, 1, 1, file); } filesample=0.0f; } file_sampleswritten++; } } }
void PlaySample() { ResetSample(false); playing_sample=true; }
void SynthSample(int length, float* buffer, FILE* file) { for(int i=0;i<length;i++) { if(!havePlayingSample()) break; float ssample=0.0f; for(int j=0;j<CHANNEL_N;j++) { if(!channels[j].playing_sample) continue; // volume envelope channels[j].env_time++; if(channels[j].env_time>channels[j].env_length[channels[j].env_stage]) { channels[j].env_time=0; channels[j].env_stage++; if(channels[j].env_stage==4) channels[j].playing_sample=false; } if(channels[j].env_stage==0) continue; switch(channels[j].env_stage) { case 1: channels[j].env_vol=(float)channels[j].env_time/channels[j].env_length[1]; break; case 2: channels[j].env_vol=1.0f+pow(1.0f-(float)channels[j].env_time/channels[j].env_length[2], 1.0f)*2.0f*channels[j].p_env_punch; break; case 3: channels[j].env_vol=1.0f-(float)channels[j].env_time/channels[j].env_length[3]; break; } channels[j].rep_time++; if(channels[j].rep_limit!=0 && channels[j].rep_time>=channels[j].rep_limit) { channels[j].rep_time=0; ResetSample(true, j); } // frequency envelopes/arpeggios channels[j].arp_time++; if(channels[j].arp_limit!=0 && channels[j].arp_time>=channels[j].arp_limit) { channels[j].arp_limit=0; channels[j].fperiod*=channels[j].arp_mod; } channels[j].fslide+=channels[j].fdslide; channels[j].fperiod*=channels[j].fslide; if(channels[j].fperiod>channels[j].fmaxperiod) { channels[j].fperiod=channels[j].fmaxperiod; if(channels[j].p_freq_limit>0.0f) channels[j].playing_sample=false; } float rfperiod=channels[j].fperiod; if(channels[j].vib_amp>0.0f) { channels[j].vib_phase+=channels[j].vib_speed; rfperiod=channels[j].fperiod*(1.0+sin(channels[j].vib_phase)*channels[j].vib_amp); } channels[j].period=(int)rfperiod; if(channels[j].period<8) channels[j].period=8; channels[j].square_duty+=channels[j].square_slide; if(channels[j].square_duty<0.0f) channels[j].square_duty=0.0f; if(channels[j].square_duty>0.5f) channels[j].square_duty=0.5f; // phaser step channels[j].fphase+=channels[j].fdphase; channels[j].iphase=abs((int)channels[j].fphase); if(channels[j].iphase>=PHASER_BUFFER_SIZE) channels[j].iphase=PHASER_BUFFER_SIZE; if(channels[j].flthp_d!=0.0f) { channels[j].flthp*=channels[j].flthp_d; if(channels[j].flthp<0.00001f) channels[j].flthp=0.00001f; if(channels[j].flthp>0.1f) channels[j].flthp=0.1f; } float sub_ssample = 0.0f; for(int si=0;si<8;si++) // 8x supersampling { float sample=0.0f; channels[j].phase++; if(channels[j].phase>=channels[j].period) { // phase=0; channels[j].phase%=channels[j].period; if(channels[j].wave_type==3) for(int i=0;i<32;i++) channels[j].noise_buffer[i]=frnd(2.0f)-1.0f; } // base waveform float fp=(float)channels[j].phase/channels[j].period; switch(channels[j].wave_type) { case 0: // square if(fp<channels[j].square_duty) sample=0.5f; else sample=-0.5f; break; case 1: // sawtooth sample=1.0f-fp*2; break; case 2: // sine sample=(float)sin(fp*2*PI); break; case 3: // noise sample=channels[j].noise_buffer[channels[j].phase*32/channels[j].period]; break; } // lp filter float pp=channels[j].fltp; channels[j].fltw*=channels[j].fltw_d; if(channels[j].fltw<0.0f) channels[j].fltw=0.0f; if(channels[j].fltw>0.1f) channels[j].fltw=0.1f; if(channels[j].p_lpf_freq!=1.0f) { channels[j].fltdp+=(sample-channels[j].fltp)*channels[j].fltw; channels[j].fltdp-=channels[j].fltdp*channels[j].fltdmp; } else { channels[j].fltp=sample; channels[j].fltdp=0.0f; } channels[j].fltp+=channels[j].fltdp; // hp filter channels[j].fltphp+=channels[j].fltp-pp; channels[j].fltphp-=channels[j].fltphp*channels[j].flthp; sample=channels[j].fltphp; // phaser channels[j].phaser_buffer[channels[j].ipp&PHASER_BUFFER_MASK]=sample; sample+=channels[j].phaser_buffer[(channels[j].ipp-channels[j].iphase+PHASER_BUFFER_SIZE)&PHASER_BUFFER_MASK]; channels[j].ipp=(channels[j].ipp+1)&PHASER_BUFFER_MASK; // final accumulation and envelope application sub_ssample+=sample*channels[j].env_vol; } ssample+=(sub_ssample/8*master_vol*master_vol_multiplier)*(2.0f*channels[j].sound_vol); } if(buffer!=NULL) { if(ssample>1.0f) ssample=1.0f; if(ssample<-1.0f) ssample=-1.0f; *buffer++=ssample; } if(file!=NULL) { // quantize depending on format // accumulate/count to accomodate variable sample rate? ssample*=4.0f; // arbitrary gain to get reasonable output volume... if(ssample>1.0f) ssample=1.0f; if(ssample<-1.0f) ssample=-1.0f; filesample+=ssample; fileacc++; if(wav_freq==44100 || fileacc==2) { filesample/=fileacc; fileacc=0; if(wav_bits==16) { short isample=(short)(filesample*32000); fwrite(&isample, 1, 2, file); } else { unsigned char isample=(unsigned char)(filesample*127+128); fwrite(&isample, 1, 1, file); } filesample=0.0f; } file_sampleswritten++; } } }
void PlaySample() { ResetSample(false); for(int i=0;i<CHANNEL_N;i++) channels[i].playing_sample=channels[i].enabled; }
void generator::PlaySample(void) { ResetSample(false); playing_sample=true; }
int SynthSample(int length, float* buffer) { for(int i=0;i<length;i++) { if(!playing_sample) return i; rep_time++; if(rep_limit!=0 && rep_time>=rep_limit) { rep_time=0; ResetSample(true); } // frequency envelopes/arpeggios arp_time++; if(arp_limit!=0 && arp_time>=arp_limit) { arp_limit=0; fperiod*=arp_mod; } fslide+=fdslide; fperiod*=fslide; if(fperiod>fmaxperiod) { fperiod=fmaxperiod; if(p_freq_limit>0.0f) { playing_sample=false; } } float rfperiod=fperiod; if(vib_amp>0.0f) { vib_phase+=vib_speed; rfperiod=fperiod*(1.0+sin(vib_phase)*vib_amp); } period=(int)rfperiod; if(period<8) period=8; square_duty+=square_slide; if(square_duty<0.0f) square_duty=0.0f; if(square_duty>0.5f) square_duty=0.5f; // volume envelope env_time++; if(env_time>env_length[env_stage]) { env_time=0; env_stage++; if(env_stage==3) { playing_sample=false; } } if(env_stage==0) env_vol=(float)env_time/env_length[0]; if(env_stage==1) env_vol=1.0f+pow(1.0f-(float)env_time/env_length[1], 1.0f)*2.0f*p_env_punch; if(env_stage==2) env_vol=1.0f-(float)env_time/env_length[2]; // phaser step fphase+=fdphase; iphase=abs((int)fphase); if(iphase>1023) iphase=1023; if(flthp_d!=0.0f) { flthp*=flthp_d; if(flthp<0.00001f) flthp=0.00001f; if(flthp>0.1f) flthp=0.1f; } float ssample=0.0f; for(int si=0;si<8;si++) // 8x supersampling { float sample=0.0f; phase++; if(phase>=period) { phase%=period; if(wave_type==3) for(int i=0;i<32;i++) noise_buffer[i]=frnd(2.0f)-1.0f; } // base waveform float fp=(float)phase/period; switch(wave_type) { case 0: // square if(fp<square_duty) sample=0.5f; else sample=-0.5f; break; case 1: // sawtooth sample=1.0f-fp*2; break; case 2: // sine sample=(float)sin(fp*2*PI); break; case 3: // noise sample=noise_buffer[phase*32/period]; break; } // lp filter float pp=fltp; fltw*=fltw_d; if(fltw<0.0f) fltw=0.0f; if(fltw>0.1f) fltw=0.1f; if(p_lpf_freq!=1.0f) { fltdp+=(sample-fltp)*fltw; fltdp-=fltdp*fltdmp; } else { fltp=sample; fltdp=0.0f; } fltp+=fltdp; // hp filter fltphp+=fltp-pp; fltphp-=fltphp*flthp; sample=fltphp; // phaser phaser_buffer[ipp&1023]=sample; sample+=phaser_buffer[(ipp-iphase+1024)&1023]; ipp=(ipp+1)&1023; // final accumulation and envelope application ssample+=sample*env_vol; } ssample=ssample/8*master_vol; ssample*=2.0f*sound_vol; if(buffer!=NULL) { if(ssample>1.0f) ssample=1.0f; if(ssample<-1.0f) ssample=-1.0f; *buffer++=ssample; } } return length; }