# include // getopt # include // u_int16_t, u_int32_t # include "qfile.hh" # include "qwavheader.hh" # include "qexception.hh" # include "endian.hh" /* caved in and used C's printf in a few places that don't seem to * be expressible with ios */ #include #include #ifdef NLS # include # include # define _(s) gettext (s) #else # define _(s) (s) #endif // see qwavheader.hh for more info about the wav header struct struct header { char riff[4]; u_int32_t rifflength; char wave[4]; char fmt_[4]; u_int32_t fmtlength; u_int16_t format; u_int16_t channels; u_int32_t samplerate; u_int32_t bytespersec; u_int16_t bytespersample; u_int16_t bitspersample; char data[4]; u_int32_t datalength; } __attribute__((packed)); const unsigned int HEADERSIZE = sizeof(struct header); void usage () { fprintf(stderr,_(" %s: dump (and fix) wav header\n"),APPNAME); fprintf(stderr,_(" syntax: %s [option]... file...\n"),APPNAME); cerr << _(" -F, --fix: correct header. use with care\n"); cerr << _(" -h, --help: show this help and exit\n"); cerr << _(" -q, --quiet: no output messages\n"); cerr << _(" -V, --version: show version and exit\n"); } int main (int argc, char **argv) { int option; bool quiet=false, fix=false; static struct option long_options[] = { {"fix",no_argument,0,'F'}, {"help",no_argument,0,'h'}, {"quiet",no_argument,0,'q'}, {"version",no_argument,0,'V'}, {0,0,0,0} }; #ifdef NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif // un altre dia, per defecte llegir *.wav ... if (argc==1) { usage(); return 1; } // supress getopt error message opterr = 0; while ((option = getopt_long(argc, argv, "FhqV",long_options,0)) != EOF) switch (option) { case 'F': fix=true; break; case 'h': usage(); return 0; break; case 'q': quiet=true; break; case 'V': cerr << APPNAME << " - " << _("version") << ' ' << VERSION << _("build") << ' ' << __DATE__ << '\n'; return 0; break; case '?': default: cerr << APPNAME << ": " << _("option") << " '" << argv[optind-1] << "' " << _("is not recognized or bad used") << '\n'; usage(); return 1; } if (argc<=optind) { // haurķem de fer *.wav ... cerr << APPNAME << _(": no input file(s)") << endl; usage(); return 1; } u_int32_t openmode = fix?qfile::READWRITE:qfile::READ; while (argv[optind]) { try { qfile f(argv[optind],openmode); if (f.getSize()riff); if (strncmp(header->riff,"RIFF",4)) { if (!quiet) fprintf(stderr,_("\t\triff field should be 'RIFF'\n")); if (fix) { strncpy(header->riff,"RIFF",4); if (!quiet) cerr << _("\t\tfixed\n"); } } printf(_("\triff length: %d\n"),letohl(header->rifflength)); if (letohl(header->rifflength)!=f.getSize()-8) { if (!quiet) fprintf(stderr,_("\t\triff length field should be %d\n"),f.getSize()-8); if (fix) { header->rifflength = htolel(f.getSize()-8); if (!quiet) cerr << _("\t\tfixed\n"); } } printf("\twave: '%.4s'\n",header->wave); if (strncmp(header->wave,"WAVE",4)) { if (!quiet) fprintf(stderr,_("\t\twave field should be 'WAVE'\n")); if (fix) { strncpy(header->wave,"WAVE",4); if (!quiet) cerr << _("\t\tfixed\n"); } } printf("\tfmt: '%.4s'\n",header->fmt_); if (strncmp(header->fmt_,"fmt ",4)) { if (!quiet) fprintf(stderr,_("\t\tfmt field should be 'fmt '\n")); if (fix) { strncpy(header->fmt_,"fmt ",4); if (!quiet) cerr << _("\t\tfixed\n"); } } printf(_("\tfmt length: %d\n"),letohl(header->fmtlength)); if (letohl(header->fmtlength)!=16) { if (!quiet) fprintf(stderr,_("\t\tfmt length field should be %d\n"),16); if (fix) { header->fmtlength = htolel(16); if (!quiet) cerr << _("\t\tfixed\n"); } } printf("\tformat: %d\n",letohs(header->format)); if (letohs(header->format)!=1) { if (!quiet) fprintf(stderr,_("\t\tformat field should 1 (pcm tag)\n")); if (fix) { header->format = htoles(1); if (!quiet) cerr << _("\t\tfixed\n"); } } printf(_("\tchannels: %d\n"),letohs(header->channels)); if (letohs(header->channels)!=2 && letohs(header->channels)!=1) { if (!quiet) fprintf(stderr,_("\t\tchannels field should be 1 (mono) or 2 (stereo)\n")); if (fix) { cerr << _("\t\tdon't know which value must be set...\n") << endl; if (!quiet) cerr << _("\t\tfixed\n"); } } printf(_("\tsample rate: %d\n"),letohl(header->samplerate)); if (letohl(header->samplerate)>48000 || letohl(header->samplerate)<8000) { if (!quiet) fprintf(stderr,_("\t\tsample rate field should be between 8000 and 48000\n")); if (fix) cerr << _("\t\tdon't know which value must be set...\n") << endl; } printf(_("\tbytes/second: %d\n"),letohl(header->bytespersec)); printf(_("\tbytes/sample: %d\n"),letohs(header->bytespersample)); if (letohs(header->bytespersample)!=1 && letohs(header->bytespersample)!=2 && letohs(header->bytespersample)!=4) { if (!quiet) fprintf(stderr,_("\t\t bytes/sample field should be 1, 2 or 4\n")); if (fix) cerr << _("\t\tdon't know which value must be set...\n") << endl; } printf(_("\tbits/sample: %d\n"),letohs(header->bitspersample)); printf("\tdata: '%.4s'\n",header->data); if (strncmp(header->data,"data",4)) { if (!quiet) fprintf(stderr,_("\t\tdata field should be 'data'\n")); if (fix) { strncpy(header->data,"data",4); if (!quiet) cerr << _("\t\tfixed\n"); } } printf(_("\tdata length: %d\n"),letohl(header->datalength)); if (letohl(header->datalength)!=f.getSize()-44) { if (!quiet) fprintf(stderr,_("\t\tdata length field should be %d\n"),f.getSize()-44); if (fix) { header->datalength = htolel(f.getSize()-44); if (!quiet) cerr << _("\t\tfixed\n"); } } } catch (qexception e) { cerr << argv[optind] << ": " << e << endl; } optind++; } }