View Single Post
Old Aug 30th, 2005, 1:15 PM   #1
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Not Beethoven, but...

...I hadda do it: the sound of one .exe clapping.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <sys\stat.h>

using namespace std;

class formatChunk
{
public:
	string formatTag;			// "fmt "
	int formatSize;				// Size of chunk following this value
	short audioFormat;			// Two bytes here; value 1 for PCM
	short nChannels;			// Two bytes here, stereo here
	int sampleRate;				// 44100 here
	int byteRate;				// sampleRate * channels * bitsPerSample/8
	short bytesPerSample;		// channels * bitsPerSample/8, two bytes
	short bitsPerSample;		// Two bytes here
	formatChunk ()
	{
		formatTag = "fmt ";
		formatSize = 16;		// PCM default
		audioFormat = 1;		// PCM default
		nChannels = 2;			// Stereo default
		sampleRate = 44100;		// Default
		bitsPerSample = 16;		// Default
		bytesPerSample = nChannels * 
			bitsPerSample / 8;
		byteRate = bytesPerSample * 
			sampleRate;
	}
};
std::ostream& operator << (std::ostream& os, const formatChunk& chunk) 
{
	os << chunk.formatTag.c_str ();
	os.write ((const char *) &chunk.formatSize, 4);
	os.write ((const char *) &chunk.audioFormat, 2);
	os.write ((const char *) &chunk.nChannels, 2);
	os.write ((const char *) &chunk.sampleRate, 4);
	os.write ((const char *) &chunk.byteRate, 4);
	os.write ((const char *) &chunk.bitsPerSample, 2);
	os.write ((const char *) &chunk.bytesPerSample, 2);
	return os;
}
class dataChunk
{
public:
	string dataTag;				// "data"
	int dataSize;				// bytes following, which is 
	dataChunk ()
	{
		dataTag = "data";
	}
};

std::ostream& operator << (std::ostream& os, const dataChunk& chunk) 
{
	os << chunk.dataTag.c_str ();
	os.write ((const char *) &chunk.dataSize, 4);
	return os;
}

class waveHeader
{
public:
	string chunkID;
	int chunkSize;				// Size of file following this value
	string formatTag;			// Specific format
	formatChunk fmt;
	dataChunk sound;
	waveHeader ()
	{
		chunkID = "RIFF";
		formatTag = "WAVE";
	}

};
std::ostream& operator << (std::ostream& os, const waveHeader& header) 
{
	os << header.chunkID.c_str ();
	os.write ((const char *) &header.chunkSize, 4);
	os << header.formatTag.c_str ();
	os << header.fmt;
	os << header.sound;
	return os;
}

int uhOh (string trouble)
{
	cerr << trouble << endl;
	return 1;
}
int main (int argc, char *argv [])
{
	ifstream inFile; 
	ofstream outFile; 
	waveHeader wDesc;
	struct stat fileStats;
	string sourceFile = "C:\\windows\\explorer.bak";
	unsigned padding;
	char *pad = NULL;

	// Get the size of the file to treat as sound
	stat (sourceFile.c_str (), &fileStats);
	// Prepare to adjust to an integral number of samples, if necessary
	padding = fileStats.st_size % wDesc.fmt.bytesPerSample;
	if (padding) char *pad = new char (padding);

	// Fill in the appropriate members of the header
	wDesc.sound.dataSize = fileStats.st_size + padding;
	wDesc.chunkSize = wDesc.formatTag.size () + wDesc.fmt.formatTag.size () +
		wDesc.fmt.formatSize + sizeof (wDesc.fmt.formatSize) +
		wDesc.sound.dataTag.size () + 
		wDesc.sound.dataSize + sizeof (wDesc.sound.dataSize);
	
	// Open the source file and a destination .wav file
	inFile.open (sourceFile.c_str (), ios::in | ios::binary);
	outFile.open ("explorer.wav", ios::out | ios::binary);
	if (!inFile.good () || !outFile.good ()) return uhOh ("File(s) didn't open");

	// Write out the header
	outFile << wDesc;
	// Tack on the "sound"
	outFile << inFile.rdbuf ();
	// Tack on padding, if necessary
	if (padding) outFile << pad;

	// Close the files
	inFile.close ();
	outFile.close ();

	// Play the sound
	system ("explorer.wav");

	return 0;
}
I apologize for the tab expansion -- something's gone kerplookety with my editor and it isn't subbing in 4 spaces per tab.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote