To understand rubberband, i wrote a small console Jack app that can play wav files at diferent speeds, keeping pitch. It works well. The code is attached.
I have a question to for the devs out there though: It seems to me that i have to run process() a few times with a fixed blocksize before, getRequiredSamples() returns something >0 in Realtime-mode. All other options are default options. Is this true? I need some help on this issue.
thanx Gerald
/* * Main.cpp * * Created on: Dec 31, 2009 * Author: zickzack */ #include <sndfile.h> #include <jack.h> #include <exception> #include <sys/signal.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <string> #include <rubberband/RubberBandStretcher.h> using namespace std; using namespace RubberBand; SNDFILE* file; jack_client_t* client; jack_port_t* leftOutput; jack_port_t* rightOutput; jack_default_audio_sample_t* temp[2]; jack_default_audio_sample_t* buffer; RubberBandStretcher *ts; SF_INFO info; int frameRead=-1; int frameWrite=0; bool eof; void JackShutdown(void* arg); int process(jack_nframes_t frames,void* args); void InitJack() { client=jack_client_open("RubberbandPlayer",JackNullOption,NULL); if(client==NULL) throw std::exception(); jack_on_shutdown(client,JackShutdown,NULL); jack_set_process_callback(client,process,NULL); leftOutput=jack_port_register(client,"Left",JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,NULL); rightOutput=jack_port_register(client,"Right",JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput,NULL); if((leftOutput==NULL)||(rightOutput==NULL)) throw std::exception(); } void InitRubberBand(double ratio) { RubberBandStretcher::Options options; options=RubberBandStretcher::OptionProcessRealTime|RubberBandStretcher::OptionTransientsCrisp; ts=new RubberBandStretcher(info.samplerate,info.channels,options); ts->setTimeRatio(ratio); } void JackShutdown(void* arg) { jack_client_close(client); if(file!=NULL) sf_close(file); if(temp[0]!=NULL) delete [] temp[0]; if(temp[1]!=NULL) delete [] temp[1]; if(buffer!=NULL) delete [] buffer; if(ts!=NULL) delete ts; exit(0); } void InitSndfile(char* filename) { info.format=0; file=sf_open(filename,SFM_READ,&info); if(file==NULL) throw std::exception(); printf("Fileinfo: Samplerate %d Channels %d Frames %d\n",info.samplerate,info.channels,info.frames); } void InitTempBuffers(int size) { if(temp[0]!=NULL) delete [] temp[0]; if(temp[1]!=NULL) delete [] temp[1]; temp[0]=new jack_default_audio_sample_t[size]; temp[1]=new jack_default_audio_sample_t[size]; } int ReadOutFrames(int frames,jack_default_audio_sample_t* left,jack_default_audio_sample_t* right) { int framesread=0; framesread=sf_readf_float(file, buffer,frames); jack_default_audio_sample_t* temp2=buffer; for(int i=0;i<framesread;i++) { memcpy(left,temp2,sizeof(jack_default_audio_sample_t)); temp2++; memcpy(right,temp2,sizeof(jack_default_audio_sample_t)); temp2++; left++; right++; } if(framesread<frames) { printf("eof\n"); eof=true; } return framesread; } int process(jack_nframes_t frames,void* args) { jack_default_audio_sample_t* left=(jack_default_audio_sample_t*)jack_port_get_buffer(leftOutput,frames); jack_default_audio_sample_t* right=(jack_default_audio_sample_t*)jack_port_get_buffer(rightOutput,frames); { while(ts->available()<frames) { int needFrames=std::min((int)frames,(int)ts->getSamplesRequired()); if(needFrames>0) { InitTempBuffers(needFrames); ReadOutFrames(needFrames,temp[0],temp[1]); ts->process(temp,needFrames,false); } } jack_default_audio_sample_t* after[2]; after[0]=left; after[1]=right; int available=ts->available(); //if(available>=frames) ts->retrieve(after,std::min((int)frames,available)); } return 0; } void signalHandler(int sig) { JackShutdown(NULL); printf("Oh, you're terminating me! buy\n"); } int main(int argc,char** argv) { eof=false; if(argc!=4) { printf("Usage: RubberbandPlayer -f <Wavefile> ratio\n"); return 0; } try { InitSndfile(argv[2]); InitJack(); double ratio=atof(argv[3]); InitRubberBand(ratio); signal(SIGTERM,signalHandler); temp[0]=new jack_default_audio_sample_t[jack_get_sample_rate(client)]; temp[1]=new jack_default_audio_sample_t[jack_get_sample_rate(client)]; buffer=new jack_default_audio_sample_t[jack_get_buffer_size(client)*info.channels]; printf("Buffersize %d",jack_get_buffer_size(client)); ts->setMaxProcessSize(jack_get_buffer_size(client)); } catch(std::exception ex) { JackShutdown(NULL); return 0; } printf("Activating client\n"); if (jack_activate (client)) { fprintf (stderr, "cannot activate client"); return 1; } float rat; while(!eof) { scanf("%f",&rat); printf("New ratio %f\n",rat); ts->setTimeRatio(rat); } JackShutdown(NULL); }
_______________________________________________ Linux-audio-dev mailing list Linux-audio-dev@xxxxxxxxxxxxxxxxxxxx http://lists.linuxaudio.org/listinfo/linux-audio-dev
_______________________________________________ Linux-audio-user mailing list Linux-audio-user@xxxxxxxxxxxxxxxxxxxx http://lists.linuxaudio.org/listinfo/linux-audio-user