Bundle libsamplerate
[audio-libsamplerate.git] / libsamplerate / examples / timewarp-file.c
diff --git a/libsamplerate/examples/timewarp-file.c b/libsamplerate/examples/timewarp-file.c
new file mode 100644 (file)
index 0000000..f0f61c4
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+** Copyright (c) 2005-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+
+#if (HAVE_SNDFILE)
+
+#include <samplerate.h>
+#include <sndfile.h>
+
+#define ARRAY_LEN(x)   ((int) (sizeof (x) / sizeof ((x) [0])))
+
+#define DEFAULT_CONVERTER      SRC_SINC_MEDIUM_QUALITY
+
+#define        BUFFER_LEN                      1024
+#define        INPUT_STEP_SIZE         8
+
+typedef struct
+{      sf_count_t      index ;
+       double          ratio ;
+} TIMEWARP_FACTOR ;
+
+static void usage_exit (const char *progname) ;
+static sf_count_t timewarp_convert (SNDFILE *infile, SNDFILE *outfile, int converter, int channels) ;
+
+int
+main (int argc, char *argv [])
+{      SNDFILE *infile, *outfile ;
+       SF_INFO sfinfo ;
+       sf_count_t      count ;
+
+       if (argc != 3)
+               usage_exit (argv [0]) ;
+
+       putchar ('\n') ;
+       printf ("Input File    : %s\n", argv [argc - 2]) ;
+       if ((infile = sf_open (argv [argc - 2], SFM_READ, &sfinfo)) == NULL)
+       {       printf ("Error : Not able to open input file '%s'\n", argv [argc - 2]) ;
+               exit (1) ;
+               } ;
+
+       if (INPUT_STEP_SIZE * sfinfo.channels > BUFFER_LEN)
+       {       printf ("\n\nError : INPUT_STEP_SIZE * sfinfo.channels > BUFFER_LEN\n\n") ;
+               exit (1) ;
+               } ;
+
+
+       /* Delete the output file length to zero if already exists. */
+       remove (argv [argc - 1]) ;
+
+       if ((outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
+       {       printf ("Error : Not able to open output file '%s'\n", argv [argc - 1]) ;
+               sf_close (infile) ;
+               exit (1) ;
+               } ;
+
+       sf_command (outfile, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
+
+       printf ("Output file   : %s\n", argv [argc - 1]) ;
+       printf ("Converter     : %s\n", src_get_name (DEFAULT_CONVERTER)) ;
+
+       count = timewarp_convert (infile, outfile, DEFAULT_CONVERTER, sfinfo.channels) ;
+
+       printf ("Output Frames : %ld\n\n", (long) count) ;
+
+       sf_close (infile) ;
+       sf_close (outfile) ;
+
+       return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static TIMEWARP_FACTOR warp [] =
+{      {       0               , 1.00000001 },
+       {       20000   , 1.01000000 },
+       {       20200   , 1.00000001 },
+       {       40000   , 1.20000000 },
+       {       40300   , 1.00000001 },
+       {       60000   , 1.10000000 },
+       {       60400   , 1.00000001 },
+       {       80000   , 1.50000000 },
+       {       81000   , 1.00000001 },
+} ;
+
+static sf_count_t
+timewarp_convert (SNDFILE *infile, SNDFILE *outfile, int converter, int channels)
+{      static float input [BUFFER_LEN] ;
+       static float output [BUFFER_LEN] ;
+
+       SRC_STATE       *src_state ;
+       SRC_DATA        src_data ;
+       int                     error, warp_index = 0 ;
+       sf_count_t      input_count = 0, output_count = 0 ;
+
+       sf_seek (infile, 0, SEEK_SET) ;
+       sf_seek (outfile, 0, SEEK_SET) ;
+
+       /* Initialize the sample rate converter. */
+       if ((src_state = src_new (converter, channels, &error)) == NULL)
+       {       printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
+               exit (1) ;
+               } ;
+
+       src_data.end_of_input = 0 ; /* Set this later. */
+
+       /* Start with zero to force load in while loop. */
+       src_data.input_frames = 0 ;
+       src_data.data_in = input ;
+
+       if (warp [0].index > 0)
+               src_data.src_ratio = 1.0 ;
+       else
+       {       src_data.src_ratio = warp [0].ratio ;
+               warp_index ++ ;
+               } ;
+
+       src_data.data_out = output ;
+       src_data.output_frames = BUFFER_LEN /channels ;
+
+       while (1)
+       {
+               if (warp_index < ARRAY_LEN (warp) - 1 && input_count >= warp [warp_index].index)
+               {       src_data.src_ratio = warp [warp_index].ratio ;
+                       warp_index ++ ;
+                       } ;
+
+               /* If the input buffer is empty, refill it. */
+               if (src_data.input_frames == 0)
+               {       src_data.input_frames = sf_readf_float (infile, input, INPUT_STEP_SIZE) ;
+                       input_count += src_data.input_frames ;
+                       src_data.data_in = input ;
+
+                       /* The last read will not be a full buffer, so snd_of_input. */
+                       if (src_data.input_frames < INPUT_STEP_SIZE)
+                               src_data.end_of_input = SF_TRUE ;
+                       } ;
+
+               /* Process current block. */
+               if ((error = src_process (src_state, &src_data)))
+               {       printf ("\nError : %s\n", src_strerror (error)) ;
+                       exit (1) ;
+                       } ;
+
+               /* Terminate if done. */
+               if (src_data.end_of_input && src_data.output_frames_gen == 0)
+                       break ;
+
+               /* Write output. */
+               sf_writef_float (outfile, output, src_data.output_frames_gen) ;
+               output_count += src_data.output_frames_gen ;
+
+               src_data.data_in += src_data.input_frames_used * channels ;
+               src_data.input_frames -= src_data.input_frames_used ;
+               } ;
+
+       src_delete (src_state) ;
+
+       return output_count ;
+} /* timewarp_convert */
+
+/*------------------------------------------------------------------------------
+*/
+
+static void
+usage_exit (const char *progname)
+{      const char      *cptr ;
+
+       if ((cptr = strrchr (progname, '/')) != NULL)
+               progname = cptr + 1 ;
+
+       if ((cptr = strrchr (progname, '\\')) != NULL)
+               progname = cptr + 1 ;
+
+       printf ("\n"
+               "  A program demonstrating the time warping capabilities of libsamplerate."
+               "  It uses libsndfile for file I/O and Secret Rabbit Code (aka libsamplerate)"
+               "  for performing the warping.\n"
+               "  It works on any file format supported by libsndfile with any \n"
+               "  number of channels (limited only by host memory).\n"
+               "\n"
+               "  The warping is dependant on a table hard code into the source code.\n"
+               "\n"
+               "  libsamplerate version : %s\n"
+               "\n"
+               "  Usage : \n"
+               "       %s <input file> <output file>\n"
+               "\n", src_get_version (), progname) ;
+
+       puts ("") ;
+
+       exit (1) ;
+} /* usage_exit */
+
+/*==============================================================================
+*/
+
+#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.mega-nerd.com/libsndfile/).\n"
+               "  It is therefore completely broken and non-functional.\n"
+               "****************************************************************\n"
+               "\n"
+               ) ;
+
+       return 0 ;
+} /* main */
+
+#endif
+
This page took 0.013256 seconds and 4 git commands to generate.