blob: 20bfd9adbb7922b5167d9e3f1a1279dd0fff365b [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,
23 float volume,
Bill Coxc978c392010-12-17 05:04:06 -050024 int quality,
Bill Cox1a299bb2010-11-19 15:07:17 -050025 int sampleRate,
26 int numChannels)
Bill Coxca02d872010-11-02 15:10:52 -040027{
Bill Coxd544fdb2010-11-23 14:13:46 -050028 sonicStream stream = sonicCreateStream(sampleRate, numChannels);
Bill Cox0c4c0602010-11-08 11:46:30 -050029 short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
Bill Cox0c4cade2010-11-09 05:54:54 -050030 int samplesRead, samplesWritten;
Bill Coxca02d872010-11-02 15:10:52 -040031
Bill Coxd544fdb2010-11-23 14:13:46 -050032 sonicSetSpeed(stream, speed);
33 sonicSetPitch(stream, pitch);
34 sonicSetVolume(stream, volume);
Bill Coxc978c392010-12-17 05:04:06 -050035 sonicSetQuality(stream, quality);
Bill Cox0c4cade2010-11-09 05:54:54 -050036 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050037 samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050038 if(samplesRead == 0) {
Bill Coxca02d872010-11-02 15:10:52 -040039 sonicFlushStream(stream);
Bill Cox0c4cade2010-11-09 05:54:54 -050040 } else {
41 sonicWriteShortToStream(stream, inBuffer, samplesRead);
Bill Coxca02d872010-11-02 15:10:52 -040042 }
Bill Cox882fb1d2010-11-02 16:27:20 -040043 do {
Bill Cox1a299bb2010-11-19 15:07:17 -050044 samplesWritten = sonicReadShortFromStream(stream, outBuffer,
45 BUFFER_SIZE/numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -050046 if(samplesWritten > 0) {
47 writeToWaveFile(outFile, outBuffer, samplesWritten);
Bill Cox882fb1d2010-11-02 16:27:20 -040048 }
Bill Cox0c4cade2010-11-09 05:54:54 -050049 } while(samplesWritten > 0);
50 } while(samplesRead > 0);
51 sonicDestroyStream(stream);
Bill Coxca02d872010-11-02 15:10:52 -040052}
53
54/* Print the usage. */
55static void usage(void)
56{
Bill Coxc978c392010-12-17 05:04:06 -050057 fprintf(stderr, "Usage: sonic [OPTION]... infile outfile\n"
58 " -p pitch -- Set pitch scaling factor. 1.3 means 30%% higher.\n"
59 " -q -- Disable speed-up heuristics. May increase quality.\n"
60 " -s speed -- Set speed up factor. 2.0 means 2X faster.\n"
61 " -v volume -- Scale volume by a constant factor.\n");
Bill Cox3a7abf92010-11-06 15:18:49 -040062 exit(1);
Bill Coxca02d872010-11-02 15:10:52 -040063}
64
65int main(
66 int argc,
67 char **argv)
68{
Bill Cox0c4cade2010-11-09 05:54:54 -050069 waveFile inFile, outFile;
Bill Coxca02d872010-11-02 15:10:52 -040070 char *inFileName, *outFileName;
Bill Coxd544fdb2010-11-23 14:13:46 -050071 float speed = 1.0;
72 float pitch = 1.0;
73 float volume = 1.0;
Bill Coxc978c392010-12-17 05:04:06 -050074 int quality = 0;
Bill Cox1a299bb2010-11-19 15:07:17 -050075 int sampleRate, numChannels;
Bill Cox0e4ec5e2010-11-09 13:26:40 -050076 int xArg = 1;
Bill Coxca02d872010-11-02 15:10:52 -040077
Bill Coxd544fdb2010-11-23 14:13:46 -050078 if(argc < 2 || *(argv[xArg]) != '-') {
79 fprintf(stderr, "You must provide at least one option to change speed,"
80 "pitch, or volume.\n");
81 usage();
82 return 1;
83 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -050084 while(xArg < argc && *(argv[xArg]) == '-') {
Bill Coxd544fdb2010-11-23 14:13:46 -050085 if(!strcmp(argv[xArg], "-p")) {
86 xArg++;
87 if(xArg < argc) {
88 pitch = atof(argv[xArg]);
Bill Coxd76d2222010-11-24 11:42:29 -050089 printf("Setting pitch to %0.2f%%\n", pitch*100.0f);
Bill Coxd544fdb2010-11-23 14:13:46 -050090 }
Bill Coxc978c392010-12-17 05:04:06 -050091 } else if(!strcmp(argv[xArg], "-q")) {
Bill Coxc978c392010-12-17 05:04:06 -050092 quality = 1;
93 printf("Disabling speed-up heuristics\n");
Bill Coxd544fdb2010-11-23 14:13:46 -050094 } else if(!strcmp(argv[xArg], "-s")) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -050095 xArg++;
96 if(xArg < argc) {
97 speed = atof(argv[xArg]);
Bill Coxd76d2222010-11-24 11:42:29 -050098 printf("Setting speed to %0.2f%%\n", speed*100.0f);
Bill Cox0e4ec5e2010-11-09 13:26:40 -050099 }
100 } else if(!strcmp(argv[xArg], "-v")) {
101 xArg++;
102 if(xArg < argc) {
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500103 volume = atof(argv[xArg]);
Bill Coxc978c392010-12-17 05:04:06 -0500104 printf("Setting volume to %0.2f\n", volume);
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500105 }
106 }
107 xArg++;
108 }
Bill Coxd544fdb2010-11-23 14:13:46 -0500109 if(argc - xArg != 2) {
Bill Coxca02d872010-11-02 15:10:52 -0400110 usage();
111 }
Bill Cox0e4ec5e2010-11-09 13:26:40 -0500112 inFileName = argv[xArg];
113 outFileName = argv[xArg + 1];
Bill Cox1a299bb2010-11-19 15:07:17 -0500114 inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500115 if(inFile == NULL) {
116 return 1;
117 }
Bill Cox1a299bb2010-11-19 15:07:17 -0500118 outFile = openOutputWaveFile(outFileName, sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500119 if(outFile == NULL) {
120 closeWaveFile(inFile);
121 return 1;
122 }
Bill Coxc978c392010-12-17 05:04:06 -0500123 runSonic(inFile, outFile, speed, pitch, volume, quality, sampleRate, numChannels);
Bill Cox0c4cade2010-11-09 05:54:54 -0500124 closeWaveFile(inFile);
125 closeWaveFile(outFile);
Bill Coxca02d872010-11-02 15:10:52 -0400126 return 0;
127}