hello / c++ / wave.cpp

#include <wave.h>

//#define B_ENDIAN
//$Id: wave.cpp 20 2006-10-24 09:02:48Z kuenishi $

#include <iostream>
#include <stdexcept>

using namespace std;

//wave::wave(){}
wave::wave(string str):filename(str), fin(str.c_str() ), verbose(false){
  if( bad() )throw exception();
  if( open_header() ) cout << str << " is ready." << endl;
}
wave::wave(char* str):filename(str), fin(str), verbose(false){
  if( bad() )throw exception();
  if( open_header() ) cout << str << " is ready." << endl;
}
wave::~wave(){
  fin.close();
}


vector<short> wave::read(unsigned int n) throw( exception &){
  if( n > 320000 ) n = 320000;

  vector<short> ret;
  ret.reserve(n);
  short s;

  ///TODO? juliusだとここでなんかヘンな読み込みしてる
  fin.read( (char*)(&s), bpb );
  for( int i = 0; i < n; i++){
    s = 0;
    if( ! fin.read( (char*)(&s), bpb ) )break;
    escape_endian(&s);
    ret.push_back(s);
  }
  return ret;
}


bool wave::good(){
  return (fin)?true:false;
}
bool wave::bad(){
  return !good();
}
bool wave::open_header() throw(exception&){
  //  void (*p_escape_endian)() = &wave::escape_endian;

  int sizeshort = sizeof( unsigned short );
  int sizeint   = sizeof( unsigned int ) ;
  //cout << "sizeof : " << sizeof( unsigned long long ) << endl;

#ifdef DEBUG
  verbose = true;
#endif
  if( sizeshort not_eq 2 or sizeint not_eq 4)
    throw exception();//"bit width ?");

  riff[4]=wavefmt[8] = data[4] = '\0';
  
  fin.read(riff, 4);
  if(verbose)
    cout << "RIFF: " <<  riff << endl;

  fin.read( (char*)(&fileSize), 4);
  escape_endian(&fileSize);
  if(verbose)
    cout << "SIZE: " << fileSize << endl;

  fin.read(wavefmt, 8);
  if(verbose)
    cout << "WAVEfmt : " << wavefmt << endl;

  fin.read((char*)(&headerSize), 4);
  escape_endian(&headerSize);
  if(verbose)
    cout << "length: " << headerSize << endl;

  fin.read( (char*)(&category), 2);
  escape_endian(&category);
  if(verbose)
    cout << "formatid: " << category << endl;
  if(category not_eq 1 )
    throw logic_error("bad format id");


  fin.read( (char*)(&channel), 2);
  escape_endian(&channel);
  if(verbose)
    cout << "channel: " << channel << endl;
  if(channel not_eq 1 )
    throw logic_error("bad channel");

  fin.read( (char*)(&rate), 4);
  escape_endian(&rate);
  if(verbose)
    cout << "sampling rate: " << rate << endl;

  fin.read( (char*)(&bps), 4);
  escape_endian(&bps);
  if(verbose)
    cout << "byte per sec: " << bps << endl;

  fin.read( (char*)(&bpb), 2);
  escape_endian(&bpb);
  if(verbose)
    cout << "byte per block: " << bpb << endl;
  if(bpb not_eq 2)
    throw logic_error("  ");

  fin.read( (char*)(&bit), 2);
  escape_endian(&bit);
  if(verbose)
    cout << "bits: " << bit << endl;
  
  data[4] = '\0';
  fin.read(data, 4);
  if(verbose)
    cout << string(data) << endl;
  return ( string( data ) == "data" );

}

inline
void wave::escape_endian(unsigned short* sh){
#ifdef B_ENDIAN
  int s = sizeof(unsigned short);
  char c[s*2];
  c[s*2]='\0';
  char ch;
  memcpy( c, sh, s );
  if(verbose)
    cout << *sh ;
  char* l = c;
  char* r = c + s*2 -1;
  while( r - l > 0){
    ch = *l;
    *l = *r;
    *r = ch;
    r--; l++;
  }
  memcpy( sh, c+s, s );
  if(verbose)
    cout << " -> " << *sh << endl;
#endif
}

inline
void wave::escape_endian(short* sh){
#ifdef B_ENDIAN
  int s = sizeof(unsigned short);
  char c[s*2];
  c[s*2]='\0';
  char ch;
  memcpy( c, sh, s );
  if(verbose)
    cout << *sh ;
  char* l = c;
  char* r = c + s*2 -1;
  while( r - l > 0){
    ch = *l;
    *l = *r;
    *r = ch;
    r--; l++;
  }
  memcpy( sh, c+s, s );
  if(verbose)
    cout << " -> " << *sh << endl;
#endif
}
inline
void wave::escape_endian(unsigned int* sh){
#ifdef B_ENDIAN
  int s = sizeof(unsigned int);
  char c[s*2];
  c[s*2]='\0';
  char ch;
  memcpy( c, sh, s );
  if(verbose)
    cout << *sh ;
  char* l = c;
  char* r = c + s*2 -1;
  while( r - l > 0){
    ch = *l;
    *l = *r;
    *r = ch;
    r--; l++;
  }
  memcpy( sh, c+s, s );
  if(verbose)
    cout << " -> " << *sh << endl;
#endif
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.