blob: 740ce4ab2b8a248d0d598da158256f315caed991 [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 Cox59e65122010-11-03 10:06:29 -040031#define BUFFER_SIZE 1024
Bill Coxca02d872010-11-02 15:10:52 -040032
Bill Cox0e4ec5e2010-11-09 13:26:40 -050033/* Scan through the input file to find it's maximum value. */
34static int findMaximumVolume(
35 waveFile inFile)
36{
37 short inBuffer[BUFFER_SIZE];
38 int samplesRead, i;
39 int maxValue = 0, value;
40
41 do {
42 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE);
43 for(i = 0; i < samplesRead; i++) {
44 value = inBuffer[i];
45 if(value < 0) {
46 value = -value;
47 }
48 if(value > maxValue) {
49 maxValue = value;
50 }
51 }
52 } while(samplesRead > 0);
53 return maxValue;
54}
55
56/* Scale the samples by the factor. */
57static void scaleSamples(
58 short *samples,
59 int numSamples,
60 double scale)
61{
62 while(numSamples--) {
63 *samples = (short)(*samples*scale + 0.5);
64 samples++;
65 }
66}
67
Bill Coxca02d872010-11-02 15:10:52 -040068/* Run sonic. */
69static void runSonic(
Bill Cox0c4cade2010-11-09 05:54:54 -050070 waveFile inFile,
71 waveFile outFile,
72 double speed,
Bill Cox0e4ec5e2010-11-09 13:26:40 -050073 double scale,
Bill Cox0c4cade2010-11-09 05:54:54 -050074 int sampleRate)
Bill Coxca02d872010-11-02 15:10:52 -040075{
Bill Coxca02d872010-11-02 15:10:52 -040076 sonicStream stream = sonicCreateStream(speed, sampleRate);
Bill Cox0c4c0602010-11-08 11:46:30 -050077 short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
Bill Cox0c4cade2010-11-09 05:54:54 -050078 int samplesRead, samplesWritten;
Bill Coxca02d872010-11-02 15:10:52 -040079
Bill Cox0c4cade2010-11-09 05:54:54 -050080 do {
81 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE);
82 if(samplesRead == 0) {
Bill Coxca02d872010-11-02 15:10:52 -040083 sonicFlushStream(stream);
Bill Cox0c4cade2010-11-09 05:54:54 -050084 } else {
Bill Cox0e4ec5e2010-11-09 13:26:40 -050085 if(scale != 1.0) {
86 scaleSamples(inBuffer, samplesRead, scale);
87 }
Bill Cox0c4cade2010-11-09 05:54:54 -050088 sonicWriteShortToStream(stream, inBuffer, samplesRead);
Bill Coxca02d872010-11-02 15:10:52 -040089 }
Bill Cox882fb1d2010-11-02 16:27:20 -040090 do {
Bill Cox0c4cade2010-11-09 05:54:54 -050091 samplesWritten = sonicReadShortFromStream(stream, outBuffer, BUFFER_SIZE);
92 if(samplesWritten > 0) {
93 writeToWaveFile(outFile, outBuffer, samplesWritten);
Bill Cox882fb1d2010-11-02 16:27:20 -040094 }
Bill Cox0c4cade2010-11-09 05:54:54 -050095 } while(samplesWritten > 0);
96 } while(samplesRead > 0);
97 sonicDestroyStream(stream);
Bill Coxca02d872010-11-02 15:10:52 -040098}
99
100/* Print the usage. */
101static void usage(void)
102{
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500103 fprintf(stderr, "Usage: sonic [-s speed] [-v volume] infile outfile\n"
104 " -s -- Set speed up factor. 1.0 means no change, 2.0 means 2X faster\n"
105 " -v -- Scale volume as percentage of maximum allowed. 100 uses full range.\n");
Bill Cox3a7abf92010-11-06 15:18:49 -0400106 exit(1);
Bill Coxca02d872010-11-02 15:10:52 -0400107}
108
109int main(
110 int argc,
111 char **argv)
112{
Bill Cox0c4cade2010-11-09 05:54:54 -0500113 waveFile inFile, outFile;
Bill Coxca02d872010-11-02 15:10:52 -0400114 char *inFileName, *outFileName;
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500115 double speed = 1.0;
116 int setVolume = 0;
117 int maxVolume;
118 double volume = 1.0;
Bill Cox0c4cade2010-11-09 05:54:54 -0500119 int sampleRate;
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500120 double scale = 1.0;
121 int xArg = 1;
Bill Coxca02d872010-11-02 15:10:52 -0400122
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500123 while(xArg < argc && *(argv[xArg]) == '-') {
124 if(!strcmp(argv[xArg], "-s")) {
125 xArg++;
126 if(xArg < argc) {
127 speed = atof(argv[xArg]);
128 printf("Setting speed to %f\n", speed);
129 }
130 } else if(!strcmp(argv[xArg], "-v")) {
131 xArg++;
132 if(xArg < argc) {
133 setVolume = 1;
134 volume = atof(argv[xArg]);
135 printf("Setting volume to %0.2f%%\n", volume);
136 volume /= 100.0;
137 }
138 }
139 xArg++;
140 }
141 if(argc -xArg != 2) {
Bill Coxca02d872010-11-02 15:10:52 -0400142 usage();
143 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500144 inFileName = argv[xArg];
145 outFileName = argv[xArg + 1];
Bill Cox0c4cade2010-11-09 05:54:54 -0500146 inFile = openInputWaveFile(inFileName, &sampleRate);
147 if(inFile == NULL) {
148 return 1;
149 }
150 outFile = openOutputWaveFile(outFileName, sampleRate);
151 if(outFile == NULL) {
152 closeWaveFile(inFile);
153 return 1;
154 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500155 if(setVolume) {
156 maxVolume = findMaximumVolume(inFile);
157 if(maxVolume != 0) {
158 scale = volume*32768.0f/maxVolume;
159 }
160 printf("Scale = %0.2f\n", scale);
161 closeWaveFile(inFile);
162 inFile = openInputWaveFile(inFileName, &sampleRate);
163 if(inFile == NULL) {
164 closeWaveFile(outFile);
165 return 1;
166 }
167 }
168 runSonic(inFile, outFile, speed, scale, sampleRate);
Bill Cox0c4cade2010-11-09 05:54:54 -0500169 closeWaveFile(inFile);
170 closeWaveFile(outFile);
Bill Coxca02d872010-11-02 15:10:52 -0400171 return 0;
172}