| @@ -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); | stretch=pow(10.0,stretch_s*18.0); | ||||
| break; | break; | ||||
| case 2: | 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; | break; | ||||
| }; | }; | ||||
| fftsize_s=pow(fftsize_s,1.5); | 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); | bufsize=optimizebufsize(bufsize); | ||||
| @@ -308,7 +305,7 @@ double Control::get_stretch_control(double stretch,int mode){ | |||||
| break; | break; | ||||
| case 2: | case 2: | ||||
| if (stretch>1.0) return -1; | if (stretch>1.0) return -1; | ||||
| result=3.0/(log(stretch)/log(10)); | |||||
| result=2.0/(log(stretch)/log(10)); | |||||
| break; | break; | ||||
| }; | }; | ||||
| return result; | return result; | ||||
| @@ -425,6 +422,7 @@ string Control::Render(string inaudio,string outaudio,FILE_TYPE outtype,FILE_TYP | |||||
| }; | }; | ||||
| int readed=0; | int readed=0; | ||||
| if (readsize!=0) readed=ai->read(readsize,inbuf_i); | if (readsize!=0) readed=ai->read(readsize,inbuf_i); | ||||
| for (int i=0;i<readed;i++) { | for (int i=0;i<readed;i++) { | ||||
| inbuf.l[i]=inbuf_i[i*2]/32768.0; | inbuf.l[i]=inbuf_i[i*2]/32768.0; | ||||
| inbuf.r[i]=inbuf_i[i*2+1]/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; | stretchl->out_buf[i]*=volume; | ||||
| stretchr->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){ | if (outtype==FILE_WAV){ | ||||
| for (int i=0;i<outbufsize;i++) { | for (int i=0;i<outbufsize;i++) { | ||||
| REALTYPE l=stretchl->out_buf[i],r=stretchr->out_buf[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 | xywh {5 50 985 420} box BORDER_BOX | ||||
| } { | } { | ||||
| Fl_Group {} { | Fl_Group {} { | ||||
| label Parameters open selected | |||||
| label Parameters open | |||||
| xywh {5 70 985 400} | xywh {5 70 985 400} | ||||
| } { | } { | ||||
| Fl_Slider stretch_slider { | Fl_Slider stretch_slider { | ||||
| @@ -284,7 +284,8 @@ o->labelcolor(FL_BLUE);} | |||||
| } | } | ||||
| Fl_Choice mode_choice { | Fl_Choice mode_choice { | ||||
| label {Mode:} | label {Mode:} | ||||
| callback {refresh();} | |||||
| callback {refresh(); | |||||
| control.update_player_stretch();} selected | |||||
| xywh {850 110 135 20} down_box BORDER_BOX | xywh {850 110 135 20} down_box BORDER_BOX | ||||
| } { | } { | ||||
| MenuItem {} { | 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 | tooltip {drag audio file here to open it} xywh {5 24 1005 22} box FLAT_BOX color 17 align 84 | ||||
| class DDBox | class DDBox | ||||
| } | } | ||||
| Fl_Group {} { | |||||
| Fl_Group {} {open | |||||
| xywh {5 475 985 70} box BORDER_BOX | xywh {5 475 985 70} box BORDER_BOX | ||||
| } { | } { | ||||
| Fl_Group {} {open | Fl_Group {} {open | ||||
| @@ -735,7 +736,7 @@ bool bypass=false; | |||||
| if (Fl::event_button()==FL_RIGHT_MOUSE) bypass=true; | if (Fl::event_button()==FL_RIGHT_MOUSE) bypass=true; | ||||
| control.startplay(bypass);} | 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 { | Fl_Button freeze_button { | ||||
| label {@<-> F} | label {@<-> F} | ||||
| @@ -791,23 +792,23 @@ control.stopplay();} | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| Function {set_mode(Mode mode)} {private | |||||
| Function {set_mode(Mode mode)} {open private | |||||
| } { | } { | ||||
| code {switch (mode){ | code {switch (mode){ | ||||
| case STOP: | case STOP: | ||||
| play_button->labelcolor(FL_BLACK); | play_button->labelcolor(FL_BLACK); | ||||
| mode_choice->activate(); | |||||
| //mode_choice->activate(); | |||||
| freeze_button->deactivate(); | freeze_button->deactivate(); | ||||
| break; | break; | ||||
| case PAUSE: | case PAUSE: | ||||
| play_button->labelcolor(FL_BLACK); | play_button->labelcolor(FL_BLACK); | ||||
| mode_choice->activate(); | |||||
| //mode_choice->activate(); | |||||
| break; | break; | ||||
| case PLAY: | case PLAY: | ||||
| play_button->labelcolor(FL_RED); | play_button->labelcolor(FL_RED); | ||||
| mode_choice->deactivate(); | |||||
| //mode_choice->deactivate(); | |||||
| fftsize_slider->labelcolor(FL_BLACK); | fftsize_slider->labelcolor(FL_BLACK); | ||||
| freeze_button->activate(); | freeze_button->activate(); | ||||
| break; | break; | ||||
| @@ -21,21 +21,39 @@ | |||||
| #include "../globals.h" | #include "../globals.h" | ||||
| class InputS{ | 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 | #endif | ||||
| @@ -312,8 +312,6 @@ void Player::newtaskcheck(){ | |||||
| int n=2*PA_SOUND_BUFFER_SIZE/outbuf.size; | int n=2*PA_SOUND_BUFFER_SIZE/outbuf.size; | ||||
| if (n<3) n=3;//min 3 buffers | 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 | 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.n=n; | ||||
| outbuf.nfresh=0; | outbuf.nfresh=0; | ||||
| outbuf.datal=new float *[outbuf.n]; | 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); | binaural_beats->process(stretchl->out_buf,stretchr->out_buf,stretchl->get_bufsize(),in_pos_100); | ||||
| // stretchl->process_output(stretchl->out_buf,stretchl->out_bufsize); | // stretchl->process_output(stretchl->out_buf,stretchl->out_bufsize); | ||||
| // stretchr->process_output(stretchr->out_buf,stretchr->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(); | bufmutex.lock(); | ||||
| @@ -1,5 +1,5 @@ | |||||
| /* | /* | ||||
| Copyright (C) 2006-2009 Nasca Octavian Paul | |||||
| Copyright (C) 2006-2011 Nasca Octavian Paul | |||||
| Author: Nasca Octavian Paul | Author: Nasca Octavian Paul | ||||
| This program is free software; you can redistribute it and/or modify | 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; | require_new_buffer=false; | ||||
| c_pos_percents=0.0; | c_pos_percents=0.0; | ||||
| extra_onset_time_credit=0.0; | extra_onset_time_credit=0.0; | ||||
| skip_samples=0; | |||||
| }; | }; | ||||
| Stretch::~Stretch(){ | Stretch::~Stretch(){ | ||||
| @@ -193,7 +194,8 @@ Stretch::~Stretch(){ | |||||
| }; | }; | ||||
| void Stretch::set_rap(REALTYPE newrap){ | 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){ | void Stretch::do_analyse_inbuf(REALTYPE *smps){ | ||||
| @@ -327,6 +329,7 @@ REALTYPE Stretch::process(REALTYPE *smps,int nsmps){ | |||||
| remained_samples+=r; | remained_samples+=r; | ||||
| int result=0; | int result=0; | ||||
| if (remained_samples>=1.0){ | if (remained_samples>=1.0){ | ||||
| skip_samples=(int)(floor(remained_samples-1.0)*bufsize); | |||||
| remained_samples=remained_samples-floor(remained_samples); | remained_samples=remained_samples-floor(remained_samples); | ||||
| require_new_buffer=true; | require_new_buffer=true; | ||||
| }else{ | }else{ | ||||
| @@ -343,6 +346,7 @@ void Stretch::here_is_onset(REALTYPE onset){ | |||||
| require_new_buffer=true; | require_new_buffer=true; | ||||
| extra_onset_time_credit+=1.0-remained_samples; | extra_onset_time_credit+=1.0-remained_samples; | ||||
| remained_samples=0.0; | remained_samples=0.0; | ||||
| skip_samples=0; | |||||
| }; | }; | ||||
| }; | }; | ||||
| @@ -356,6 +360,10 @@ int Stretch::get_nsamples_for_fill(){ | |||||
| return bufsize*2; | return bufsize*2; | ||||
| }; | }; | ||||
| int Stretch::get_skip_nsamples(){ | |||||
| return skip_samples; | |||||
| }; | |||||
| REALTYPE Stretch::get_stretch_multiplier(REALTYPE pos_percents){ | REALTYPE Stretch::get_stretch_multiplier(REALTYPE pos_percents){ | ||||
| return 1.0; | return 1.0; | ||||
| }; | }; | ||||
| @@ -80,6 +80,7 @@ class Stretch{ | |||||
| int get_nsamples(REALTYPE current_pos_percents);//how many samples are required | 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_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 | void set_rap(REALTYPE newrap);//set the current stretch value | ||||
| @@ -114,6 +115,7 @@ class Stretch{ | |||||
| long double remained_samples;//0..1 | long double remained_samples;//0..1 | ||||
| long double extra_onset_time_credit; | long double extra_onset_time_credit; | ||||
| REALTYPE c_pos_percents; | REALTYPE c_pos_percents; | ||||
| int skip_samples; | |||||
| bool require_new_buffer; | bool require_new_buffer; | ||||
| bool bypass; | bool bypass; | ||||
| }; | }; | ||||
| @@ -68,11 +68,11 @@ History: | |||||
| 20110211(2.1-0) | 20110211(2.1-0) | ||||
| - Increased the precision of a paremeter for extreme long stretches | - 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 | - Added an option to preserve the tonal part or noise part | ||||
| - Ignored the commandline parameters starting with "-" (usefull for macosx) | - Ignored the commandline parameters starting with "-" (usefull for macosx) | ||||
| - Improved the algorithm | |||||
| - Added onset detection | |||||
| Enjoy! :) | Enjoy! :) | ||||
| Paul | Paul | ||||