main.c revision 9d1402171689d5b13869fe3f9d8ef753996a6fb5
19d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox/* This file, main.c, was written by Bill Cox in 2010, and placed into the public domain. 29d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox Feel free to copy and paste code from this file into your application. Note, 39d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox however, that the other source files, sonic.c and sonic.h, are LGPL. 4ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 59d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox This file is meant as a simple example for how to use libsonic. It is also a 69d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox useful utility on it's own, which can speed up or slow down wav files, change 79d1402171689d5b13869fe3f9d8ef753996a6fb5Bill Cox pitch, and scale volume. */ 8ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 9ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox#include <stdio.h> 10ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox#include <stdlib.h> 110e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox#include <string.h> 12ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox#include "sonic.h" 13ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox#include "wave.h" 14ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 151a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox#define BUFFER_SIZE 2048 16ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 17ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox/* Run sonic. */ 18ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Coxstatic void runSonic( 190c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox waveFile inFile, 200c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox waveFile outFile, 21d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float speed, 22d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float pitch, 23d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float volume, 24c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox int quality, 251a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox int sampleRate, 261a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox int numChannels) 27ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox{ 28d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox sonicStream stream = sonicCreateStream(sampleRate, numChannels); 290c4c06089176345f408613c8da6a5585a9af9615Bill Cox short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE]; 300c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox int samplesRead, samplesWritten; 31ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 32d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox sonicSetSpeed(stream, speed); 33d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox sonicSetPitch(stream, pitch); 34d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox sonicSetVolume(stream, volume); 35c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox sonicSetQuality(stream, quality); 360c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox do { 371a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels); 380c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox if(samplesRead == 0) { 39ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox sonicFlushStream(stream); 400c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox } else { 410c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox sonicWriteShortToStream(stream, inBuffer, samplesRead); 42ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox } 43882fb1db2700b48a33c11783635e936780199840Bill Cox do { 441a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox samplesWritten = sonicReadShortFromStream(stream, outBuffer, 451a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox BUFFER_SIZE/numChannels); 460c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox if(samplesWritten > 0) { 470c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox writeToWaveFile(outFile, outBuffer, samplesWritten); 48882fb1db2700b48a33c11783635e936780199840Bill Cox } 490c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox } while(samplesWritten > 0); 500c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox } while(samplesRead > 0); 510c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox sonicDestroyStream(stream); 52ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox} 53ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 54ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox/* Print the usage. */ 55ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Coxstatic void usage(void) 56ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox{ 57c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox fprintf(stderr, "Usage: sonic [OPTION]... infile outfile\n" 58c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox " -p pitch -- Set pitch scaling factor. 1.3 means 30%% higher.\n" 59c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox " -q -- Disable speed-up heuristics. May increase quality.\n" 60c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox " -s speed -- Set speed up factor. 2.0 means 2X faster.\n" 61c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox " -v volume -- Scale volume by a constant factor.\n"); 623a7abf9306e470963a422881af62811633fede47Bill Cox exit(1); 63ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox} 64ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 65ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Coxint main( 66ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox int argc, 67ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox char **argv) 68ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox{ 690c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox waveFile inFile, outFile; 70ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox char *inFileName, *outFileName; 71d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float speed = 1.0; 72d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float pitch = 1.0; 73d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox float volume = 1.0; 74c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox int quality = 0; 751a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox int sampleRate, numChannels; 760e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox int xArg = 1; 77ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox 78d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox if(argc < 2 || *(argv[xArg]) != '-') { 79d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox fprintf(stderr, "You must provide at least one option to change speed," 80d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox "pitch, or volume.\n"); 81d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox usage(); 82d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox return 1; 83d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox } 840e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox while(xArg < argc && *(argv[xArg]) == '-') { 85d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox if(!strcmp(argv[xArg], "-p")) { 86d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox xArg++; 87d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox if(xArg < argc) { 88d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox pitch = atof(argv[xArg]); 89d76d222882a9e098d148278592d155842326909bBill Cox printf("Setting pitch to %0.2f%%\n", pitch*100.0f); 90d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox } 91c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox } else if(!strcmp(argv[xArg], "-q")) { 92c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox quality = 1; 93c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox printf("Disabling speed-up heuristics\n"); 94d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox } else if(!strcmp(argv[xArg], "-s")) { 950e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox xArg++; 960e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox if(xArg < argc) { 970e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox speed = atof(argv[xArg]); 98d76d222882a9e098d148278592d155842326909bBill Cox printf("Setting speed to %0.2f%%\n", speed*100.0f); 990e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox } 1000e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox } else if(!strcmp(argv[xArg], "-v")) { 1010e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox xArg++; 1020e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox if(xArg < argc) { 1030e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox volume = atof(argv[xArg]); 104c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox printf("Setting volume to %0.2f\n", volume); 1050e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox } 1060e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox } 1070e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox xArg++; 1080e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox } 109d544fdb83eee1360eedfdcbd1e24a983403bb314Bill Cox if(argc - xArg != 2) { 110ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox usage(); 111ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox } 1120e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox inFileName = argv[xArg]; 1130e4ec5e65f696f6648feeeace9adc77dd69e2532Bill Cox outFileName = argv[xArg + 1]; 1141a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels); 1150c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox if(inFile == NULL) { 1160c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox return 1; 1170c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox } 1181a299bb54901f02ef8cd0d9f3774e2a67b85e938Bill Cox outFile = openOutputWaveFile(outFileName, sampleRate, numChannels); 1190c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox if(outFile == NULL) { 1200c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox closeWaveFile(inFile); 1210c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox return 1; 1220c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox } 123c978c39e1abbdf7bd650a4a74d5936fd0d2b0f0dBill Cox runSonic(inFile, outFile, speed, pitch, volume, quality, sampleRate, numChannels); 1240c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox closeWaveFile(inFile); 1250c4cade6939162c0700dd5d701bf91095bcc9eddBill Cox closeWaveFile(outFile); 126ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox return 0; 127ca02d872cc6cb963d438ceae6d011bd04c658b3Bill Cox} 128