//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Sun Mar 5 13:02:45 PST 2000
// Last Modified: Sun Mar 5 13:02:49 PST 2000
// Filename: ...sig/doc/examples/sig/sigfile/sndsplit/sndsplit.cpp
// Syntax: C++; sig
//
// Description: split a large file into several smaller versions.
//
#include "sigAudio.h"
#include <stdlib.h>
#ifndef OLDCPP
#include <iostream>
using namespace std;
#else
#include <iostream.h>
#endif
void checkOptions(Options& opts);
void example(void);
void usage(const char* command);
int segment = -1; // used with the -n option
///////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
Options options(argc, argv);
checkOptions(options);
int i;
// Elements
SoundFileOut *outsound;
SoundFileIn insound(options.getArg(1));
SoundHeader header(options.getArg(1));
int channels = header.getChannels();
int sampleCount = header.getSamples();
double srate = header.getSrate();
int filelength = 0;
// determine the sample length of each output sound file
if (options.getBoolean("duration")) {
filelength = (int)(options.getDouble("duration") * srate);
} else {
filelength = options.getInteger("samples");
}
double fileCount = (double) sampleCount / filelength;
char buffer[1024] = {0};
char nbuffer[1024] = {0};
char basename[1024] = {0};
char *extension = NULL;
strncpy(basename, options.getArg(1), 1000);
int length = strlen(basename);
for (i=0; i<length; i++) {
if (basename[length-i-1] == '.') {
basename[length-i-1] = '\0';
extension = &basename[length-i];
break;
}
}
if (extension == NULL) {
cout << "Error: invalid soundfile name: " << options.getArg(1) << endl;
exit(1);
}
Action action;
int k;
for (i=0; i<(int)fileCount; i++) {
strcpy(buffer, basename);
strcat(buffer, "-");
if (fileCount >= 10 && i < 10) {
strcat(buffer, "0");
}
if (fileCount >= 100 && i < 100) {
strcat(buffer, "0");
}
if (fileCount >= 1000 && i < 1000) {
strcat(buffer, "0");
}
sprintf(nbuffer, "%d", i);
strcat(buffer, nbuffer);
strcat(buffer, ".");
strcat(buffer, extension);
if (segment < 0 || segment == i) {
outsound = new SoundFileOut(buffer, header);
for (k=0; k<channels; k++) {
outsound->connect(insound, k, k);
}
if (!options.getBoolean("quiet")) {
cout << "writing file " << buffer << endl;
}
// copy the soundfile to the output soundfile
action.tick(*outsound, filelength);
delete outsound;
} else if (i < segment) {
action.tick(insound, filelength);
} else {
break;
}
}
int leftover = sampleCount - (int)fileCount * (int)filelength;
if (segment < 0 && leftover > 0) {
strcpy(buffer, basename);
strcat(buffer, "-");
if (fileCount >= 10 && i < 10) {
strcat(buffer, "0");
}
if (fileCount >= 100 && i < 100) {
strcat(buffer, "0");
}
if (fileCount >= 1000 && i < 1000) {
strcat(buffer, "0");
}
sprintf(nbuffer, "%d", i);
strcat(buffer, nbuffer);
strcat(buffer, ".");
strcat(buffer, extension);
outsound = new SoundFileOut(buffer, header);
for (k=0; k<channels; k++) {
outsound->connect(insound, k, k);
}
if (!options.getBoolean("quiet")) {
cout << "writing file " << buffer << endl;
}
// copy the soundfile to the output soundfile
action.tick(*outsound, leftover);
delete outsound;
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
//////////////////////////////
//
// checkOptions -- handle command-line options.
//
void checkOptions(Options& opts) {
opts.define("d|dur|duration=d", "the duration of the segment");
opts.define("n|nth=i:0", "extract only the nth segment");
opts.define("s|samples=i:44100 samples", "the number of samples in each segment");
opts.define("o|overlap=d:0", "overlap of each segment (not implemented");
opts.define("q|quiet=b");
opts.define("author=b");
opts.define("version=b");
opts.define("example=b");
opts.define("help=b");
opts.process();
if (opts.getBoolean("author")) {
cout << "Written by Craig Stuart Sapp, "
<< "craig@ccrma.stanford.edu, 5 March 2000" << endl;
exit(0);
}
if (opts.getBoolean("version")) {
cout << "compiled: " << __DATE__ << endl;
cout << SIG_VERSION << endl;
exit(0);
}
if (opts.getBoolean("help")) {
usage(opts.getCommand());
exit(0);
}
if (opts.getBoolean("example")) {
example();
exit(0);
}
// must have exactly one sound filename
if (opts.getArgCount() != 1) {
cout << "Error: need exactly one input soundfile." << endl;
usage(opts.getCommand());
exit(1);
}
if (opts.getBoolean("nth")) {
segment = opts.getInteger("nth");
}
}
//////////////////////////////
//
// example -- gives example calls to the concatenate program.
//
void example(void) {
cout <<
" \n"
"# sndsplit examples: \n"
"# Splits a soundfile into one second pieces \n"
" sndsplit -d 1 test.wav \n"
<< endl;
}
//////////////////////////////
//
// usage -- how to run the sndsplit program on the command line.
//
void usage(const char* command) {
cout <<
" \n"
"Splits the given soundfile into smaller files. The output file format \n"
"is identical to the given input sound. \n"
" \n"
"Usage: " << command << " [-d duration][-s samples] insound\n"
" \n"
"Options: \n"
" -s = length of the output soundfiles specified in samples \n"
" -d = the time in seconds of output files. Overrides the -s option. \n"
" -q = quiet mode. Do not display message as each soundfile is written.\n"
" --options = list of all options, aliases and defaults \n"
" \n"
" \n"
<< endl;
}
// md5sum: ba553af34dddc95d7081eab29e318c5e sndsplit.cpp [20050403]