/* This file was written by Bill Cox in 2010, and is licensed under the Apache
   2.0 license.

   This file is meant as a simple example for how to use libsonic.  It is also a
   useful utility on it's own, which can speed up or slow down wav files, change
   pitch, and scale volume. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sonic.h"
#include "wave.h"

#define BUFFER_SIZE 2048

/* Run sonic. */
static void runSonic(
    waveFile inFile,
    waveFile outFile,
    float speed,
    float pitch,
    float rate,
    float volume,
    int emulateChordPitch,
    int quality,
    int sampleRate,
    int numChannels)
{
    sonicStream stream = sonicCreateStream(sampleRate, numChannels);
    short inBuffer[BUFFER_SIZE], outBuffer[BUFFER_SIZE];
    int samplesRead, samplesWritten;

    sonicSetSpeed(stream, speed);
    sonicSetPitch(stream, pitch);
    sonicSetRate(stream, rate);
    sonicSetVolume(stream, volume);
    sonicSetChordPitch(stream, emulateChordPitch);
    sonicSetQuality(stream, quality);
    do {
        samplesRead = readFromWaveFile(inFile, inBuffer, BUFFER_SIZE/numChannels);
	if(samplesRead == 0) {
	    sonicFlushStream(stream);
	} else {
	    sonicWriteShortToStream(stream, inBuffer, samplesRead);
	}
	do {
	    samplesWritten = sonicReadShortFromStream(stream, outBuffer,
	        BUFFER_SIZE/numChannels);
	    if(samplesWritten > 0) {
		writeToWaveFile(outFile, outBuffer, samplesWritten);
	    }
	} while(samplesWritten > 0);
    } while(samplesRead > 0);
    sonicDestroyStream(stream);
}

/* Print the usage. */
static void usage(void)
{
    fprintf(stderr, "Usage: sonic [OPTION]... infile outfile\n"
        "    -c         -- Modify pitch by emulating vocal chords vibrating\n"
	"                  faster or slower.\n"
        "    -p pitch   -- Set pitch scaling factor.  1.3 means 30%% higher.\n"
        "    -q         -- Disable speed-up heuristics.  May increase quality.\n"
        "    -r rate    -- Set playback rate.  2.0 means 2X faster, and 2X pitch.\n"
        "    -s speed   -- Set speed up factor.  2.0 means 2X faster.\n"
	"    -v volume  -- Scale volume by a constant factor.\n");
    exit(1);
}

int main(
    int argc,
    char **argv)
{
    waveFile inFile, outFile;
    char *inFileName, *outFileName;
    float speed = 1.0f;
    float pitch = 1.0f;
    float rate = 1.0f;
    float volume = 1.0f;
    int emulateChordPitch = 0;
    int quality = 0;
    int sampleRate, numChannels;
    int xArg = 1;

    while(xArg < argc && *(argv[xArg]) == '-') {
	if(!strcmp(argv[xArg], "-c")) {
	    emulateChordPitch = 1;
	    printf("Scaling pitch linearly.\n");
	} else if(!strcmp(argv[xArg], "-p")) {
	    xArg++;
	    if(xArg < argc) {
	        pitch = atof(argv[xArg]);
                printf("Setting pitch to %0.2fX\n", pitch);
	    }
	} else if(!strcmp(argv[xArg], "-q")) {
	    quality = 1;
	    printf("Disabling speed-up heuristics\n");
	} else if(!strcmp(argv[xArg], "-r")) {
	    xArg++;
	    if(xArg < argc) {
	        rate = atof(argv[xArg]);
                printf("Setting rate to %0.2fX\n", rate);
	    }
	} else if(!strcmp(argv[xArg], "-s")) {
	    xArg++;
	    if(xArg < argc) {
	        speed = atof(argv[xArg]);
                printf("Setting speed to %0.2fX\n", speed);
	    }
	} else if(!strcmp(argv[xArg], "-v")) {
	    xArg++;
	    if(xArg < argc) {
	        volume = atof(argv[xArg]);
                printf("Setting volume to %0.2f\n", volume);
	    }
	}
	xArg++;
    }
    if(argc - xArg != 2) {
	usage();
    }
    inFileName = argv[xArg];
    outFileName = argv[xArg + 1];
    inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
    if(inFile == NULL) {
	return 1;
    }
    outFile = openOutputWaveFile(outFileName, sampleRate, numChannels);
    if(outFile == NULL) {
	closeWaveFile(inFile);
	return 1;
    }
    runSonic(inFile, outFile, speed, pitch, rate, volume, emulateChordPitch, quality,
        sampleRate, numChannels);
    closeWaveFile(inFile);
    closeWaveFile(outFile);
    return 0;
}
