/* This file was written by Bill Cox in 2010, and is licensed under the Apache 2.0 license. This file is meant as a simple example for how to use libsonic. It is also a useful utility on it's own, which can speed up or slow down wav files, change pitch, and scale volume. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sonic.h" #include "wave.h" #define BUFFER_SIZE 2048 /* Run sonic. */ static void runSonic( waveFile inFile, waveFile outFile, float speed, float pitch, float rate, float volume, int emulateChordPitch, int quality, int sampleRate, int numChannels) { sonicStream stream = sonicCreateStream(sampleRate, numChannels); short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE]; int samplesRead, samplesWritten; sonicSetSpeed(stream, speed); sonicSetPitch(stream, pitch); sonicSetRate(stream, rate); sonicSetVolume(stream, volume); sonicSetChordPitch(stream, emulateChordPitch); sonicSetQuality(stream, quality); do { samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels); if(samplesRead == 0) { sonicFlushStream(stream); } else { sonicWriteShortToStream(stream, inBuffer, samplesRead); } do { samplesWritten = sonicReadShortFromStream(stream, outBuffer, BUFFER_SIZE/numChannels); if(samplesWritten > 0) { writeToWaveFile(outFile, outBuffer, samplesWritten); } } while(samplesWritten > 0); } while(samplesRead > 0); sonicDestroyStream(stream); } /* Print the usage. */ static void usage(void) { fprintf(stderr, "Usage: sonic [OPTION]... infile outfile\n" " -c -- Modify pitch by emulating vocal chords vibrating\n" " faster or slower.\n" " -p pitch -- Set pitch scaling factor. 1.3 means 30%% higher.\n" " -q -- Disable speed-up heuristics. May increase quality.\n" " -r rate -- Set playback rate. 2.0 means 2X faster, and 2X pitch.\n" " -s speed -- Set speed up factor. 2.0 means 2X faster.\n" " -v volume -- Scale volume by a constant factor.\n"); exit(1); } int main( int argc, char **argv) { waveFile inFile, outFile; char *inFileName, *outFileName; float speed = 1.0f; float pitch = 1.0f; float rate = 1.0f; float volume = 1.0f; int emulateChordPitch = 0; int quality = 0; int sampleRate, numChannels; int xArg = 1; while(xArg < argc && *(argv[xArg]) == '-') { if(!strcmp(argv[xArg], "-c")) { emulateChordPitch = 1; printf("Scaling pitch linearly.\n"); } else if(!strcmp(argv[xArg], "-p")) { xArg++; if(xArg < argc) { pitch = atof(argv[xArg]); printf("Setting pitch to %0.2fX\n", pitch); } } else if(!strcmp(argv[xArg], "-q")) { quality = 1; printf("Disabling speed-up heuristics\n"); } else if(!strcmp(argv[xArg], "-r")) { xArg++; if(xArg < argc) { rate = atof(argv[xArg]); printf("Setting rate to %0.2fX\n", rate); } } else if(!strcmp(argv[xArg], "-s")) { xArg++; if(xArg < argc) { speed = atof(argv[xArg]); printf("Setting speed to %0.2fX\n", speed); } } else if(!strcmp(argv[xArg], "-v")) { xArg++; if(xArg < argc) { volume = atof(argv[xArg]); printf("Setting volume to %0.2f\n", volume); } } xArg++; } if(argc - xArg != 2) { usage(); } inFileName = argv[xArg]; outFileName = argv[xArg + 1]; inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels); if(inFile == NULL) { return 1; } outFile = openOutputWaveFile(outFileName, sampleRate, numChannels); if(outFile == NULL) { closeWaveFile(inFile); return 1; } runSonic(inFile, outFile, speed, pitch, rate, volume, emulateChordPitch, quality, sampleRate, numChannels); closeWaveFile(inFile); closeWaveFile(outFile); return 0; }