/*
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "config.h"

#include <float_cast.h>

#if (HAVE_SNDFILE)

#include <samplerate.h>
#include <sndfile.h>

#include "audio_out.h"

#define ARRAY_LEN(x)	((int) (sizeof (x) / sizeof ((x) [0])))

#define	BUFFER_LEN		4096
#define	INPUT_FRAMES	100

#define	MIN(a,b)		((a) < (b) ? (a) : (b))

#define	MAGIC_NUMBER	((int) ('S' << 16) + ('R' << 8) + ('C'))

#ifndef	M_PI
#define	M_PI			3.14159265358979323846264338
#endif


typedef struct
{	int			magic ;

	SNDFILE 	*sndfile ;
	SF_INFO 	sfinfo ;

	SRC_STATE	*src_state ;
	SRC_DATA	src_data ;

	int			freq_point ;
	int			buffer_out_start, buffer_out_end ;

	float		buffer_in	[BUFFER_LEN] ;
	float		buffer_out	[BUFFER_LEN] ;
} CALLBACK_DATA ;

static int varispeed_get_data (CALLBACK_DATA *data, float *samples, int frames) ;
static void varispeed_play (const char *filename, int converter) ;

int
main (int argc, char *argv [])
{	const char	*cptr, *progname, *filename ;
	int			k, converter ;

	converter = SRC_SINC_FASTEST ;

	progname = argv [0] ;

	if ((cptr = strrchr (progname, '/')) != NULL)
		progname = cptr + 1 ;

	if ((cptr = strrchr (progname, '\\')) != NULL)
		progname = cptr + 1 ;

	printf ("\n"
		"  %s\n"
		"\n"
		"  This is a demo program which plays the given file at a slowly \n"
		"  varying speed. Lots of fun with drum loops and full mixes.\n"
		"\n"
		"  It uses Secret Rabbit Code (aka libsamplerate) to perform the \n"
		"  vari-speeding and libsndfile for file I/O.\n"
		"\n", progname) ;

	if (argc == 2)
		filename = argv [1] ;
	else if (argc == 4 && strcmp (argv [1], "-c") == 0)
	{	filename = argv [3] ;
		converter = atoi (argv [2]) ;
		}
	else
	{	printf ("  Usage :\n\n       %s [-c <number>] <input file>\n\n", progname) ;
		puts (
			"  The optional -c argument allows the converter type to be chosen from\n"
			"  the following list :"
			"\n"
			) ;

		for (k = 0 ; (cptr = src_get_name (k)) != NULL ; k++)
			printf ("       %d : %s\n", k, cptr) ;

		puts ("") ;
		exit (1) ;
		} ;

	varispeed_play (filename, converter) ;

	return 0 ;
} /* main */

/*==============================================================================
*/

static void
varispeed_play (const char *filename, int converter)
{	CALLBACK_DATA	*data ;
	AUDIO_OUT		*audio_out ;
	int				error ;

	/* Allocate memory for the callback data. */
	if ((data = calloc (1, sizeof (CALLBACK_DATA))) == NULL)
	{	printf ("\n\n%s:%d Calloc failed!\n", __FILE__, __LINE__) ;
		exit (1) ;
		} ;

	data->magic = MAGIC_NUMBER ;

	if ((data->sndfile = sf_open (filename, SFM_READ, &data->sfinfo)) == NULL)
	{	puts (sf_strerror (NULL)) ;
		exit (1) ;
		} ;

	/* Initialize the sample rate converter. */
	if ((data->src_state = src_new (converter, data->sfinfo.channels, &error)) == NULL)
	{	printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
		exit (1) ;
		} ;

	printf (

		"  Playing   : %s\n"
		"  Converter : %s\n"
		"\n"
		"  Press <control-c> to exit.\n"
		"\n",
		filename, src_get_name (converter)) ;

	if ((audio_out = audio_open (data->sfinfo.channels, data->sfinfo.samplerate)) == NULL)
	{	printf ("\n\nError : audio_open () failed.\n") ;
		exit (1) ;
		} ;

	/* Set up sample rate converter info. */
	data->src_data.end_of_input = 0 ; /* Set this later. */

	/* Start with zero to force load in while loop. */
	data->src_data.input_frames = 0 ;
	data->src_data.data_in = data->buffer_in ;

	/* Start with output frames also zero. */
	data->src_data.output_frames_gen = 0 ;

	data->buffer_out_start = data->buffer_out_end = 0 ;
	data->src_data.src_ratio = 1.0 ;

	/* Pass the data and the callbacl function to audio_play */
	audio_play ((get_audio_callback_t) varispeed_get_data, audio_out, data) ;

	/* Cleanup */
	audio_close (audio_out) ;
	sf_close (data->sndfile) ;
	src_delete (data->src_state) ;

	free (data) ;

} /* varispeed_play */

