@@ -274,16 +274,13 @@ void Control::set_stretch_controls(double stretch_s,int mode,double fftsize_s,do | |||
stretch=pow(10.0,stretch_s*18.0); | |||
break; | |||
case 2: | |||
stretch=1.0/pow(10.0,stretch_s*3.0); | |||
if (stretch<0.1) stretch=0.1; | |||
stretch=1.0/pow(10.0,stretch_s*2.0); | |||
break; | |||
}; | |||
fftsize_s=pow(fftsize_s,1.5); | |||
double tmp=1.0; | |||
if (mode==2) tmp=1.0/stretch; | |||
int bufsize=(int)(pow(2.0,fftsize_s*12.0)*512.0*tmp); | |||
int bufsize=(int)(pow(2.0,fftsize_s*12.0)*512.0); | |||
bufsize=optimizebufsize(bufsize); | |||
@@ -308,7 +305,7 @@ double Control::get_stretch_control(double stretch,int mode){ | |||
break; | |||
case 2: | |||
if (stretch>1.0) return -1; | |||
result=3.0/(log(stretch)/log(10)); | |||
result=2.0/(log(stretch)/log(10)); | |||
break; | |||
}; | |||
return result; | |||
@@ -425,6 +422,7 @@ string Control::Render(string inaudio,string outaudio,FILE_TYPE outtype,FILE_TYP | |||
}; | |||
int readed=0; | |||
if (readsize!=0) readed=ai->read(readsize,inbuf_i); | |||
for (int i=0;i<readed;i++) { | |||
inbuf.l[i]=inbuf_i[i*2]/32768.0; | |||
inbuf.r[i]=inbuf_i[i*2+1]/32768.0; | |||
@@ -439,6 +437,9 @@ string Control::Render(string inaudio,string outaudio,FILE_TYPE outtype,FILE_TYP | |||
stretchl->out_buf[i]*=volume; | |||
stretchr->out_buf[i]*=volume; | |||
}; | |||
int nskip=stretchl->get_skip_nsamples(); | |||
if (nskip>0) ai->skip(nskip); | |||
if (outtype==FILE_WAV){ | |||
for (int i=0;i<outbufsize;i++) { | |||
REALTYPE l=stretchl->out_buf[i],r=stretchr->out_buf[i]; | |||
@@ -267,7 +267,7 @@ render();} | |||
xywh {5 50 985 420} box BORDER_BOX | |||
} { | |||
Fl_Group {} { | |||
label Parameters open selected | |||
label Parameters open | |||
xywh {5 70 985 400} | |||
} { | |||
Fl_Slider stretch_slider { | |||
@@ -284,7 +284,8 @@ o->labelcolor(FL_BLUE);} | |||
} | |||
Fl_Choice mode_choice { | |||
label {Mode:} | |||
callback {refresh();} | |||
callback {refresh(); | |||
control.update_player_stretch();} selected | |||
xywh {850 110 135 20} down_box BORDER_BOX | |||
} { | |||
MenuItem {} { | |||
@@ -715,7 +716,7 @@ selection_pos2->value(100.0);} | |||
tooltip {drag audio file here to open it} xywh {5 24 1005 22} box FLAT_BOX color 17 align 84 | |||
class DDBox | |||
} | |||
Fl_Group {} { | |||
Fl_Group {} {open | |||
xywh {5 475 985 70} box BORDER_BOX | |||
} { | |||
Fl_Group {} {open | |||
@@ -735,7 +736,7 @@ bool bypass=false; | |||
if (Fl::event_button()==FL_RIGHT_MOUSE) bypass=true; | |||
control.startplay(bypass);} | |||
tooltip Play xywh {20 500 40 20} box PLASTIC_UP_BOX | |||
tooltip {Play - right click to play the original sound} xywh {20 500 40 20} box PLASTIC_UP_BOX | |||
} | |||
Fl_Button freeze_button { | |||
label {@<-> F} | |||
@@ -791,23 +792,23 @@ control.stopplay();} | |||
} | |||
} | |||
} | |||
Function {set_mode(Mode mode)} {private | |||
Function {set_mode(Mode mode)} {open private | |||
} { | |||
code {switch (mode){ | |||
case STOP: | |||
play_button->labelcolor(FL_BLACK); | |||
mode_choice->activate(); | |||
//mode_choice->activate(); | |||
freeze_button->deactivate(); | |||
break; | |||
case PAUSE: | |||
play_button->labelcolor(FL_BLACK); | |||
mode_choice->activate(); | |||
//mode_choice->activate(); | |||
break; | |||
case PLAY: | |||
play_button->labelcolor(FL_RED); | |||
mode_choice->deactivate(); | |||
//mode_choice->deactivate(); | |||
fftsize_slider->labelcolor(FL_BLACK); | |||
freeze_button->activate(); | |||
break; | |||
@@ -21,21 +21,39 @@ | |||
#include "../globals.h" | |||
class InputS{ | |||
public: | |||
virtual bool open(std::string filename)=0; | |||
virtual void close()=0; | |||
virtual int read(int nsmps,short int *smps)=0; | |||
virtual void seek(double pos)=0;//0=start,1.0=end | |||
struct { | |||
int nsamples; | |||
int nchannels; | |||
int samplerate; | |||
int currentsample; | |||
} info; | |||
bool eof; | |||
public: | |||
InputS(){ | |||
skipbufsize=1024; | |||
skipbuf=new short int[skipbufsize*4]; | |||
}; | |||
virtual ~InputS(){ | |||
delete [] skipbuf; | |||
}; | |||
virtual bool open(std::string filename)=0; | |||
virtual void close()=0; | |||
virtual int read(int nsmps,short int *smps)=0; | |||
void skip(int nsmps){ | |||
while ((nsmps>0)&&(!eof)){ | |||
int readsize=(nsmps<skipbufsize)?nsmps:skipbufsize; | |||
read(readsize,skipbuf); | |||
nsmps-=readsize; | |||
}; | |||
}; | |||
virtual void seek(double pos)=0;//0=start,1.0=end | |||
struct { | |||
int nsamples; | |||
int nchannels; | |||
int samplerate; | |||
int currentsample; | |||
} info; | |||
bool eof; | |||
private: | |||
int skipbufsize; | |||
short int *skipbuf; | |||
}; | |||
#endif | |||
@@ -312,8 +312,6 @@ void Player::newtaskcheck(){ | |||
int n=2*PA_SOUND_BUFFER_SIZE/outbuf.size; | |||
if (n<3) n=3;//min 3 buffers | |||
if (n<(min_samples/outbuf.size)) n=(min_samples/outbuf.size);//the internal buffers sums "min_samples" amount | |||
// printf("PA_BUFSIZE=%d out_bufsize=%d => %d\n",PA_SOUND_BUFFER_SIZE,outbuf.size,n); | |||
outbuf.n=n; | |||
outbuf.nfresh=0; | |||
outbuf.datal=new float *[outbuf.n]; | |||
@@ -418,6 +416,9 @@ void Player::computesamples(){ | |||
binaural_beats->process(stretchl->out_buf,stretchr->out_buf,stretchl->get_bufsize(),in_pos_100); | |||
// stretchl->process_output(stretchl->out_buf,stretchl->out_bufsize); | |||
// stretchr->process_output(stretchr->out_buf,stretchr->out_bufsize); | |||
int nskip=stretchl->get_skip_nsamples(); | |||
if (nskip>0) ai->skip(nskip); | |||
bufmutex.lock(); | |||
@@ -1,5 +1,5 @@ | |||
/* | |||
Copyright (C) 2006-2009 Nasca Octavian Paul | |||
Copyright (C) 2006-2011 Nasca Octavian Paul | |||
Author: Nasca Octavian Paul | |||
This program is free software; you can redistribute it and/or modify | |||
@@ -178,6 +178,7 @@ Stretch::Stretch(REALTYPE rap_,int bufsize_,FFTWindow w,bool bypass_,REALTYPE sa | |||
require_new_buffer=false; | |||
c_pos_percents=0.0; | |||
extra_onset_time_credit=0.0; | |||
skip_samples=0; | |||
}; | |||
Stretch::~Stretch(){ | |||
@@ -193,7 +194,8 @@ Stretch::~Stretch(){ | |||
}; | |||
void Stretch::set_rap(REALTYPE newrap){ | |||
if ((rap>=1.0)&&(newrap>=1.0)) rap=newrap; | |||
//if ((rap>=1.0)&&(newrap>=1.0)) | |||
rap=newrap; | |||
}; | |||
void Stretch::do_analyse_inbuf(REALTYPE *smps){ | |||
@@ -327,6 +329,7 @@ REALTYPE Stretch::process(REALTYPE *smps,int nsmps){ | |||
remained_samples+=r; | |||
int result=0; | |||
if (remained_samples>=1.0){ | |||
skip_samples=(int)(floor(remained_samples-1.0)*bufsize); | |||
remained_samples=remained_samples-floor(remained_samples); | |||
require_new_buffer=true; | |||
}else{ | |||
@@ -343,6 +346,7 @@ void Stretch::here_is_onset(REALTYPE onset){ | |||
require_new_buffer=true; | |||
extra_onset_time_credit+=1.0-remained_samples; | |||
remained_samples=0.0; | |||
skip_samples=0; | |||
}; | |||
}; | |||
@@ -356,6 +360,10 @@ int Stretch::get_nsamples_for_fill(){ | |||
return bufsize*2; | |||
}; | |||
int Stretch::get_skip_nsamples(){ | |||
return skip_samples; | |||
}; | |||
REALTYPE Stretch::get_stretch_multiplier(REALTYPE pos_percents){ | |||
return 1.0; | |||
}; | |||
@@ -80,6 +80,7 @@ class Stretch{ | |||
int get_nsamples(REALTYPE current_pos_percents);//how many samples are required | |||
int get_nsamples_for_fill();//how many samples are required to be added for a complete buffer refill (at start of the song or after seek) | |||
int get_skip_nsamples();//used for shorten | |||
void set_rap(REALTYPE newrap);//set the current stretch value | |||
@@ -114,6 +115,7 @@ class Stretch{ | |||
long double remained_samples;//0..1 | |||
long double extra_onset_time_credit; | |||
REALTYPE c_pos_percents; | |||
int skip_samples; | |||
bool require_new_buffer; | |||
bool bypass; | |||
}; | |||
@@ -68,11 +68,11 @@ History: | |||
20110211(2.1-0) | |||
- Increased the precision of a paremeter for extreme long stretches | |||
2011????(2.) | |||
20110303(2.2) | |||
- Improved the stretching algorithm, adding the onset detection | |||
- Shorten algorithm improvements | |||
- Added an option to preserve the tonal part or noise part | |||
- Ignored the commandline parameters starting with "-" (usefull for macosx) | |||
- Improved the algorithm | |||
- Added onset detection | |||
Enjoy! :) | |||
Paul | |||