|
Resident Grouch
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 
|
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.
|