annotate src/libsamplerate-0.1.9/examples/varispeed-play.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 481f5f8c5634
children
rev   line source
Chris@41 1 /*
Chris@41 2 ** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@41 3 ** All rights reserved.
Chris@41 4 **
Chris@41 5 ** This code is released under 2-clause BSD license. Please see the
Chris@41 6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
Chris@41 7 */
Chris@41 8
Chris@41 9 #include <stdio.h>
Chris@41 10 #include <stdlib.h>
Chris@41 11 #include <unistd.h>
Chris@41 12 #include <string.h>
Chris@41 13
Chris@41 14 #include "config.h"
Chris@41 15
Chris@41 16 #include <float_cast.h>
Chris@41 17
Chris@41 18 #if (HAVE_SNDFILE)
Chris@41 19
Chris@41 20 #include <samplerate.h>
Chris@41 21 #include <sndfile.h>
Chris@41 22
Chris@41 23 #include "audio_out.h"
Chris@41 24
Chris@41 25 #define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
Chris@41 26
Chris@41 27 #define BUFFER_LEN 4096
Chris@41 28 #define VARISPEED_BLOCK_LEN 64
Chris@41 29
Chris@41 30 #define MIN(a,b) ((a) < (b) ? (a) : (b))
Chris@41 31
Chris@41 32 #define SRC_MAGIC ((int) ('S' << 16) + ('R' << 8) + ('C'))
Chris@41 33 #define SNDFILE_MAGIC ((int) ('s' << 24) + ('n' << 20) + ('d' << 16) + ('f' << 12) + ('i' << 8) + ('l' << 4) + 'e')
Chris@41 34
Chris@41 35 #ifndef M_PI
Chris@41 36 #define M_PI 3.14159265358979323846264338
Chris@41 37 #endif
Chris@41 38
Chris@41 39
Chris@41 40 typedef struct
Chris@41 41 { int magic ;
Chris@41 42 SNDFILE *sndfile ;
Chris@41 43 SF_INFO sfinfo ;
Chris@41 44
Chris@41 45 float buffer [BUFFER_LEN] ;
Chris@41 46 } SNDFILE_CB_DATA ;
Chris@41 47
Chris@41 48 typedef struct
Chris@41 49 { int magic ;
Chris@41 50
Chris@41 51 SNDFILE_CB_DATA sf ;
Chris@41 52
Chris@41 53 int freq_point ;
Chris@41 54
Chris@41 55 SRC_STATE *src_state ;
Chris@41 56
Chris@41 57 } SRC_CB_DATA ;
Chris@41 58
Chris@41 59 static int varispeed_get_data (SRC_CB_DATA *data, float *samples, int frames) ;
Chris@41 60 static void varispeed_play (const char *filename, int converter) ;
Chris@41 61
Chris@41 62 static long src_input_callback (void *cb_data, float **data) ;
Chris@41 63
Chris@41 64 int
Chris@41 65 main (int argc, char *argv [])
Chris@41 66 { const char *cptr, *progname, *filename ;
Chris@41 67 int k, converter ;
Chris@41 68
Chris@41 69 converter = SRC_SINC_FASTEST ;
Chris@41 70
Chris@41 71 progname = argv [0] ;
Chris@41 72
Chris@41 73 if ((cptr = strrchr (progname, '/')) != NULL)
Chris@41 74 progname = cptr + 1 ;
Chris@41 75
Chris@41 76 if ((cptr = strrchr (progname, '\\')) != NULL)
Chris@41 77 progname = cptr + 1 ;
Chris@41 78
Chris@41 79 printf ("\n"
Chris@41 80 " %s\n"
Chris@41 81 "\n"
Chris@41 82 " This is a demo program which plays the given file at a slowly \n"
Chris@41 83 " varying speed. Lots of fun with drum loops and full mixes.\n"
Chris@41 84 "\n"
Chris@41 85 " It uses Secret Rabbit Code (aka libsamplerate) to perform the \n"
Chris@41 86 " vari-speeding and libsndfile for file I/O.\n"
Chris@41 87 "\n", progname) ;
Chris@41 88
Chris@41 89 if (argc == 2)
Chris@41 90 filename = argv [1] ;
Chris@41 91 else if (argc == 4 && strcmp (argv [1], "-c") == 0)
Chris@41 92 { filename = argv [3] ;
Chris@41 93 converter = atoi (argv [2]) ;
Chris@41 94 }
Chris@41 95 else
Chris@41 96 { printf (" Usage :\n\n %s [-c <number>] <input file>\n\n", progname) ;
Chris@41 97 puts (
Chris@41 98 " The optional -c argument allows the converter type to be chosen from\n"
Chris@41 99 " the following list :"
Chris@41 100 "\n"
Chris@41 101 ) ;
Chris@41 102
Chris@41 103 for (k = 0 ; (cptr = src_get_name (k)) != NULL ; k++)
Chris@41 104 printf (" %d : %s\n", k, cptr) ;
Chris@41 105
Chris@41 106 puts ("") ;
Chris@41 107 exit (1) ;
Chris@41 108 } ;
Chris@41 109
Chris@41 110 varispeed_play (filename, converter) ;
Chris@41 111
Chris@41 112 return 0 ;
Chris@41 113 } /* main */
Chris@41 114
Chris@41 115 /*==============================================================================
Chris@41 116 */
Chris@41 117
Chris@41 118 static void
Chris@41 119 varispeed_play (const char *filename, int converter)
Chris@41 120 { SRC_CB_DATA data ;
Chris@41 121 AUDIO_OUT *audio_out ;
Chris@41 122 int error ;
Chris@41 123
Chris@41 124 memset (&data, 0, sizeof (data)) ;
Chris@41 125
Chris@41 126 data.magic = SRC_MAGIC ;
Chris@41 127 data.sf.magic = SNDFILE_MAGIC ;
Chris@41 128
Chris@41 129 if ((data.sf.sndfile = sf_open (filename, SFM_READ, &data.sf.sfinfo)) == NULL)
Chris@41 130 { puts (sf_strerror (NULL)) ;
Chris@41 131 exit (1) ;
Chris@41 132 } ;
Chris@41 133
Chris@41 134 /* Initialize the sample rate converter. */
Chris@41 135 if ((data.src_state = src_callback_new (src_input_callback, converter, data.sf.sfinfo.channels, &error, &data.sf)) == NULL)
Chris@41 136 { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
Chris@41 137 exit (1) ;
Chris@41 138 } ;
Chris@41 139
Chris@41 140 printf (
Chris@41 141
Chris@41 142 " Playing : %s\n"
Chris@41 143 " Converter : %s\n"
Chris@41 144 "\n"
Chris@41 145 " Press <control-c> to exit.\n"
Chris@41 146 "\n",
Chris@41 147 filename, src_get_name (converter)) ;
Chris@41 148
Chris@41 149 if ((audio_out = audio_open (data.sf.sfinfo.channels, data.sf.sfinfo.samplerate)) == NULL)
Chris@41 150 { printf ("\n\nError : audio_open () failed.\n") ;
Chris@41 151 exit (1) ;
Chris@41 152 } ;
Chris@41 153
Chris@41 154 /* Pass the data and the callbacl function to audio_play */
Chris@41 155 audio_play ((get_audio_callback_t) varispeed_get_data, audio_out, &data) ;
Chris@41 156
Chris@41 157 /* Cleanup */
Chris@41 158 audio_close (audio_out) ;
Chris@41 159 sf_close (data.sf.sndfile) ;
Chris@41 160 src_delete (data.src_state) ;
Chris@41 161
Chris@41 162 } /* varispeed_play */
Chris@41 163
Chris@41 164 static long
Chris@41 165 src_input_callback (void *cb_data, float **audio)
Chris@41 166 { SNDFILE_CB_DATA * data = (SNDFILE_CB_DATA *) cb_data ;
Chris@41 167 const int input_frames = ARRAY_LEN (data->buffer) / data->sfinfo.channels ;
Chris@41 168 int read_frames ;
Chris@41 169
Chris@41 170 if (data->magic != SNDFILE_MAGIC)
Chris@41 171 { printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__, __LINE__) ;
Chris@41 172 exit (1) ;
Chris@41 173 } ;
Chris@41 174
Chris@41 175 for (read_frames = 0 ; read_frames < input_frames ; )
Chris@41 176 { sf_count_t position ;
Chris@41 177
Chris@41 178 read_frames += sf_readf_float (data->sndfile, data->buffer + read_frames * data->sfinfo.channels, input_frames - read_frames) ;
Chris@41 179
Chris@41 180 position = sf_seek (data->sndfile, 0, SEEK_CUR) ;
Chris@41 181
Chris@41 182 if (position < 0 || position == data->sfinfo.frames)
Chris@41 183 sf_seek (data->sndfile, 0, SEEK_SET) ;
Chris@41 184 } ;
Chris@41 185
Chris@41 186 *audio = & (data->buffer [0]) ;
Chris@41 187
Chris@41 188 return input_frames ;
Chris@41 189 } /* src_input_callback */
Chris@41 190
Chris@41 191
Chris@41 192 /*==============================================================================
Chris@41 193 */
Chris@41 194
Chris@41 195 static int
Chris@41 196 varispeed_get_data (SRC_CB_DATA *data, float *samples, int out_frames)
Chris@41 197 { float *output ;
Chris@41 198 int rc, out_frame_count ;
Chris@41 199
Chris@41 200 if (data->magic != SRC_MAGIC)
Chris@41 201 { printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__, __LINE__) ;
Chris@41 202 exit (1) ;
Chris@41 203 } ;
Chris@41 204
Chris@41 205 for (out_frame_count = 0 ; out_frame_count < out_frames ; out_frame_count += VARISPEED_BLOCK_LEN)
Chris@41 206 { double src_ratio = 1.0 - 0.5 * sin (data->freq_point * 2 * M_PI / 20000) ;
Chris@41 207
Chris@41 208 data->freq_point ++ ;
Chris@41 209
Chris@41 210 output = samples + out_frame_count * data->sf.sfinfo.channels ;
Chris@41 211
Chris@41 212 if ((rc = src_callback_read (data->src_state, src_ratio, VARISPEED_BLOCK_LEN, output)) < VARISPEED_BLOCK_LEN)
Chris@41 213 { printf ("\nError : src_callback_read short output (%d instead of %d)\n\n", rc, VARISPEED_BLOCK_LEN) ;
Chris@41 214 exit (1) ;
Chris@41 215 } ;
Chris@41 216 } ;
Chris@41 217
Chris@41 218 return out_frames ;
Chris@41 219 } /* varispeed_get_data */
Chris@41 220
Chris@41 221 /*==============================================================================
Chris@41 222 */
Chris@41 223
Chris@41 224 #else /* (HAVE_SNFILE == 0) */
Chris@41 225
Chris@41 226 /* Alternative main function when libsndfile is not available. */
Chris@41 227
Chris@41 228 int
Chris@41 229 main (void)
Chris@41 230 { puts (
Chris@41 231 "\n"
Chris@41 232 "****************************************************************\n"
Chris@41 233 " This example program was compiled without libsndfile \n"
Chris@41 234 " (http://www.zip.com.au/~erikd/libsndfile/).\n"
Chris@41 235 " It is therefore completely broken and non-functional.\n"
Chris@41 236 "****************************************************************\n"
Chris@41 237 "\n"
Chris@41 238 ) ;
Chris@41 239
Chris@41 240 return 0 ;
Chris@41 241 } /* main */
Chris@41 242
Chris@41 243 #endif
Chris@41 244