Hi guys, I just wanted to give an update on the integration of
librubberband into TerminatorX.
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
[email protected]
http://lists.linuxaudio.org/listinfo/linux-audio-dev