1*b290403dSRicardo Garcia /* This file was written by Bill Cox in 2010, and is licensed under the Apache
2*b290403dSRicardo Garcia 2.0 license.
3*b290403dSRicardo Garcia
4*b290403dSRicardo Garcia This file is meant as a simple example for how to use libsonic. It is also a
5*b290403dSRicardo Garcia useful utility on its own, which can speed up or slow down wav files, change
6*b290403dSRicardo Garcia pitch, and scale volume. */
7*b290403dSRicardo Garcia
8*b290403dSRicardo Garcia #include <stdio.h>
9*b290403dSRicardo Garcia #include <stdlib.h>
10*b290403dSRicardo Garcia #include <string.h>
11*b290403dSRicardo Garcia #include "sonic_lite.h"
12*b290403dSRicardo Garcia #include "wave.h"
13*b290403dSRicardo Garcia
14*b290403dSRicardo Garcia /* Run sonic_lite. */
runSonic(char * inFileName,char * outFileName,float speed,float volume)15*b290403dSRicardo Garcia static void runSonic(char* inFileName, char* outFileName, float speed, float volume) {
16*b290403dSRicardo Garcia waveFile inFile, outFile = NULL;
17*b290403dSRicardo Garcia short inBuffer[SONIC_INPUT_SAMPLES], outBuffer[SONIC_INPUT_SAMPLES];
18*b290403dSRicardo Garcia int samplesRead, samplesWritten, sampleRate, numChannels;
19*b290403dSRicardo Garcia
20*b290403dSRicardo Garcia inFile = openInputWaveFile(inFileName, &sampleRate, &numChannels);
21*b290403dSRicardo Garcia if (numChannels != 1) {
22*b290403dSRicardo Garcia fprintf(stderr, "sonic_lite only processes mono wave files. This file has %d channels.\n",
23*b290403dSRicardo Garcia numChannels);
24*b290403dSRicardo Garcia exit(1);
25*b290403dSRicardo Garcia }
26*b290403dSRicardo Garcia if (sampleRate != SONIC_SAMPLE_RATE) {
27*b290403dSRicardo Garcia fprintf(stderr,
28*b290403dSRicardo Garcia "sonic_lite only processes wave files with a sample rate of %d Hz. This file uses %d\n",
29*b290403dSRicardo Garcia SONIC_SAMPLE_RATE, sampleRate);
30*b290403dSRicardo Garcia exit(1);
31*b290403dSRicardo Garcia }
32*b290403dSRicardo Garcia if (inFile == NULL) {
33*b290403dSRicardo Garcia fprintf(stderr, "Unable to read wave file %s\n", inFileName);
34*b290403dSRicardo Garcia exit(1);
35*b290403dSRicardo Garcia }
36*b290403dSRicardo Garcia outFile = openOutputWaveFile(outFileName, sampleRate, 1);
37*b290403dSRicardo Garcia if (outFile == NULL) {
38*b290403dSRicardo Garcia closeWaveFile(inFile);
39*b290403dSRicardo Garcia fprintf(stderr, "Unable to open wave file %s for writing\n", outFileName);
40*b290403dSRicardo Garcia exit(1);
41*b290403dSRicardo Garcia }
42*b290403dSRicardo Garcia sonicInit();
43*b290403dSRicardo Garcia sonicSetSpeed(speed);
44*b290403dSRicardo Garcia sonicSetVolume(volume);
45*b290403dSRicardo Garcia do {
46*b290403dSRicardo Garcia samplesRead = readFromWaveFile(inFile, inBuffer, SONIC_INPUT_SAMPLES);
47*b290403dSRicardo Garcia if (samplesRead == 0) {
48*b290403dSRicardo Garcia sonicFlushStream();
49*b290403dSRicardo Garcia } else {
50*b290403dSRicardo Garcia sonicWriteShortToStream(inBuffer, samplesRead);
51*b290403dSRicardo Garcia }
52*b290403dSRicardo Garcia do {
53*b290403dSRicardo Garcia samplesWritten = sonicReadShortFromStream(outBuffer, SONIC_INPUT_SAMPLES);
54*b290403dSRicardo Garcia if (samplesWritten > 0) {
55*b290403dSRicardo Garcia writeToWaveFile(outFile, outBuffer, samplesWritten);
56*b290403dSRicardo Garcia }
57*b290403dSRicardo Garcia } while (samplesWritten > 0);
58*b290403dSRicardo Garcia } while (samplesRead > 0);
59*b290403dSRicardo Garcia closeWaveFile(inFile);
60*b290403dSRicardo Garcia closeWaveFile(outFile);
61*b290403dSRicardo Garcia }
62*b290403dSRicardo Garcia
63*b290403dSRicardo Garcia /* Print the usage. */
usage(void)64*b290403dSRicardo Garcia static void usage(void) {
65*b290403dSRicardo Garcia fprintf(
66*b290403dSRicardo Garcia stderr,
67*b290403dSRicardo Garcia "Usage: sonic_lite [OPTION]... infile outfile\n"
68*b290403dSRicardo Garcia " -s speed -- Set speed up factor. 2.0 means 2X faster.\n"
69*b290403dSRicardo Garcia " -v volume -- Scale volume by a constant factor.\n");
70*b290403dSRicardo Garcia exit(1);
71*b290403dSRicardo Garcia }
72*b290403dSRicardo Garcia
main(int argc,char ** argv)73*b290403dSRicardo Garcia int main(int argc, char** argv) {
74*b290403dSRicardo Garcia char* inFileName;
75*b290403dSRicardo Garcia char* outFileName;
76*b290403dSRicardo Garcia float speed = 1.0f;
77*b290403dSRicardo Garcia float volume = 1.0f;
78*b290403dSRicardo Garcia int xArg = 1;
79*b290403dSRicardo Garcia
80*b290403dSRicardo Garcia while (xArg < argc && *(argv[xArg]) == '-') {
81*b290403dSRicardo Garcia if (!strcmp(argv[xArg], "-s")) {
82*b290403dSRicardo Garcia xArg++;
83*b290403dSRicardo Garcia if (xArg < argc) {
84*b290403dSRicardo Garcia speed = atof(argv[xArg]);
85*b290403dSRicardo Garcia printf("Setting speed to %0.2fX\n", speed);
86*b290403dSRicardo Garcia }
87*b290403dSRicardo Garcia } else if (!strcmp(argv[xArg], "-v")) {
88*b290403dSRicardo Garcia xArg++;
89*b290403dSRicardo Garcia if (xArg < argc) {
90*b290403dSRicardo Garcia volume = atof(argv[xArg]);
91*b290403dSRicardo Garcia printf("Setting volume to %0.2f\n", volume);
92*b290403dSRicardo Garcia }
93*b290403dSRicardo Garcia }
94*b290403dSRicardo Garcia xArg++;
95*b290403dSRicardo Garcia }
96*b290403dSRicardo Garcia if (argc - xArg != 2) {
97*b290403dSRicardo Garcia usage();
98*b290403dSRicardo Garcia }
99*b290403dSRicardo Garcia inFileName = argv[xArg];
100*b290403dSRicardo Garcia outFileName = argv[xArg + 1];
101*b290403dSRicardo Garcia runSonic(inFileName, outFileName, speed, volume);
102*b290403dSRicardo Garcia return 0;
103*b290403dSRicardo Garcia }
104