**
** Copyright (c) 2003 Kevin Rosenberg
**
-** NOTES
-** Quick & Dirty hack, but efficient and good error checking
-** Allocates memory equal to the size of channel (2 * number of samples)
-**
-** BUGS
-** Need command line options for verbose and debug output
-** Should comment the reading and writing of files to document the file formats
-**
-** $Id: wdq2wav.cpp,v 1.7 2003/01/21 04:19:44 kevin Exp $
+** $Id: wdq2wav.cpp,v 1.8 2003/01/21 07:37:13 kevin Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License (version 2) as
#include <wdq2wav.h>
-static bool g_verbose = true;
+enum { O_VERBOSE, O_QUIET, O_DEBUG, O_HELP, O_VERSION };
+
+static struct option my_options[] =
+{
+ {"verbose", 0, 0, O_VERBOSE},
+ {"quiet", 0, 0, O_QUIET},
+ {"debug", 0, 0, O_DEBUG},
+ {"help", 0, 0, O_HELP},
+ {"version", 0, 0, O_VERSION},
+ {0, 0, 0, 0}
+};
+
+static const char* g_szIdStr = "$Id: wdq2wav.cpp,v 1.8 2003/01/21 07:37:13 kevin Exp $";
+
+static bool g_quiet = false;
+static bool g_verbose = false;
static bool g_debug = false;
+#define MAX_INPUT_STR 256
+
void
error_msg (const char *msg)
{
- fprintf (stderr, "%s\n",msg);
+ std::cerr << msg << "\n";
}
void
info_msg (const char* msg)
{
- fprintf (stdout, "%s\n", msg);
+ std::cout << msg << "\n";
}
void
info_msg_sans_newline (const char* msg)
{
- fprintf (stdout, "%s", msg);
+ std::cout << msg;
}
+const char*
+fileBasename (const char* filename)
+{
+ const char* p = strrchr (filename, '/');
+ return (p ? p + 1 : filename);
+}
+
+char *
+str_rm_tail (char *str, const char* const charlist)
+{
+ int i;
+
+ for (i = strlen(str) - 1; i >= 0; i--)
+ if (strchr (charlist, str[i]) != NULL)
+ str[i] = 0;
+ else
+ break; /* found non-specified char, all done */
+
+ return (str);
+}
+
+char *
+str_wrm_tail (char *str)
+{
+ return (str_rm_tail(str, "\b\t\n\r"));
+}
+
+
void
-usage ()
+usage (const char* progname)
{
- error_msg ("usage: wdq2wav <wdq-file> <channel-number> <wav-file>");
+ std::cout << "usage: " << fileBasename (progname) << " <wdq-file> <channel-number> <wav-file>\n";
+ std::cout << " --quiet Supress all messages\n";
+ std::cout << " --verbose Verbose mode\n";
+ std::cout << " --debug Debug mode\n";
+ std::cout << " --version Print version\n";
+ std::cout << " --help Print this help message\n";
}
bool wdq2wav (const char* wdq_fname, const int channel, const char *wav_fname);
int
main (int argc, char *argv[])
{
- if (argc != 4) {
- usage();
- exit(1);
- }
-
- char *wdq_fname = argv[1];
- char *channel_endptr;
- int channel = (int) strtol (argv[2], &channel_endptr, 10);
- char *wav_fname = argv[3];
+ while (1) {
+ int c = getopt_long (argc, argv, "", my_options, NULL);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case O_VERSION:
+ std::cout << "Version " << g_szIdStr << std::endl;
+ break;
+ case O_QUIET:
+ g_quiet = true;
+ break;
+ case O_VERBOSE:
+ g_verbose = true;
+ break;
+ case O_DEBUG:
+ g_debug = true;
+ break;
+ case O_HELP:
+ case '?':
+ usage(argv[0]);
+ return (0);
+ default:
+ usage(argv[0]);
+ return (1);
+ }
+ }
+
+ if (optind + 3 < argc) {
+ std::cerr << "Too many parameters\n";
+ usage (argv[0]);
+ return (1);
+ }
- if (*channel_endptr != 0) {
- std::ostringstream os;
- os << "Error: Channel " << argv[2] << " is not an integer";
- error_msg (os.str().c_str());
- usage();
- return(1);
- }
+ char wdq_fname[MAX_INPUT_STR];
+ if (optind < argc)
+ strncpy (wdq_fname, argv [optind], MAX_INPUT_STR);
+ else {
+ std::cout << "Enter input WinDAQ filename: ";
+ std::cin.getline (wdq_fname, MAX_INPUT_STR);
+ }
- if (! wdq2wav (wdq_fname, channel, wav_fname))
- return 1;
+ char channel_buf [MAX_INPUT_STR];
+ if (optind + 1 < argc)
+ strncpy (channel_buf, argv[optind+1], MAX_INPUT_STR);
+ else {
+ std::cout << "Enter channel number: ";
+ std::cin.getline (channel_buf, MAX_INPUT_STR);
+ }
+
+ char *channel_endptr;
+ int channel = static_cast<int>(strtol (channel_buf, &channel_endptr, 10));
+ if (*channel_endptr != 0) {
+ std::ostringstream os;
+ os << "Error: Channel " << channel_buf << " is not an integer";
+ error_msg (os.str().c_str());
+ usage (argv[0]);
+ return (1);
+ }
- return 0;
+ char wav_fname[MAX_INPUT_STR];
+ if (optind + 2 < argc)
+ strncpy (wav_fname, argv[optind+2], MAX_INPUT_STR);
+ else {
+ std::cout << "Enter output wav filename: ";
+ std::cin.getline (wav_fname, MAX_INPUT_STR);
+ }
+
+ if (! wdq2wav (wdq_fname, channel, wav_fname))
+ return 1;
+
+ return 0;
}
bool
WindaqFile wdq (wdq_fname);
if (! wdq.ReadHeader()) {
+ if (wdq.m_error.size()) {
+ std::ostringstream os;
+ os << "Error reading file " << wdq_fname << ": " << wdq.m_error.c_str();
+ error_msg (os.str().c_str());
+ } else {
+ std::ostringstream os;
+ os << "Error reading file " << wdq_fname;
+ error_msg (os.str().c_str());
+ }
return false;
}
- if (g_verbose) {
+ if (! g_quiet || g_verbose || g_debug) {
std::ostringstream os1;
os1 << "File " << wdq_fname;
info_msg (os1.str().c_str());
return false;
}
- if (g_verbose) {
+ if (! g_quiet || g_verbose || g_debug) {
std::ostringstream os1;
os1 << "Channel " << channel;
info_msg (os1.str().c_str());
os3 << " Raw minimum: " << wdq_channel.m_min_raw_data <<
", maximum: " << wdq_channel.m_max_raw_data;
info_msg (os3.str().c_str());
+ }
+ if (g_debug) {
std::ostringstream os4;
os4 << " Scaled minimum: " << wdq_channel.m_min_scaled_data <<
", maximum: " << wdq_channel.m_max_scaled_data;
unsigned int tmp4;
m_valid = false;
- if ((m_fd = open (m_strFile.c_str(), O_RDONLY)) == 0)
+ if ((m_fd = open (m_strFile.c_str(), O_RDONLY)) == 0) {
+ m_error = "Unable to open file";
return false;
+ }
lseek (0, 0, SEEK_SET);
if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) {
- error_msg ("Error reading file");
+ m_error = "Unable to read beginning of file";
return false;
}
m_nChannels = tmp2 & 0x1f;
m_sr_denom = (tmp2 & 0x7fff) >> 5;
m_sr_numer = (tmp2 & 0x8000) << 1;
- if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2))
return false;
- }
+
m_sr_numer |= tmp2;
m_sample_rate = (double) m_sr_numer / (double) (m_sr_denom * m_nChannels);
- if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2))
return false;
- }
+
m_channel_offset = tmp2 & 0xFF;
m_nBytes_channel_header = tmp2 >> 8;
- if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2))
return false;
- }
+
m_nHeader_bytes = tmp2;
- if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4))
return false;
- }
+
m_nData_bytes = tmp4;
m_nSamples = (m_nData_bytes / m_nChannels) / 2;
lseek (m_fd, 36, SEEK_SET);
- if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4))
return false;
- }
+
m_time_acq_start = tmp4;
- if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4))
return false;
- }
+
m_time_acq_stop = tmp4;
// Verify Windaq signature
lseek (m_fd, m_nHeader_bytes - 2, SEEK_SET);
- if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) {
- error_msg ("Error reading file");
+ if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2))
return false;
- }
+
if (tmp2 != 0x8001) {
std::ostringstream os;
- os << m_strFile << " is not a WinDAQ file";
- error_msg (os.str().c_str());
+ m_error = "File is not a valid WinDAQ file";
return false;
}
data_scale = 65535. / (wdq_channel.m_max_scaled_data -
wdq_channel.m_min_scaled_data);
- if (g_debug)
- printf ("data_scale: %f, data_offset: %f\n", data_scale, data_offset);
+ if (g_debug) {
+ std::ostringstream os;
+ os << " Wav data_scale: " << data_scale << ", data_offset: " << data_offset;
+ info_msg (os.str().c_str());
+ }
signed short int* input = wdq_channel.m_data;
double slope = wdq_channel.m_slope;