/*==============================================================================
*/

static int
varispeed_get_data (CALLBACK_DATA *data, float *samples, int frames)
{	int		error, readframes, frame_count, direct_out ;

	if (data->magic != MAGIC_NUMBER)
	{	printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__, __LINE__) ;
		exit (1) ;
		} ;

	frame_count = 0 ;

	if (data->buffer_out_start < data->buffer_out_end)
	{	frame_count = MIN (data->buffer_out_end - data->buffer_out_start, frames) ;
		memcpy (samples, data->buffer_out + data->sfinfo.channels * data->buffer_out_start, data->sfinfo.channels * frame_count * sizeof (float)) ;
		data->buffer_out_start += frame_count ;
		} ;

	data->buffer_out_start = data->buffer_out_end = 0 ;

	while (frame_count < frames)
	{
		/* Read INPUT_FRAMES frames worth looping at end of file. */
		for (readframes = 0 ; readframes < INPUT_FRAMES ; )
		{	sf_count_t position ;

			readframes += sf_readf_float (data->sndfile, data->buffer_in + data->sfinfo.channels * readframes, INPUT_FRAMES - readframes) ;

			position = sf_seek (data->sndfile, 0, SEEK_CUR) ;

			if (position < 0 || position == data->sfinfo.frames)
				sf_seek (data->sndfile, 0, SEEK_SET) ;
			} ;

		data->src_data.input_frames = readframes ;

		data->src_data.src_ratio = 1.0 - 0.5 * sin (data->freq_point * 2 * M_PI / 20000) ;
		data->freq_point ++ ;

		direct_out = (data->src_data.src_ratio * readframes < frames - frame_count) ? 1 : 0 ;

		if (direct_out)
		{	data->src_data.data_out = samples + frame_count * data->sfinfo.channels ;
			data->src_data.output_frames = frames - frame_count ;
			}
		else
		{	data->src_data.data_out = data->buffer_out ;
			data->src_data.output_frames = BUFFER_LEN / data->sfinfo.channels ;
			} ;

		if ((error = src_process (data->src_state, &data->src_data)))
		{	printf ("\nError : %s\n\n", src_strerror (error)) ;
			exit (1) ;
			} ;

		if (direct_out)
		{	frame_count += data->src_data.output_frames_gen ;
			continue ;
			} ;

		memcpy (samples + frame_count * data->sfinfo.channels, data->buffer_out, (frames - frame_count) * data->sfinfo.channels * sizeof (float)) ;

		data->buffer_out_start = frames - frame_count ;
		data->buffer_out_end = data->src_data.output_frames_gen ;

		frame_count += frames - frame_count ;
		} ;

	return frame_count ;
} /* varispeed_get_data */

/*==============================================================================
*/

#else /* (HAVE_SNFILE == 0) */

/* Alternative main function when libsndfile is not available. */

int
main (void)
{	puts (
		"\n"
		"****************************************************************\n"
		" This example program was compiled without libsndfile \n"
		" (http://www.zip.com.au/~erikd/libsndfile/).\n"
		" It is therefore completely broken and non-functional.\n"
		"****************************************************************\n"
		"\n"
		) ;

	return 0 ;
} /* main */

#endif

