blob: e77221c86587ee426b00d6bd55af518c4404140f [file] [log] [blame]
Bill Coxca02d872010-11-02 15:10:52 -04001/* Sonic library
2 Copyright 2010
3 Bill Cox
4 This file is part of the Sonic Library.
5
Bill Coxa9999872010-11-11 14:36:59 -05006 The Sonic Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
Bill Coxca02d872010-11-02 15:10:52 -040010
Bill Coxa9999872010-11-11 14:36:59 -050011 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
Bill Coxca02d872010-11-02 15:10:52 -040015
Bill Coxa9999872010-11-11 14:36:59 -050016 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
Bill Coxca02d872010-11-02 15:10:52 -040020
21/*
22Read wave files and speed them up or slow them down.
23*/
24
25#include <stdio.h>
26#include <stdlib.h>
Bill Cox0e4ec5e2010-11-09 13:26:40 -050027#include <string.h>
Bill Coxca02d872010-11-02 15:10:52 -040028#include "sonic.h"
29#include "wave.h"
30
Bill Cox1a299bb2010-11-19 15:07:17 -050031#define BUFFER_SIZE 2048
Bill Coxca02d872010-11-02 15:10:52 -040032
33/* Run sonic. */
34static void runSonic(
Bill Cox0c4cade2010-11-09 05:54:54 -050035 waveFile inFile,
36 waveFile outFile,
Bill Coxd544fdb2010-11-23 14:13:46 -050037 float speed,
38 float pitch,
39 float volume,
Bill Cox1a299bb2010-11-19 15:07:17 -050040 int sampleRate,
41 int numChannels)
Bill Coxca02d872010-11-02 15:10:52 -040042{
Bill Coxd544fdb2010-11-23 14:13:46 -050043 sonicStream stream = sonicCreateStream(sampleRate, numChannels);
Bill Cox0c4c0602010-11-08 11:46:30 -050044 short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
Bill Cox0c4cade2010-11-09 05:54:54 -050045 int samplesRead, samplesWritten;
Bill Coxca02d872010-11-02 15:10:52 -040046
Bill Coxd544fdb2010-11-23 14:13:46 -050047 sonicSetSpeed(stream, speed);
48 sonicSetPitch(stream, pitch);
49 sonicSetVolume(stream, volume);
Bill Cox0c4cade2010-11-09 05:54:54 -050050 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050051 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050052 if(samplesRead == 0) {
Bill Coxca02d872010-11-02 15:10:52 -040053 sonicFlushStream(stream);
Bill Cox0c4cade2010-11-09 05:54:54 -050054 } else {
55 sonicWriteShortToStream(stream, inBuffer, samplesRead);
Bill Coxca02d872010-11-02 15:10:52 -040056 }
Bill Cox882fb1d2010-11-02 16:27:20 -040057 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050058 samplesWritten = sonicReadShortFromStream(stream, outBuffer,
59 BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050060 if(samplesWritten > 0) {
61 writeToWaveFile(outFile, outBuffer, samplesWritten);
Bill Cox882fb1d2010-11-02 16:27:20 -040062 }
Bill Cox0c4cade2010-11-09 05:54:54 -050063 } while(samplesWritten > 0);
64 } while(samplesRead > 0);
65 sonicDestroyStream(stream);
Bill Coxca02d872010-11-02 15:10:52 -040066}
67
68/* Print the usage. */
69static void usage(void)
70{
Bill Cox0e4ec5e2010-11-09 13:26:40 -050071 fprintf(stderr, "Usage: sonic [-s speed] [-v volume] infile outfile\n"
Bill Coxd544fdb2010-11-23 14:13:46 -050072 " -p -- Set pitch scaling factor. 1.3 means 30%% higher.\n"
73 " -s -- Set speed up factor. 1.0 means no change, 2.0 means 2X faster.\n"
Bill Cox0e4ec5e2010-11-09 13:26:40 -050074 " -v -- Scale volume as percentage of maximum allowed. 100 uses full range.\n");
Bill Cox3a7abf92010-11-06 15:18:49 -040075 exit(1);
Bill Coxca02d872010-11-02 15:10:52 -040076}
77
78int main(
79 int argc,
80 char **argv)
81{
Bill Cox0c4cade2010-11-09 05:54:54 -050082 waveFile inFile, outFile;
Bill Coxca02d872010-11-02 15:10:52 -040083 char *inFileName, *outFileName;
Bill Coxd544fdb2010-11-23 14:13:46 -050084 float speed = 1.0;
85 float pitch = 1.0;
86 float volume = 1.0;
Bill Cox1a299bb2010-11-19 15:07:17 -050087 int sampleRate, numChannels;
Bill Cox0e4ec5e2010-11-09 13:26:40 -050088 int xArg = 1;
Bill Coxca02d872010-11-02 15:10:52 -040089
Bill Coxd544fdb2010-11-23 14:13:46 -050090 if(argc < 2 || *(argv[xArg]) != '-') {
91 fprintf(stderr, "You must provide at least one option to change speed,"
92 "pitch, or volume.\n");
93 usage();
94 return 1;
95 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -050096 while(xArg < argc && *(argv[xArg]) == '-') {
Bill Coxd544fdb2010-11-23 14:13:46 -050097 if(!strcmp(argv[xArg], "-p")) {
98 xArg++;
99 if(xArg < argc) {
100 pitch = atof(argv[xArg]);
Bill Coxd76d2222010-11-24 11:42:29 -0500101 printf("Setting pitch to %0.2f%%\n", pitch*100.0f);
Bill Coxd544fdb2010-11-23 14:13:46 -0500102 }
103 } else if(!strcmp(argv[xArg], "-s")) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500104 xArg++;
105 if(xArg < argc) {
106 speed = atof(argv[xArg]);
Bill Coxd76d2222010-11-24 11:42:29 -0500107 printf("Setting speed to %0.2f%%\n", speed*100.0f);
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500108 }
109 } else if(!strcmp(argv[xArg], "-v")) {
110 xArg++;
111 if(xArg < argc) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500112 volume = atof(argv[xArg]);
Bill Coxd76d2222010-11-24 11:42:29 -0500113 printf("Setting volume to %0.2f%%\n", volume*100.0f);
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500114 }
115 }
116 xArg++;
117 }
Bill Coxd544fdb2010-11-23 14:13:46 -0500118 if(argc - xArg != 2) {
Bill Coxca02d872010-11-02 15:10:52 -0400119 usage();
120 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500121 inFileName = argv[xArg];
122 outFileName = argv[xArg + 1];
Bill Cox1a299bb2010-11-19 15:07:17 -0500123 inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500124 if(inFile == NULL) {
125 return 1;
126 }
Bill Cox1a299bb2010-11-19 15:07:17 -0500127 outFile = openOutputWaveFile(outFileName, sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500128 if(outFile == NULL) {
129 closeWaveFile(inFile);
130 return 1;
131 }
Bill Coxd544fdb2010-11-23 14:13:46 -0500132 runSonic(inFile, outFile, speed, pitch, volume, sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500133 closeWaveFile(inFile);
134 closeWaveFile(outFile);
Bill Coxca02d872010-11-02 15:10:52 -0400135 return 0;
136}