home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.ee.lbl.gov
/
2014.05.ftp.ee.lbl.gov.tar
/
ftp.ee.lbl.gov
/
sst.tar.Z
/
sst.tar
/
sst
/
pitch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-10
|
3KB
|
122 lines
/* pitch.c - change the pitch of a sound file
**
** Copyright (C) 1989 by Jef Poskanzer.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
*/
#include <stdio.h>
#include "libfft.h"
#include "libst.h"
#define MYBUFSIZ 256
#define LOG2_SAMPLES_PER_CHUNK 9
#define SAMPLES_PER_CHUNK ( 1 << LOG2_SAMPLES_PER_CHUNK )
#define HALF_SPC ( 1 << ( LOG2_SAMPLES_PER_CHUNK - 1 ) )
static complex czero[SAMPLES_PER_CHUNK];
main( argc, argv )
int argc;
char *argv[];
{
FILE *f;
char mybuf[MYBUFSIZ];
float scale;
double atof();
int c, i, j, k;
int linbuf[SAMPLES_PER_CHUNK];
if ( argc < 2 || argc > 3 )
{
fprintf( stderr, "usage: %s <factor> [<file>]\n", argv[0] );
exit( 1 );
}
scale = atof( argv[1] );
if ( scale <= 0.0 )
{
fprintf( stderr, "%s: non-negative scale factor required\n", argv[0] );
exit( 1 );
}
if ( argc == 2 )
f = stdin;
else if ( argc == 3 )
{
f = fopen( argv[2], "r" );
if ( f == NULL )
{
perror( argv[2] );
exit( 1 );
}
}
initfft( LOG2_SAMPLES_PER_CHUNK );
for (i = 0; i < SAMPLES_PER_CHUNK; ++i)
czero[i].r = czero[i].i = 0.0;
i = 0;
while ( (c = getc( f )) != EOF )
{
linbuf[i] = st_ulaw_to_linear( c );
++i;
if ( i == SAMPLES_PER_CHUNK )
{
shiftchunk( linbuf, i, scale );
i = 0;
}
}
if ( i > 0 )
shiftchunk( linbuf, i, scale );
exit( 0 );
}
shiftchunk( linbuf, i, scale )
int linbuf[SAMPLES_PER_CHUNK];
float scale;
int i;
{
register int j, kk;
register float k;
complex x[SAMPLES_PER_CHUNK];
complex sx[SAMPLES_PER_CHUNK];
for ( j = 0; j < i; ++j )
{
x[j].r = linbuf[j];
x[j].i = 0.0;
}
if ( i < SAMPLES_PER_CHUNK )
bcopy( czero, &x[i], ( SAMPLES_PER_CHUNK - i ) * sizeof(*x) );
fft( x, 0 );
#ifdef notdef
for ( j = 0; j < SAMPLES_PER_CHUNK; ++j )
fprintf( stderr, "%d %g\n", j, x[j].r );
#endif
/* Zero the destination, then loop through the source copying buckets. */
bcopy( czero, sx, sizeof(sx) );
for ( j = 0, k = 0.5; j < HALF_SPC; ++j, k += scale )
{
kk = (int) k;
if ( kk >= HALF_SPC )
break;
sx[kk] = x[j];
sx[SAMPLES_PER_CHUNK - 1 - kk] = x[SAMPLES_PER_CHUNK - 1 - j];
}
fft_real_inverse( sx );
for ( j = 0; j < i; ++j )
putchar( st_linear_to_ulaw( (int) sx[j].r ) );
}