From: Kevin M. Rosenberg Date: Tue, 21 Jan 2003 11:23:09 +0000 (+0000) Subject: r3832: *** empty log message *** X-Git-Tag: v0.8.1~45 X-Git-Url: http://git.kpe.io/?p=wdq2wav.git;a=commitdiff_plain;h=8eec8116b49d2838727bd77a75308c6a65aaf2e7 r3832: *** empty log message *** --- diff --git a/wdq2wav.cpp b/wdq2wav.cpp index 5c18169..e307f00 100644 --- a/wdq2wav.cpp +++ b/wdq2wav.cpp @@ -8,7 +8,7 @@ ** ** Copyright (c) 2003 Kevin Rosenberg ** -** $Id: wdq2wav.cpp,v 1.9 2003/01/21 09:38:59 kevin Exp $ +** $Id: wdq2wav.cpp,v 1.10 2003/01/21 11:23:09 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 @@ -26,23 +26,11 @@ #include -enum { O_VERBOSE, O_QUIET, O_DEBUG, O_HELP, O_VERSION }; +const char* g_szIdStr = "$Id: wdq2wav.cpp,v 1.10 2003/01/21 11:23:09 kevin Exp $"; -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.9 2003/01/21 09:38:59 kevin Exp $"; - -static bool g_quiet = false; -static bool g_verbose = false; -static bool g_debug = false; +bool g_quiet = false; +bool g_verbose = false; +bool g_debug = false; void error_msg (const char *msg) @@ -93,63 +81,68 @@ str_wrm_tail (char *str) void usage (const char* progname) { - std::cout << "usage: " << fileBasename (progname) << " \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"; + std::cout << "usage: " << fileBasename (progname) << " [OPTIONS] \n"; + std::cout << "OPTIONS\n"; + std::cout << " -p Play channel through audio system\n"; + std::cout << " -q Supress all messages\n"; + std::cout << " -v Verbose mode\n"; + std::cout << " -d Debug mode\n"; + std::cout << " -r Print program version\n"; + std::cout << " -h Print this help message\n"; } int main (int argc, char *argv[]) { - while (1) { - int c = getopt_long (argc, argv, "", my_options, NULL); - if (c == -1) - break; - - switch (c) { - case O_VERSION: + int c; + bool play = false; + + while ((c = getopt (argc, argv, "rqvdph")) != -1) { + switch (c) { + case 'r': 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: + case 'q': + g_quiet = true; + break; + case 'v': + g_verbose = true; + break; + case 'd': + g_debug = true; + break; + case 'p': + play = true; + break; + case 'h': + usage (argv[0]); + return (0); + case '?': + default: usage(argv[0]); return (1); } } - - if (optind + 3 < argc) { + argc -= optind; + argv += optind; + if (argc > 3) { std::cerr << "Too many parameters\n"; usage (argv[0]); 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: "; + char wdq_fname[MAX_INPUT_STR]; + if (argc >= 1) + strncpy (wdq_fname, argv [1], MAX_INPUT_STR); + else { + std::cout << "Enter input WinDAQ filename: "; std::cin.getline (wdq_fname, MAX_INPUT_STR); } char channel_buf [MAX_INPUT_STR]; - if (optind + 1 < argc) - strncpy (channel_buf, argv[optind+1], MAX_INPUT_STR); + if (argc >= 2) + strncpy (channel_buf, argv[2], MAX_INPUT_STR); else { std::cout << "Enter channel number: "; std::cin.getline (channel_buf, MAX_INPUT_STR); @@ -166,8 +159,8 @@ main (int argc, char *argv[]) } char wav_fname[MAX_INPUT_STR]; - if (optind + 2 < argc) - strncpy (wav_fname, argv[optind+2], MAX_INPUT_STR); + if (argc >= 3) + strncpy (wav_fname, argv[3], MAX_INPUT_STR); else { std::cout << "Enter output wav filename: "; std::cin.getline (wav_fname, MAX_INPUT_STR); @@ -274,11 +267,34 @@ WindaqFile::~WindaqFile () close (m_fd); } +bool read_int2 (int fd, unsigned short int& n) +{ + unsigned char tmp1; + unsigned int tmp2; + if (read (fd, &tmp1, 1) != 1) + return false; + tmp2 = tmp1; + if (read (fd, &tmp1, 1) != 1) + return false; + n = tmp2 + (tmp1 * 256); +} + +bool read_int4 (int fd, unsigned int& n) +{ + unsigned int tmp4; + unsigned short int tmp2; + if (! read_int2 (fd, tmp2)) + return false; + tmp4 = tmp2; + if (! read_int2 (fd, tmp2)) + return false; + n = tmp4 + (tmp2 * 65536); +} + bool WindaqFile::ReadHeader () { unsigned short int tmp2; - unsigned int tmp4; m_valid = false; if ((m_fd = open (m_strFile.c_str(), O_RDONLY)) < 0) { @@ -287,49 +303,43 @@ WindaqFile::ReadHeader () } lseek (0, 0, SEEK_SET); - if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) { + if (! read_int2 (m_fd, tmp2)) 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)) + if (! read_int2 (m_fd, 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)) + if (! read_int2 (m_fd, tmp2)) return false; m_channel_offset = tmp2 & 0xFF; m_nBytes_channel_header = tmp2 >> 8; - if (read (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) + if (! read_int2 (m_fd, m_nHeader_bytes)) return false; - - m_nHeader_bytes = tmp2; - if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) + if (! read_int4 (m_fd, m_nData_bytes)) 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)) + if (! read_int4 (m_fd, m_time_acq_start)) return false; - m_time_acq_start = tmp4; - if (read (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) + if (! read_int4 (m_fd, m_time_acq_stop)) 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)) + if (! read_int2 (m_fd, tmp2)) return false; if (tmp2 != 0x8001) { @@ -366,6 +376,24 @@ WindaqChannel::~WindaqChannel () delete m_data; } +bool get_float8 (int fd, double& f) +{ + unsigned char buf[8]; + if (read (fd, &buf, 8) != 8) + return false; + +#ifdef BIG_ENDIAN + unsigned char c; + c = buf[0]; buf[0] = buf[7]; buf[7] = c; + c = buf[1]; buf[1] = buf[6]; buf[6] = c; + c = buf[2]; buf[2] = buf[5]; buf[5] = c; + c = buf[3]; buf[3] = buf[4]; buf[4] = c; +#endif + + double* p = reinterpret_cast(buf); + f = *p; +} + bool WindaqChannel::read_channel_data () { @@ -383,16 +411,11 @@ WindaqChannel::read_channel_data () lseek (fd, r_wdq.m_channel_offset + 8 + (m_channel - 1) * r_wdq.m_nBytes_channel_header, SEEK_SET); - if (read (fd, &float8, sizeof(float8)) != sizeof(float8)) { - error_msg ("Error reading file"); + if (! get_float8 (fd, m_slope)) return false; - } - m_slope = float8; - if (read (fd, &float8, sizeof(float8)) != sizeof(float8)) { - error_msg ("Error reading file"); + + if (get_float8 (fd, m_intercept)) return false; - } - m_intercept = float8; char units[7]; units[6] = 0; @@ -417,8 +440,14 @@ WindaqChannel::read_channel_data () error_msg (os.str().c_str()); return false; } - - signed short int value = *psample >> 2; + signed short int v = *psample; + +#ifdef BIG_ENDIAN + unsigned char* p = reinterpret_cast(&v); + unsigned char c = p[0]; p[0] = p[1]; p[1] = c; +#endif + + signed short int value = v >> 2; m_data[i] = value; if (i == 0) { @@ -450,7 +479,6 @@ WavFile::WavFile (WindaqChannel& wdq_channel, const char* fname) m_nBitsPerSample = 16; m_nBytesPerSample = 2; m_rate = wdq_channel.r_wdq.m_sample_rate; - m_data = new signed short int [m_nSamples]; double data_offset = -wdq_channel.m_min_scaled_data; double data_scale = 0.; @@ -464,17 +492,32 @@ WavFile::WavFile (WindaqChannel& wdq_channel, const char* fname) info_msg (os.str().c_str()); } + unsigned int nHeaderBytes = 44; + m_nFileBytes = nHeaderBytes + m_nSamples * m_nBytesPerSample; + + unsigned int nHeaderShortInts = nHeaderBytes / sizeof(signed short int); + + m_data = new signed short int [m_nSamples + nHeaderShortInts]; signed short int* input = wdq_channel.m_data; + signed short int* output = &m_data[nHeaderShortInts]; double slope = wdq_channel.m_slope; double intercept = wdq_channel.m_intercept; + if (! fill_header ()) + return; + long int i; for (i = 0; i < m_nSamples; i++) { double value = input[i]; value = (slope * value) + intercept; value = (value + data_offset) * data_scale; value += 0.5 - 32768; - m_data[i] = static_cast(value); + signed short int v = static_cast(value); +#ifdef BIG_ENDIAN + unsigned char* p = reinterpret_cast(&v); + unsigned char c = p[0]; p[0] = p[1]; p[1] = c; +#endif + output[i] = v; } } @@ -491,12 +534,68 @@ WavFile::~WavFile () delete m_data; } +void +put_int4 (char* p, unsigned int n) +{ + *p = n & 0xFF; + *(p+1) = 0xFF & (n >> 8); + *(p+2) = 0xFF & (n >> 16); + *(p+3) = 0xFF & (n >> 24); +} + +void +put_int2 (char* p, unsigned short int n) +{ + *p = n & 0xFF; + *(p+1) = 0xFF & (n >> 8); +} + +bool +WavFile::fill_header () +{ + char* pData = reinterpret_cast (m_data); + unsigned long data_bytes = m_nSamples * m_nBytesPerSample * m_nChannels; + + strncpy (pData, "RIFF", 4); + + // Length of file after 8 byte header + put_int4 (pData + 4, 36 + data_bytes); + + strncpy (pData + 8, "WAVEfmt ", 8); + + // Length of header block + put_int4 (pData + 16, 0x10); + + // Always 1 + put_int2 (pData + 20, 1); + + /* Number of channels */ + put_int2 (pData + 22, m_nChannels); + + // Sample Rate + put_int4 (pData + 24, static_cast (m_rate + 0.5)); + + // Bytes per second + put_int4 (pData + 28, static_cast (m_rate * m_nBytesPerSample + 0.5)); + + // Bytes per sample + put_int2 (pData + 32, m_nBytesPerSample * m_nChannels); + + // Bits per sample + put_int2 (pData + 34, m_nBitsPerSample); + + strncpy (pData + 36, "data", 4); + + put_int4 (pData + 40, data_bytes); + + return true; +} + bool WavFile::WriteFile () { unsigned short int tmp2; unsigned int tmp4; - unsigned long data_bytes = m_nSamples * 2; if (! m_valid) return false; @@ -511,82 +610,11 @@ WavFile::WriteFile () } lseek (m_fd, 0, SEEK_SET); - if (write (m_fd, "RIFF", 4) != 4) { - error_msg ("Error writing file"); - return false; - } - - /* Length of file post 8 byte header */ - tmp4 = 36 + data_bytes; - if (write (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) { - error_msg ("Error writing file"); - return false; - } - - if (write (m_fd, "WAVEfmt ", 8) != 8) { + if (write (m_fd, m_data, m_nFileBytes) != m_nFileBytes) { error_msg ("Error writing file"); return false; } - tmp4 = 0x10; - if (write (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) { - error_msg ("Error writing file"); - } - tmp2 = 1; - if (write (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) { - error_msg ("Error writing file"); - return false; - } - /* Number of channels */ - tmp2 = m_nChannels; - if (write (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) { - error_msg ("Error writing file"); - return false; - } - tmp4 = static_cast (m_rate + 0.5); - /* Sample rate */ - if (write (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) { - error_msg ("Error writing file"); - return false; - } - tmp4 = static_cast (m_rate * m_nBytesPerSample + 0.5); - /* Bytes per second */ - if (write (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) { - error_msg ("Error writing file"); - return false; - } - tmp2 = m_nBytesPerSample * m_nChannels; - /* Bytes per sample */ - if (write (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) { - error_msg ("Error writing file"); - return false; - } - tmp2 = m_nBitsPerSample; - /* Bits per sample */ - if (write (m_fd, &tmp2, sizeof(tmp2)) != sizeof(tmp2)) { - error_msg ("Error writing file"); - return false; - } - if (write (m_fd, "data", 4) != 4) { - error_msg ("Error writing file"); - return false; - } - tmp4 = data_bytes; - /* Data length */ - if (write (m_fd, &tmp4, sizeof(tmp4)) != sizeof(tmp4)) { - error_msg ("Error writing file"); - return false; - } - - long int i; - for (i = 0; i < m_nSamples; i++) { - signed short int stmp2 = m_data[i]; - if (write (m_fd, &stmp2, sizeof(stmp2)) != sizeof(stmp2)) { - error_msg ("Error writing file"); - return false; - } - } - if (close (m_fd) < 0) error_msg ("Error closing output file"); diff --git a/wdq2wav.h b/wdq2wav.h index 60b5dc5..0caab1e 100644 --- a/wdq2wav.h +++ b/wdq2wav.h @@ -8,7 +8,7 @@ ** ** Copyright (c) 2003 Kevin Rosenberg ** -** $Id: wdq2wav.h,v 1.6 2003/01/21 09:38:59 kevin Exp $ +** $Id: wdq2wav.h,v 1.7 2003/01/21 11:23:09 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 @@ -32,7 +32,8 @@ #include #include #include -#include +#include +#include extern const char* g_szIdStr; extern bool g_quiet; @@ -62,10 +63,10 @@ public: unsigned int m_nSamples; double m_sample_rate; unsigned int m_sr_denom, m_sr_numer; - unsigned int m_nHeader_bytes, m_channel_offset, m_nBytes_channel_header; + unsigned short int m_nHeader_bytes, m_channel_offset, m_nBytes_channel_header; unsigned int m_nData_bytes; - unsigned long int m_time_acq_start; - unsigned long int m_time_acq_stop; + unsigned int m_time_acq_start; + unsigned int m_time_acq_stop; }; class WindaqChannel @@ -103,9 +104,13 @@ class WavFile unsigned int m_nBitsPerSample; unsigned int m_nBytesPerSample; signed short int* m_data; + unsigned long int m_nFileBytes; WavFile (WindaqChannel& wdq_channel, const char* fname); ~WavFile (); bool WriteFile (); + + private: + bool fill_header(); };