blob: 1814009efe9694ff5005c1149347d613da4a6005 [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
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
19
20/*
21Read wave files and speed them up or slow them down.
22*/
23
24#include <stdio.h>
25#include <stdlib.h>
Bill Cox0e4ec5e2010-11-09 13:26:40 -050026#include <string.h>
Bill Coxca02d872010-11-02 15:10:52 -040027#include "sonic.h"
28#include "wave.h"
29
Bill Cox59e65122010-11-03 10:06:29 -040030#define BUFFER_SIZE 1024
Bill Coxca02d872010-11-02 15:10:52 -040031
Bill Cox0e4ec5e2010-11-09 13:26:40 -050032/* Scan through the input file to find it's maximum value. */
33static int findMaximumVolume(
34 waveFile inFile)
35{
36 short inBuffer[BUFFER_SIZE];
37 int samplesRead, i;
38 int maxValue = 0, value;
39
40 do {
41 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE);
42 for(i = 0; i < samplesRead; i++) {
43 value = inBuffer[i];
44 if(value < 0) {
45 value = -value;
46 }
47 if(value > maxValue) {
48 maxValue = value;
49 }
50 }
51 } while(samplesRead > 0);
52 return maxValue;
53}
54
55/* Scale the samples by the factor. */
56static void scaleSamples(
57 short *samples,
58 int numSamples,
59 double scale)
60{
61 while(numSamples--) {
62 *samples = (short)(*samples*scale + 0.5);
63 samples++;
64 }
65}
66
Bill Coxca02d872010-11-02 15:10:52 -040067/* Run sonic. */
68static void runSonic(
Bill Cox0c4cade2010-11-09 05:54:54 -050069 waveFile inFile,
70 waveFile outFile,
71 double speed,
Bill Cox0e4ec5e2010-11-09 13:26:40 -050072 double scale,
Bill Cox0c4cade2010-11-09 05:54:54 -050073 int sampleRate)
Bill Coxca02d872010-11-02 15:10:52 -040074{
Bill Coxca02d872010-11-02 15:10:52 -040075 sonicStream stream = sonicCreateStream(speed, sampleRate);
Bill Cox0c4c0602010-11-08 11:46:30 -050076 short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
Bill Cox0c4cade2010-11-09 05:54:54 -050077 int samplesRead, samplesWritten;
Bill Coxca02d872010-11-02 15:10:52 -040078
Bill Cox0c4cade2010-11-09 05:54:54 -050079 do {
80 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE);
81 if(samplesRead == 0) {
Bill Coxca02d872010-11-02 15:10:52 -040082 sonicFlushStream(stream);
Bill Cox0c4cade2010-11-09 05:54:54 -050083 } else {
Bill Cox0e4ec5e2010-11-09 13:26:40 -050084 if(scale != 1.0) {
85 scaleSamples(inBuffer, samplesRead, scale);
86 }
Bill Cox0c4cade2010-11-09 05:54:54 -050087 sonicWriteShortToStream(stream, inBuffer, samplesRead);
Bill Coxca02d872010-11-02 15:10:52 -040088 }
Bill Cox882fb1d2010-11-02 16:27:20 -040089 do {
Bill Cox0c4cade2010-11-09 05:54:54 -050090 samplesWritten = sonicReadShortFromStream(stream, outBuffer, BUFFER_SIZE);
91 if(samplesWritten > 0) {
92 writeToWaveFile(outFile, outBuffer, samplesWritten);
Bill Cox882fb1d2010-11-02 16:27:20 -040093 }
Bill Cox0c4cade2010-11-09 05:54:54 -050094 } while(samplesWritten > 0);
95 } while(samplesRead > 0);
96 sonicDestroyStream(stream);
Bill Coxca02d872010-11-02 15:10:52 -040097}
98
99/* Print the usage. */
100static void usage(void)
101{
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500102 fprintf(stderr, "Usage: sonic [-s speed] [-v volume] infile outfile\n"
103 " -s -- Set speed up factor. 1.0 means no change, 2.0 means 2X faster\n"
104 " -v -- Scale volume as percentage of maximum allowed. 100 uses full range.\n");
Bill Cox3a7abf92010-11-06 15:18:49 -0400105 exit(1);
Bill Coxca02d872010-11-02 15:10:52 -0400106}
107
108int main(
109 int argc,
110 char **argv)
111{
Bill Cox0c4cade2010-11-09 05:54:54 -0500112 waveFile inFile, outFile;
Bill Coxca02d872010-11-02 15:10:52 -0400113 char *inFileName, *outFileName;
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500114 double speed = 1.0;
115 int setVolume = 0;
116 int maxVolume;
117 double volume = 1.0;
Bill Cox0c4cade2010-11-09 05:54:54 -0500118 int sampleRate;
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500119 double scale = 1.0;
120 int xArg = 1;
Bill Coxca02d872010-11-02 15:10:52 -0400121
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500122 while(xArg < argc && *(argv[xArg]) == '-') {
123 if(!strcmp(argv[xArg], "-s")) {
124 xArg++;
125 if(xArg < argc) {
126 speed = atof(argv[xArg]);
127 printf("Setting speed to %f\n", speed);
128 }
129 } else if(!strcmp(argv[xArg], "-v")) {
130 xArg++;
131 if(xArg < argc) {
132 setVolume = 1;
133 volume = atof(argv[xArg]);
134 printf("Setting volume to %0.2f%%\n", volume);
135 volume /= 100.0;
136 }
137 }
138 xArg++;
139 }
140 if(argc -xArg != 2) {
Bill Coxca02d872010-11-02 15:10:52 -0400141 usage();
142 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500143 inFileName = argv[xArg];
144 outFileName = argv[xArg + 1];
Bill Cox0c4cade2010-11-09 05:54:54 -0500145 inFile = openInputWaveFile(inFileName, &sampleRate);
146 if(inFile == NULL) {
147 return 1;
148 }
149 outFile = openOutputWaveFile(outFileName, sampleRate);
150 if(outFile == NULL) {
151 closeWaveFile(inFile);
152 return 1;
153 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500154 if(setVolume) {
155 maxVolume = findMaximumVolume(inFile);
156 if(maxVolume != 0) {
157 scale = volume*32768.0f/maxVolume;
158 }
159 printf("Scale = %0.2f\n", scale);
160 closeWaveFile(inFile);
161 inFile = openInputWaveFile(inFileName, &sampleRate);
162 if(inFile == NULL) {
163 closeWaveFile(outFile);
164 return 1;
165 }
166 }
167 runSonic(inFile, outFile, speed, scale, sampleRate);
Bill Cox0c4cade2010-11-09 05:54:54 -0500168 closeWaveFile(inFile);
169 closeWaveFile(outFile);
Bill Coxca02d872010-11-02 15:10:52 -0400170 return 0;
171}