Nick said:
I need to know how to input bits from a *.wav file.
I have tried this:
#include <fstream>
...
ifstream fin;
fin.open("/root/foofile.wav", ios::in|ios::binary);
and then inputting individual bits as a bool, and then joining them as an
int (which represents one 8 bit byte) like this (I don't care about leading
zeroes):tin
int byte=0;
bool bit;
for(int i=0; i<8; i++)
{
bit=fin.get();
if(bit)
byte*=10;
byte++;
}tin
Is "tin" a typo?
but somehow, it's not working. Can anyone find some error in the way I'm
inputting my bits, opening my file, etc?
I am running Slackware Linux, and I use gcc(++) to compile stuff.
Why are you representing a byte with an int? Because bytes are such
fundamental units, they have their own type, misleadingly named "char".
The name is because characters generally are represented by integers,
through a mapping called a "character set." Similarly, "fin.get( )"
will *not* return a boolean 1 or 0, as you might expect; instead, it
will return the integer that represents the corresponding character in
your local character set. You can represent such values intuitively
with single quotes, as in '1' and '0'.
I notice you are multiplying by ten. That's how base-ten numerals are
left-shifted. You aren't reading base ten, are you? You're reading
base two. Because this happens to be the base on which most computers
are built, and because left-shifting is such a common operation, this
task has its very own operator in C++. It looks just like the insertion
operator "<<" you may have seen used with output streams.
Also, what purpose does "bit" serve? Is it just to hold a value between
one line and the next? Lots of people do that when they think it makes
the code clearer, but I don't think it does here. However, may I
suggest you at least move the definition of "bit" down to the point of
initialization? A similar recommendation applies to the opening of the
fstream; why didn't you initialize it properly, rather than calling
"fin.open" manually on the next line? Either way, you don't have to
specify ios::in; it is implied by the fact that you are constructing an
"ifstream", not just an "fstream".
By the way, are you running this program as root? You probably don't
want to do that. However, if you try running this program as a normal
user, it may not be able to read the file from root's home directory.
Here's what I think you want. This is a very naive implementation,
since it does not check for erros in the input stream. For example, if
the file cannot be read, or if the input contains a '2' instead of a '1'
or a '0', this program will not notice.
#include <iostream>
struct Byte
{
typedef unsigned char Value;
Value value;
operator unsigned char const ( ) const { return value; }
};
std:
stream&
operator << ( std:
stream& out, Byte const& b )
{
Byte::Value value = b.value;
int i = std::numeric_limits< Byte::Value >::digits;
while( --i >= 0 )
{
out << ( ( b.value & ( 1 << i ) ) ? '1' : '0' );
}
return out;
}
std::istream&
operator >> ( std::istream& in, Byte& b )
{
Byte::Value value = ( in.get( ) == '1' );
int i = std::numeric_limits< Byte::Value >::digits;
while( --i )
{
value = ( value << 1 ) | ( in.get( ) == '1' );
}
b.value = value;
return in;
}
#include <fstream>
int main( int argc, char** argv )
{
Byte byte;
while( *++argv )
{
std::ifstream fin( *argv, std::ios::binary );
fin >> byte;
std::cout << byte << '\n';
}
}