Sorry here's the attachement.
Gerald
On Mon, 2010-01-11 at 21:25 +0100, gerald mwangi wrote:

> 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
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev

Reply via email to