| @@ -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 | |||