]>
iEval git - audio-libsamplerate.git/blob - libsamplerate/examples/varispeed-play.c
2 ** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** All rights reserved.
5 ** This code is released under 2-clause BSD license. Please see the
6 ** file at : https://github.com/erikd/libsamplerate/blob/master/COPYING
16 #include <float_cast.h>
20 #include <samplerate.h>
23 #include "audio_out.h"
25 #define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
27 #define BUFFER_LEN 4096
28 #define VARISPEED_BLOCK_LEN 64
30 #define MIN(a,b) ((a) < (b) ? (a) : (b))
32 #define SRC_MAGIC ((int) ('S' << 16) + ('R' << 8) + ('C'))
33 #define SNDFILE_MAGIC ((int) ('s' << 24) + ('n' << 20) + ('d' << 16) + ('f' << 12) + ('i' << 8) + ('l' << 4) + 'e')
36 #define M_PI 3.14159265358979323846264338
45 float buffer
[BUFFER_LEN
] ;
55 SRC_STATE
*src_state
;
59 static int varispeed_get_data (SRC_CB_DATA
*data
, float *samples
, int frames
) ;
60 static void varispeed_play (const char *filename
, int converter
) ;
62 static long src_input_callback (void *cb_data
, float **data
) ;
65 main (int argc
, char *argv
[])
66 { const char *cptr
, *progname
, *filename
;
69 converter
= SRC_SINC_FASTEST
;
73 if ((cptr
= strrchr (progname
, '/')) != NULL
)
76 if ((cptr
= strrchr (progname
, '\\')) != NULL
)
82 " This is a demo program which plays the given file at a slowly \n"
83 " varying speed. Lots of fun with drum loops and full mixes.\n"
85 " It uses Secret Rabbit Code (aka libsamplerate) to perform the \n"
86 " vari-speeding and libsndfile for file I/O.\n"
91 else if (argc
== 4 && strcmp (argv
[1], "-c") == 0)
92 { filename
= argv
[3] ;
93 converter
= atoi (argv
[2]) ;
96 { printf (" Usage :\n\n %s [-c <number>] <input file>\n\n", progname
) ;
98 " The optional -c argument allows the converter type to be chosen from\n"
99 " the following list :"
103 for (k
= 0 ; (cptr
= src_get_name (k
)) != NULL
; k
++)
104 printf (" %d : %s\n", k
, cptr
) ;
110 varispeed_play (filename
, converter
) ;
115 /*==============================================================================
119 varispeed_play (const char *filename
, int converter
)
121 AUDIO_OUT
*audio_out
;
124 memset (&data
, 0, sizeof (data
)) ;
126 data
.magic
= SRC_MAGIC
;
127 data
.sf
.magic
= SNDFILE_MAGIC
;
129 if ((data
.sf
.sndfile
= sf_open (filename
, SFM_READ
, &data
.sf
.sfinfo
)) == NULL
)
130 { puts (sf_strerror (NULL
)) ;
134 /* Initialize the sample rate converter. */
135 if ((data
.src_state
= src_callback_new (src_input_callback
, converter
, data
.sf
.sfinfo
.channels
, &error
, &data
.sf
)) == NULL
)
136 { printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error
)) ;
145 " Press <control-c> to exit.\n"
147 filename
, src_get_name (converter
)) ;
149 if ((audio_out
= audio_open (data
.sf
.sfinfo
.channels
, data
.sf
.sfinfo
.samplerate
)) == NULL
)
150 { printf ("\n\nError : audio_open () failed.\n") ;
154 /* Pass the data and the callbacl function to audio_play */
155 audio_play ((get_audio_callback_t
) varispeed_get_data
, audio_out
, &data
) ;
158 audio_close (audio_out
) ;
159 sf_close (data
.sf
.sndfile
) ;
160 src_delete (data
.src_state
) ;
162 } /* varispeed_play */
165 src_input_callback (void *cb_data
, float **audio
)
166 { SNDFILE_CB_DATA
* data
= (SNDFILE_CB_DATA
*) cb_data
;
167 const int input_frames
= ARRAY_LEN (data
->buffer
) / data
->sfinfo
.channels
;
170 if (data
->magic
!= SNDFILE_MAGIC
)
171 { printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__
, __LINE__
) ;
175 for (read_frames
= 0 ; read_frames
< input_frames
; )
176 { sf_count_t position
;
178 read_frames
+= sf_readf_float (data
->sndfile
, data
->buffer
+ read_frames
* data
->sfinfo
.channels
, input_frames
- read_frames
) ;
180 position
= sf_seek (data
->sndfile
, 0, SEEK_CUR
) ;
182 if (position
< 0 || position
== data
->sfinfo
.frames
)
183 sf_seek (data
->sndfile
, 0, SEEK_SET
) ;
186 *audio
= & (data
->buffer
[0]) ;
188 return input_frames
;
189 } /* src_input_callback */
192 /*==============================================================================
196 varispeed_get_data (SRC_CB_DATA
*data
, float *samples
, int out_frames
)
198 int rc
, out_frame_count
;
200 if (data
->magic
!= SRC_MAGIC
)
201 { printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__
, __LINE__
) ;
205 for (out_frame_count
= 0 ; out_frame_count
< out_frames
; out_frame_count
+= VARISPEED_BLOCK_LEN
)
206 { double src_ratio
= 1.0 - 0.5 * sin (data
->freq_point
* 2 * M_PI
/ 20000) ;
208 data
->freq_point
++ ;
210 output
= samples
+ out_frame_count
* data
->sf
.sfinfo
.channels
;
212 if ((rc
= src_callback_read (data
->src_state
, src_ratio
, VARISPEED_BLOCK_LEN
, output
)) < VARISPEED_BLOCK_LEN
)
213 { printf ("\nError : src_callback_read short output (%d instead of %d)\n\n", rc
, VARISPEED_BLOCK_LEN
) ;
219 } /* varispeed_get_data */
221 /*==============================================================================
224 #else /* (HAVE_SNFILE == 0) */
226 /* Alternative main function when libsndfile is not available. */
232 "****************************************************************\n"
233 " This example program was compiled without libsndfile \n"
234 " (http://www.zip.com.au/~erikd/libsndfile/).\n"
235 " It is therefore completely broken and non-functional.\n"
236 "****************************************************************\n"
This page took 0.061864 seconds and 4 git commands to generate.