Goto: [ Program Documentation ]
// // Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu> // Creation Date: Tue May 14 20:21:29 PDT 1996 // Last Modified: Sat Apr 4 16:47:49 GMT-0800 1998 // Filename: ...sig/doc/examples/sig/sigfile/sndbit/sndbit.cpp // Syntax: C++; sig // // Description: With this program you can mask bits in a 16-bit/sample // soundfile, and you can also reorder the bits in the output sound file. // // To pass a bit to the output soundfile specify a '1' in the desired bit // location of the -m option. To stop a bit from being passed to the output // soundfile, specify a '0'. For example, to pass the 4 most significant // bits of the sound samples, the following command would be used: // sndbit -m1111000000000000 in.snd out.snd // // To verify that the ordering option is done properly, put the bits in // a random order, and then reverse the process: // sndbit -o0123456789abcdef in.snd out.snd # reverses bits // sndbit -o0123456789abcdef out.snd in2.snd # reverses bits again // Now in.snd and in2.snd should be the same. // // Bits can be repeated multiple times in the output ordering. For example, // the following command will generate a sequence of 0's and -1's according // to the value of the most-significant bit of the input sound samples: // sndbit -m1000000000000000 -offffffffffffffff in.snd out.snd // #include "Options.h" #include "sigAudio.h" #include <string.h> #include <stdio.h> #include <ctype.h> #ifndef OLDCPP #include <iostream> using namespace std; #else #include <iostream.h> #endif // function declarations: void checkOptions(Options& opts); void example(void); void exitUsage(const char* command); void help(void); ushort makeBitMask(const char*); ushort mixbits(const int* mixingString, const char* maskingString, ushort sample); void printbinaryshort(ushort); // global variables: Options options; // for handling program input arguments //////////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { if (argc == 1) { exitUsage(argv[0]); } options.define("m|mask=s:1111111111111111"); options.define("o|order=s"); options.define("h|help=b"); options.define("author=b"); options.define("version=b"); options.define("example=b"); options.define("usage=b"); options.process(argc, argv); checkOptions(options); SoundFileIn insound(options.getArgument(1)); if (insound.getBitsPerSample() != 16) { cout << "Error: This program can only process 16-bit samples." << endl; cout << " sample size in input soundfile is " << insound.getBitsPerSample() << "." << endl; exit(1); } SoundFileOut outsound(options.getArgument(2), insound.getHeader()); const char* patternMaskStr = options.getString("mask"); const char* patternOrderStr = options.getString("order"); ushort twoByteMask; // for filtering bits from sound samples twoByteMask = makeBitMask(patternMaskStr); int orderingArray[16]; if (strlen(patternOrderStr) != 0) { for (int i=0; i<16; i++) { if (isalpha(patternOrderStr[i])) { orderingArray[i] = tolower(patternOrderStr[i]) -'a' + 10; if (orderingArray[i] >= 16) { cout << "Error: invalid letter in ordering string.\n"; exitUsage(options.getCommand()); } } else if (isdigit(patternOrderStr[i])) { orderingArray[i] = patternOrderStr[i] -'0'; } else { cout << "Error: invalid character in ordering string.\n"; exitUsage(options.getCommand()); } } } int sampleCount; // total number of sound samples in input/output sampleCount = insound.getSamples() * insound.getChannels(); ushort currentSample; // current sample to process if (strlen(patternOrderStr) == 0) { // not moving bits around for (int i=0; i<sampleCount; i++) { currentSample = insound.extractSample16Bit(); currentSample &= twoByteMask; outsound.insertSample16Bit(currentSample); } } else { // moving bits for (int i=0; i<sampleCount; i++) { currentSample = insound.extractSample16Bit(); currentSample &= twoByteMask; outsound.insertSample16Bit(mixbits(orderingArray, patternMaskStr, currentSample)); } } return 0; } //////////////////////////////////////////////////////////////////////////////// ////////////////////////////// // // checkOptions -- make sure that all program options are ok. // void checkOptions(Options& opts) { if (opts.getBoolean("help")) { help(); exit(1); } if (opts.getBoolean("usage")) { exitUsage(opts.getCommand()); } if (opts.getBoolean("example")) { example(); exit(1); } if (opts.getBoolean("author")) { cout << "Written by Craig Stuart Sapp, " << "craig@ccrma.stanford.edu, May 1996" << endl; exit(1); } if (opts.getBoolean("version")) { cout << "sndbit version: Tue Apr 7 20:29:29 PDT 1998." << endl; cout << SIG_VERSION << endl; exit(1); } if (opts.getArgCount() != 2) { cout << "Error: must specify input and output soundfiles." << endl; exitUsage(opts.getCommand()); } if (strlen(opts.getString("mask")) != 16) { cout << "Error: must specify 16 bits in masking pattern.\n"; exitUsage(opts.getCommand()); } const char *orderString = opts.getString("order"); if (!(strlen(orderString) == 16 || strlen(orderString) == 0)) { cout << "Error: must specify 16 bits in ordering pattern.\n"; cout << " Length is " << strlen(orderString) << endl; exitUsage(opts.getCommand()); } } ////////////////////////////// // // example // void example(void) { cout << "# sndbit example: \n" "# Here is an example which will quantize a soundfile to \n" "# 16 loudness levels: \n" " osc \"0 0 1 440\" \"0 0 1 1 2 0\" -d 2 infile.snd \n" " sndbit -m 1111000000000000 infile.snd outfile.snd \n" "# \n" "# Here are the least significant bits amplified: \n" " sndbit -m 0000000000001111 -o3210ffffffffffff \\ \n" " infile.snd outfile.snd \n" << endl; } ////////////////////////////// // // exitUsage // void exitUsage(const char* command) { cout << "\nUsage: " << command << " [-m maskingBitPattern][-o orderingBitPattern] inFile outFile\n"; cout << " Removes bits/reorders bits in a soundfile.\n" << " The default options will not change the input.\n"; cout << " Options are:\n"; cout << " -m maskingBitPattern = 0 removes a bit, 1 keeps a bit.\n"; cout << " Default is 1111111111111111\n"; cout << " -o orderingBitPattern = Default is fedcba9876543210\n"; cout << " -h for further help.\n"; cout << endl; exit(1); } ////////////////////////////// // // help // void help(void) { cout << "Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>\n" "Creation Date: Tue May 14 20:21:29 PDT 1996\n" "Last Modified: Sat Apr 4 18:16:15 GMT-0800 1998 \n" "\n" "Description: With this program you can mask bits in a 16-bit/sample\n" "soundfile, and you can also reorder the bits in the output sound file.\n" "\n" "To pass a bit to the output soundfile specify a '1' in the desired bit\n" "location of the -m option. To stop a bit from being passed to the output \n" "soundfile, specify a '0'. For example, to pass the 4 most significant \n" "bits of the sound samples, the following command would be used:\n" "sndbit -m1111000000000000 in.snd out.snd\n" "\n" "To verify that the ordering option is done properly, put the bits in \n" "a random order, and then reverse the process:\n" " sndbit -ofedcba9786543210 in.snd out.snd\n" " sndbit -ofedcba9786543210 out.snd in2.snd\n" "Now in.snd and in2.snd should be the same.\n" "\n" "Bits can be repeated multiple times in the output ordering. For example,\n" "the following command will generate a sequence of 0's and -1's according\n" "to the value of the most-significant bit of the input sound samples:\n" " sndbit -m1000000000000000 -offffffffffffffff in.snd out.snd\n" << endl; } ////////////////////////////// // // makeBitMask // ushort makeBitMask(const char* str) { int i; int length; ushort value = 0; length = strlen(str); for (i=0; i<16; i++) { if (str[i] == '1') value = (value << 1) | 0x0001; else if (str[i] == '0') value = value << 1; else { fprintf(stderr, "Invalid masking pattern character: %c.", str[i]); fprintf(stderr, " Must be a '1' or a '0'.\n"); } } return value; } ////////////////////////////// // // mixbits // ushort mixbits(const int* mixingString, const char* maskingString, ushort sample) { int origPos, newPos, move; ushort origBit, newBit; ushort value = 0; int i; for (i=0; i<16; i++) { origPos = mixingString[i]; if (maskingString[15 - origPos] == '0') continue; origBit = (sample & (0x0001 << origPos)); newPos = 15 - i; move = newPos - origPos; newBit = (move >= 0) ? (origBit << move) : (origBit >> -move); value = value | newBit; } return value; } /////////////////////////////// // // printbinaryshort -- useful, but not used anymore. // void printbinaryshort(ushort input) { int i; for (i=15; i>=0; i--) { if ((input & (0x0001 << i)) == 0) printf("0"); else printf("1"); } printf("\n"); } // md5sum: 718b226a74c0b0f6818bdb2eb6a62a13 sndbit.cpp [20050403]