blob: 9fdee9c7c14fd27c0a878a219ef1010d85386ca4 [file] [log] [blame]
Bill Cox9d140212011-01-09 11:45:41 -05001/* This file, main.c, was written by Bill Cox in 2010, and placed into the public domain.
2 Feel free to copy and paste code from this file into your application. Note,
3 however, that the other source files, sonic.c and sonic.h, are LGPL.
Bill Coxca02d872010-11-02 15:10:52 -04004
Bill Cox9d140212011-01-09 11:45:41 -05005 This file is meant as a simple example for how to use libsonic. It is also a
6 useful utility on it's own, which can speed up or slow down wav files, change
7 pitch, and scale volume. */
Bill Coxca02d872010-11-02 15:10:52 -04008
9#include <stdio.h>
10#include <stdlib.h>
Bill Cox0e4ec5e2010-11-09 13:26:40 -050011#include <string.h>
Bill Coxca02d872010-11-02 15:10:52 -040012#include "sonic.h"
13#include "wave.h"
14
Bill Cox1a299bb2010-11-19 15:07:17 -050015#define BUFFER_SIZE 2048
Bill Coxca02d872010-11-02 15:10:52 -040016
17/* Run sonic. */
18static void runSonic(
Bill Cox0c4cade2010-11-09 05:54:54 -050019 waveFile inFile,
20 waveFile outFile,
Bill Coxd544fdb2010-11-23 14:13:46 -050021 float speed,
22 float pitch,
Bill Cox3276bb02011-01-11 07:39:26 -050023 float rate,
Bill Coxd544fdb2010-11-23 14:13:46 -050024 float volume,
Bill Cox3276bb02011-01-11 07:39:26 -050025 int emulateChordPitch,
Bill Coxc978c392010-12-17 05:04:06 -050026 int quality,
Bill Cox1a299bb2010-11-19 15:07:17 -050027 int sampleRate,
28 int numChannels)
Bill Coxca02d872010-11-02 15:10:52 -040029{
Bill Coxd544fdb2010-11-23 14:13:46 -050030 sonicStream stream = sonicCreateStream(sampleRate, numChannels);
Bill Cox0c4c0602010-11-08 11:46:30 -050031 short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
Bill Cox0c4cade2010-11-09 05:54:54 -050032 int samplesRead, samplesWritten;
Bill Coxca02d872010-11-02 15:10:52 -040033
Bill Coxd544fdb2010-11-23 14:13:46 -050034 sonicSetSpeed(stream, speed);
35 sonicSetPitch(stream, pitch);
Bill Cox3276bb02011-01-11 07:39:26 -050036 sonicSetRate(stream, rate);
Bill Coxd544fdb2010-11-23 14:13:46 -050037 sonicSetVolume(stream, volume);
Bill Cox3276bb02011-01-11 07:39:26 -050038 sonicSetChordPitch(stream, emulateChordPitch);
Bill Coxc978c392010-12-17 05:04:06 -050039 sonicSetQuality(stream, quality);
Bill Cox0c4cade2010-11-09 05:54:54 -050040 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050041 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050042 if(samplesRead == 0) {
Bill Coxca02d872010-11-02 15:10:52 -040043 sonicFlushStream(stream);
Bill Cox0c4cade2010-11-09 05:54:54 -050044 } else {
45 sonicWriteShortToStream(stream, inBuffer, samplesRead);
Bill Coxca02d872010-11-02 15:10:52 -040046 }
Bill Cox882fb1d2010-11-02 16:27:20 -040047 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050048 samplesWritten = sonicReadShortFromStream(stream, outBuffer,
49 BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050050 if(samplesWritten > 0) {
51 writeToWaveFile(outFile, outBuffer, samplesWritten);
Bill Cox882fb1d2010-11-02 16:27:20 -040052 }
Bill Cox0c4cade2010-11-09 05:54:54 -050053 } while(samplesWritten > 0);
54 } while(samplesRead > 0);
55 sonicDestroyStream(stream);
Bill Coxca02d872010-11-02 15:10:52 -040056}
57
58/* Print the usage. */
59static void usage(void)
60{
Bill Coxc978c392010-12-17 05:04:06 -050061 fprintf(stderr, "Usage: sonic [OPTION]... infile outfile\n"
Bill Cox3276bb02011-01-11 07:39:26 -050062 " -c -- Modify pitch by emulating vocal chords vibrating\n"
63 " faster or slower.\n"
Bill Coxc978c392010-12-17 05:04:06 -050064 " -p pitch -- Set pitch scaling factor. 1.3 means 30%% higher.\n"
65 " -q -- Disable speed-up heuristics. May increase quality.\n"
Bill Cox3276bb02011-01-11 07:39:26 -050066 " -r rate -- Set playback rate. 2.0 means 2X faster, and 2X pitch.\n"
Bill Coxc978c392010-12-17 05:04:06 -050067 " -s speed -- Set speed up factor. 2.0 means 2X faster.\n"
68 " -v volume -- Scale volume by a constant factor.\n");
Bill Cox3a7abf92010-11-06 15:18:49 -040069 exit(1);
Bill Coxca02d872010-11-02 15:10:52 -040070}
71
72int main(
73 int argc,
74 char **argv)
75{
Bill Cox0c4cade2010-11-09 05:54:54 -050076 waveFile inFile, outFile;
Bill Coxca02d872010-11-02 15:10:52 -040077 char *inFileName, *outFileName;
Bill Cox3276bb02011-01-11 07:39:26 -050078 float speed = 1.0f;
79 float pitch = 1.0f;
80 float rate = 1.0f;
81 float volume = 1.0f;
82 int emulateChordPitch = 0;
Bill Coxc978c392010-12-17 05:04:06 -050083 int quality = 0;
Bill Cox1a299bb2010-11-19 15:07:17 -050084 int sampleRate, numChannels;
Bill Cox0e4ec5e2010-11-09 13:26:40 -050085 int xArg = 1;
Bill Coxca02d872010-11-02 15:10:52 -040086
Bill Cox0e4ec5e2010-11-09 13:26:40 -050087 while(xArg < argc && *(argv[xArg]) == '-') {
Bill Cox3276bb02011-01-11 07:39:26 -050088 if(!strcmp(argv[xArg], "-c")) {
89 emulateChordPitch = 1;
90 printf("Scaling pitch linearly.\n");
91 } else if(!strcmp(argv[xArg], "-p")) {
Bill Coxd544fdb2010-11-23 14:13:46 -050092 xArg++;
93 if(xArg < argc) {
94 pitch = atof(argv[xArg]);
Bill Cox3276bb02011-01-11 07:39:26 -050095 printf("Setting pitch to %0.2fX\n", pitch);
Bill Coxd544fdb2010-11-23 14:13:46 -050096 }
Bill Coxc978c392010-12-17 05:04:06 -050097 } else if(!strcmp(argv[xArg], "-q")) {
Bill Coxc978c392010-12-17 05:04:06 -050098 quality = 1;
99 printf("Disabling speed-up heuristics\n");
Bill Cox3276bb02011-01-11 07:39:26 -0500100 } else if(!strcmp(argv[xArg], "-r")) {
101 xArg++;
102 if(xArg < argc) {
103 rate = atof(argv[xArg]);
104 printf("Setting rate to %0.2fX\n", rate);
105 }
Bill Coxd544fdb2010-11-23 14:13:46 -0500106 } else if(!strcmp(argv[xArg], "-s")) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500107 xArg++;
108 if(xArg < argc) {
109 speed = atof(argv[xArg]);
Bill Cox3276bb02011-01-11 07:39:26 -0500110 printf("Setting speed to %0.2fX\n", speed);
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500111 }
112 } else if(!strcmp(argv[xArg], "-v")) {
113 xArg++;
114 if(xArg < argc) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500115 volume = atof(argv[xArg]);
Bill Coxc978c392010-12-17 05:04:06 -0500116 printf("Setting volume to %0.2f\n", volume);
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500117 }
118 }
119 xArg++;
120 }
Bill Coxd544fdb2010-11-23 14:13:46 -0500121 if(argc - xArg != 2) {
Bill Coxca02d872010-11-02 15:10:52 -0400122 usage();
123 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500124 inFileName = argv[xArg];
125 outFileName = argv[xArg + 1];
Bill Cox1a299bb2010-11-19 15:07:17 -0500126 inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500127 if(inFile == NULL) {
128 return 1;
129 }
Bill Cox1a299bb2010-11-19 15:07:17 -0500130 outFile = openOutputWaveFile(outFileName, sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500131 if(outFile == NULL) {
132 closeWaveFile(inFile);
133 return 1;
134 }
Bill Cox3276bb02011-01-11 07:39:26 -0500135 runSonic(inFile, outFile, speed, pitch, rate, volume, emulateChordPitch, quality,
136 sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500137 closeWaveFile(inFile);
138 closeWaveFile(outFile);
Bill Coxca02d872010-11-02 15:10:52 -0400139 return 0;
140}