paulstretch_cpp

PaulStretch
Log | Files | Refs | LICENSE

commit 626cec829a06ffcf1acfb299a608891c5120005c
parent 8db997ce0804a66b6baca3f57e26a9f337bbad48
Author: Nasca Octavian PAUL <zynaddsubfx@yahoo.com>
Date:   Thu,  3 Mar 2011 22:08:12 +0200

Shorten algorithm improvements

Diffstat:
MControl.cpp | 13+++++++------
MGUI.fl | 17+++++++++--------
MInput/InputS.h | 48+++++++++++++++++++++++++++++++++---------------
MPlayer.cpp | 5+++--
MStretch.cpp | 12++++++++++--
MStretch.h | 2++
Mreadme.txt | 6+++---
7 files changed, 67 insertions(+), 36 deletions(-)

diff --git a/Control.cpp b/Control.cpp @@ -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]; diff --git a/GUI.fl b/GUI.fl @@ -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; diff --git a/Input/InputS.h b/Input/InputS.h @@ -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 diff --git a/Player.cpp b/Player.cpp @@ -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(); diff --git a/Stretch.cpp b/Stretch.cpp @@ -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; }; diff --git a/Stretch.h b/Stretch.h @@ -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; }; diff --git a/readme.txt b/readme.txt @@ -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