/* *********************************************************************************

	EXAMPLE main() for smbPitchShift using MiniAiff to handle sound file i/o
	(c) 2003-2009 S. M. Bernsee, http://www.dspdimension.com
	
	IMPORTANT: requires miniAIFF to be included in the project

********************************************************************************* */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "MiniAiff.h"

void resample(float *inbuf, float *outbuf, long inrate, long outrate)
{
	double fact = (double)inrate/(double)outrate;
	
	long v = 0;
	do{
		double curr = (double)v * fact;
		long previous = (long) curr;
		long next = (long) curr + 1;
		if (next > inrate-1) next = inrate-1;
		double rem = curr - (double)previous;
		
		outbuf[v] = (float)((1.0-rem)*(double)inbuf[previous] + rem*(double)inbuf[next]);
		
	} while (v++ < outrate-1);
}



void smbPitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata);


int main(void)
{
	
	long numChannels = 1;
	long bufferLengthFrames = 8192;
	int ret = 0;
	
	float timePercent = 150.;					// out time stretch factor in percent (200% = half speed)
	float pitchShift = timePercent/100.;
	
	char inFileName[] = "voice.aif";
	char outFileName[] = "out.aif";
	
	float **data = mAiffAllocateAudioBuffer(numChannels, bufferLengthFrames);
	
	long outBufferLengthFrames = timePercent*bufferLengthFrames/100.+.5;
	float **dataOut = mAiffAllocateAudioBuffer(numChannels, outBufferLengthFrames);

	printf("Running MiniAiff version %s\n(C) S.M.Bernsee - http://www.dspdimension.com\n\n", mAiffGetVersion());

	float sr = mAiffGetSampleRate(inFileName);

	// Create output file
	printf("Creating output\n");
	ret = mAiffInitFile(outFileName, sr /* sample rate */, 16 /* bits */, numChannels /* mono */);
	if (ret < 0) {
		printf("! Error creating output file %s - error #%d\n! File may be busy\n", outFileName, ret);
		exit(-1);
	}

	unsigned long inPosition=0;
	for(;;)
	{
	
		// Read from input file
		printf("Reading from input: %s\n", inFileName);
		ret = mAiffReadData(inFileName, data, inPosition, bufferLengthFrames, numChannels);
		if (ret < 0) {
			printf("! Error reading input file %s - error #%d\n! Wrong format or filename\n", inFileName, ret);
			exit(-1);
		} else if (ret == 0) break;		// end of file reached
		
		// Increment the read position
		inPosition += bufferLengthFrames;

		// --------------------------------- call smbPitchShift() ---------------------------------
		smbPitchShift(pitchShift, bufferLengthFrames, 2048, 4, mAiffGetSampleRate(inFileName), data[0], data[0]);
		resample(data[0], dataOut[0], bufferLengthFrames, outBufferLengthFrames);	// this is where we convert the sample rate

		// ----------------------------------------------------------------------------------------

		// write processed data to output file
		printf("Writing to output: %s\n", outFileName);
		ret = mAiffWriteData(outFileName, dataOut, outBufferLengthFrames, numChannels);
		if (ret < 0) {
			printf("! Error writing output file %s - error #%d\n! Not enough space?\n", outFileName, ret);
			exit(-1);
		}
	}

	mAiffDeallocateAudioBuffer(data, numChannels);
	mAiffDeallocateAudioBuffer(dataOut, numChannels);
	
	// That's all there is to it.
	printf("You're a cool dude now!\n");
	return 0;
}

