// // Programmer: Craig Stuart Sapp // 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 #include #include #ifndef OLDCPP #include using namespace std; #else #include #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\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]