commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r7730 - in gnuradio/trunk: gnuradio-core/src/lib/io gn


From: jcorgan
Subject: [Commit-gnuradio] r7730 - in gnuradio/trunk: gnuradio-core/src/lib/io gnuradio-core/src/python/gnuradio/gr gnuradio-examples/python/audio
Date: Sun, 17 Feb 2008 23:27:50 -0700 (MST)

Author: jcorgan
Date: 2008-02-17 23:27:50 -0700 (Sun, 17 Feb 2008)
New Revision: 7730

Added:
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.cc
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.h
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.i
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.cc
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.h
   gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.i
   gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.cc
   gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.h
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav
   gnuradio/trunk/gnuradio-examples/python/audio/dial_tone_wav.py
Modified:
   gnuradio/trunk/gnuradio-core/src/lib/io/Makefile.am
   gnuradio/trunk/gnuradio-core/src/lib/io/io.i
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am
   gnuradio/trunk/gnuradio-examples/python/audio/Makefile.am
Log:
Merged -r7723:7729 from jcorgan/wav into trunk, with added example program.  
Adds Martin Braun's gr.wavfile_source and gr.wavfile_sink blocks.

Modified: gnuradio/trunk/gnuradio-core/src/lib/io/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/Makefile.am 2008-02-18 06:02:59 UTC 
(rev 7729)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/Makefile.am 2008-02-18 06:27:50 UTC 
(rev 7730)
@@ -53,7 +53,10 @@
        ppio_ppdev.cc                   \
        sdr_1000.cc                     \
        gr_udp_sink.cc                  \
-       gr_udp_source.cc
+       gr_udp_source.cc                \
+       gr_wavfile_sink.cc              \
+       gr_wavfile_source.cc            \
+       gri_wavfile.cc
 
 grinclude_HEADERS =                    \
        gr_file_sink.h                  \
@@ -83,9 +86,14 @@
        ppio_ppdev.h                    \
        sdr_1000.h                      \
        gr_udp_sink.h                   \
-       gr_udp_source.h
+       gr_udp_source.h                 \
+       gr_wavfile_source.h             \
+       gr_wavfile_sink.h               \
+       gri_wavfile.h
 
 
+
+
 swiginclude_HEADERS =                  \
        io.i                            \
        gr_file_sink.i                  \
@@ -102,4 +110,7 @@
        ppio.i                          \
        sdr_1000.i                      \
        gr_udp_sink.i                   \
-       gr_udp_source.i
+       gr_udp_source.i                 \
+       gr_wavfile_source.i             \
+       gr_wavfile_sink.i
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.cc (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_sink.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.cc                  
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.cc  2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,278 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2006,2007,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_wavfile_sink.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <stdexcept>
+#include <climits>
+#include <cstring>
+#include <cmath>
+#include <fcntl.h>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define OUR_O_BINARY O_BINARY
+#else
+#define OUR_O_BINARY 0
+#endif
+
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define OUR_O_LARGEFILE 0
+#endif
+
+
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink(const char *filename,
+                    int n_channels,
+                    unsigned int sample_rate,
+                    int bits_per_sample)
+{
+  return gr_wavfile_sink_sptr (new gr_wavfile_sink (filename,
+                                                   n_channels,
+                                                   sample_rate,
+                                                   bits_per_sample));
+}
+
+gr_wavfile_sink::gr_wavfile_sink(const char *filename,
+                                int n_channels,
+                                unsigned int sample_rate,
+                                int bits_per_sample)
+  : gr_sync_block ("wavfile_sink",
+                  gr_make_io_signature(1, n_channels, sizeof(float)),
+                  gr_make_io_signature(0, 0, 0)),
+    d_sample_rate(sample_rate), d_nchans(n_channels),
+    d_fp(0), d_new_fp(0), d_updated(false)
+{
+  if (bits_per_sample != 8 && bits_per_sample != 16) {
+    throw std::runtime_error("Invalid bits per sample (supports 8 and 16)");
+  }
+  d_bytes_per_sample = bits_per_sample / 8;
+  d_bytes_per_sample_new = d_bytes_per_sample;
+  
+  if (!open(filename)) {
+    throw std::runtime_error ("can't open file");
+  }
+
+  if (bits_per_sample == 8) {
+    d_max_sample_val = 0xFF;
+    d_min_sample_val = 0;
+    d_normalize_fac  = d_max_sample_val/2;
+    d_normalize_shift = 1;
+  } else {
+    d_max_sample_val = 0x7FFF;
+    d_min_sample_val = -0x7FFF;
+    d_normalize_fac  = d_max_sample_val;
+    d_normalize_shift = 0;
+    if (bits_per_sample != 16) {
+      fprintf(stderr, "Invalid bits per sample value requested, using 16");
+    }
+  }
+}
+
+
+bool
+gr_wavfile_sink::open(const char* filename)
+{
+  omni_mutex_lock l(d_mutex);
+  
+  // we use the open system call to get access to the O_LARGEFILE flag.
+  int fd;
+  if ((fd = ::open (filename,
+                   O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY,
+                   0664)) < 0){
+    perror (filename);
+    return false;
+  }
+
+  if (d_new_fp) {    // if we've already got a new one open, close it
+    fclose(d_new_fp);
+    d_new_fp = 0;
+  }
+  
+  if ((d_new_fp = fdopen (fd, "wb")) == NULL) {
+    perror (filename);
+    ::close(fd);  // don't leak file descriptor if fdopen fails.
+    return false;
+  }
+  d_updated = true;
+  
+  if (!gri_wavheader_write(d_new_fp,
+                          d_sample_rate,
+                          d_nchans,
+                          d_bytes_per_sample_new)) {
+    fprintf(stderr, "[%s] could not write to WAV file\n", __FILE__);
+    exit(-1);
+  }
+  
+  return true;
+}
+
+
+void
+gr_wavfile_sink::close()
+{
+  omni_mutex_lock l(d_mutex);
+  
+  if (!d_fp)
+    return;
+  
+  close_wav();
+}
+
+void gr_wavfile_sink::close_wav()
+{
+  unsigned int byte_count = d_sample_count * d_bytes_per_sample;
+  
+  gri_wavheader_complete(d_fp, byte_count);
+  
+  fclose(d_fp);
+  d_fp = NULL;
+}
+
+
+gr_wavfile_sink::~gr_wavfile_sink ()
+{
+  if (d_new_fp) {
+    fclose(d_new_fp);
+  }
+
+  close();
+}
+
+
+int
+gr_wavfile_sink::work (int noutput_items,
+                      gr_vector_const_void_star &input_items,
+                      gr_vector_void_star &output_items)
+{
+  float **in = (float **) &input_items[0];
+  int n_in_chans = input_items.size();
+  
+  short int sample_buf_s;
+  
+  int nwritten;
+  
+  do_update(); // update: d_fp is reqd
+  if (!d_fp)   // drop output on the floor
+    return noutput_items;
+  
+  for (nwritten = 0; nwritten < noutput_items; nwritten++) {
+    for (int chan = 0; chan < d_nchans; chan++) {
+      // Write zeros to channels which are in the WAV file
+      // but don't have any inputs here
+      if (chan < n_in_chans) {
+       sample_buf_s = 
+         convert_to_short(in[chan][nwritten]);
+      } else {
+       sample_buf_s = 0;
+      }
+      
+      gri_wav_write_sample(d_fp, sample_buf_s, d_bytes_per_sample);
+      
+      if (feof(d_fp) || ferror(d_fp)) {
+       fprintf(stderr, "[%s] file i/o error\n", __FILE__);
+       close();
+       exit(-1);
+      }
+      d_sample_count++;
+    }
+  }
+  
+  return nwritten;
+}
+
+
+short int
+gr_wavfile_sink::convert_to_short(float sample)
+{
+  sample += d_normalize_shift;
+  sample *= d_normalize_fac;
+  if (sample > d_max_sample_val) {
+    sample = d_max_sample_val;
+  } else if (sample < d_min_sample_val) {
+    sample = d_min_sample_val;
+  }
+  
+  return (short int) roundf(sample);
+}
+
+
+void
+gr_wavfile_sink::set_bits_per_sample(int bits_per_sample)
+{
+  omni_mutex_lock l(d_mutex);
+  if (bits_per_sample == 8 || bits_per_sample == 16) {
+    d_bytes_per_sample_new = bits_per_sample / 8;
+  }
+}
+
+
+void
+gr_wavfile_sink::set_sample_rate(unsigned int sample_rate)
+{
+  omni_mutex_lock l(d_mutex);
+  d_sample_rate = sample_rate;
+}
+
+
+void
+gr_wavfile_sink::do_update()
+{
+  if (!d_updated) {
+    return;
+  }
+  
+  omni_mutex_lock     l(d_mutex);     // hold mutex for duration of this block
+  if (d_fp) {
+    close_wav();
+  }
+
+  d_fp = d_new_fp;                    // install new file pointer
+  d_new_fp  = 0;
+  d_sample_count = 0;
+  d_bytes_per_sample = d_bytes_per_sample_new;
+
+  if (d_bytes_per_sample == 1) {
+    d_max_sample_val = UCHAR_MAX;
+    d_min_sample_val = 0;
+    d_normalize_fac  = d_max_sample_val/2;
+    d_normalize_shift = 1;
+  } else if (d_bytes_per_sample == 2) {
+    d_max_sample_val = SHRT_MAX;
+    d_min_sample_val = SHRT_MIN;
+    d_normalize_fac  = d_max_sample_val;
+    d_normalize_shift = 0;
+  }
+  
+  d_updated = false;
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.h (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_sink.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.h                   
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.h   2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,137 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_WAVFILE_SINK_H
+#define INCLUDED_GR_WAVFILE_SINK_H
+
+#include <gr_sync_block.h>
+#include <gr_file_sink_base.h>
+#include <omnithread.h>
+
+class gr_wavfile_sink;
+typedef boost::shared_ptr<gr_wavfile_sink> gr_wavfile_sink_sptr;
+
+/*
+ * \p filename The .wav file to be opened
+ * \p n_channels Number of channels (2 = stereo or I/Q output)
+ * \p sample_rate Sample rate [S/s]
+ * \p bits_per_sample 16 or 8 bit, default is 16
+ */
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+                     int n_channels,
+                     unsigned int sample_rate,
+                     int bits_per_sample = 16);
+
+/*!
+ * \brief Read stream from a Microsoft PCM (.wav) file, output floats
+ *
+ * Values are within [-1;1].
+ * Check gr_make_wavfile_source() for extra info.
+ *
+ * \ingroup sink
+ */
+class gr_wavfile_sink : public gr_sync_block
+{
+private:
+  friend gr_wavfile_sink_sptr gr_make_wavfile_sink (const char *filename,
+                                                   int n_channels,
+                                                   unsigned int sample_rate,
+                                                   int bits_per_sample);
+
+  gr_wavfile_sink(const char *filename,
+                 int n_channels,
+                 unsigned int sample_rate,
+                 int bits_per_sample);
+
+  unsigned d_sample_rate;
+  int d_nchans;
+  unsigned d_sample_count;
+  int d_bytes_per_sample;
+  int d_bytes_per_sample_new;
+  int d_max_sample_val;
+  int d_min_sample_val;
+  int d_normalize_shift;
+  int d_normalize_fac;
+
+  FILE *d_fp;
+  FILE *d_new_fp;
+  bool d_updated;
+  omni_mutex d_mutex;
+  
+  /*!
+   * \brief Convert a sample value within [-1;+1] to a corresponding
+   *  short integer value
+   */
+  short convert_to_short(float sample);
+
+  /*!
+   * \brief Writes information to the WAV header which is not available
+   * a-priori (chunk size etc.) and closes the file. Not thread-safe and
+   * assumes d_fp is a valid file pointer, should thus only be called by
+   * other methods.
+   */
+  void close_wav();
+
+public:
+  ~gr_wavfile_sink ();
+
+  /*!
+   * \brief Opens a new file and writes a WAV header. Thread-safe.
+   */
+  bool open(const char* filename);
+
+  /*!
+   * \brief Closes the currently active file and completes the WAV
+   * header. Thread-safe.
+   */
+  void close();
+
+  /*!
+   * \brief If any file changes have occurred, update now. This is called
+   * internally by work() and thus doesn't usually need to be called by
+   * hand.
+   */
+  void do_update();
+  
+  /*!
+   * \brief Set the sample rate. This will not affect the WAV file
+   * currently opened. Any following open() calls will use this new
+   * sample rate.
+   */
+  void set_sample_rate(unsigned int sample_rate);
+  
+  /*!
+   * \brief Set bits per sample. This will not affect the WAV file
+   * currently opened (see set_sample_rate()). If the value is neither
+   * 8 nor 16, the call is ignored and the current value is kept.
+   */
+  void set_bits_per_sample(int bits_per_sample);
+  
+  
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+  
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SINK_H */

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.i (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_sink.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.i                   
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_sink.i   2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,47 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_sink);
+
+gr_wavfile_sink_sptr
+gr_make_wavfile_sink (const char *filename,
+                     int n_channels,
+                     unsigned int sample_rate,
+                     int bits_per_sample = 16) throw (std::runtime_error);
+
+class gr_wavfile_sink : public gr_sync_block
+{
+protected:
+  gr_wavfile_sink(const char *filename,
+                 int n_channels,
+                 unsigned int sample_rate,
+                 int bits_per_sample) throw (std::runtime_error);
+  
+public:
+  ~gr_wavfile_sink ();
+  bool open(const char* filename);
+  void close();
+  void set_sample_rate(unsigned int sample_rate);
+  void set_bits_per_sample(int bits_per_sample);
+};
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.cc (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_source.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.cc                
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.cc        
2008-02-18 06:27:50 UTC (rev 7730)
@@ -0,0 +1,172 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_wavfile_source.h>
+#include <gr_io_signature.h>
+#include <gri_wavfile.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <stdexcept>
+
+// win32 (mingw/msvc) specific
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef O_BINARY
+#define        OUR_O_BINARY O_BINARY
+#else
+#define        OUR_O_BINARY 0
+#endif
+// should be handled via configure
+#ifdef O_LARGEFILE
+#define        OUR_O_LARGEFILE O_LARGEFILE
+#else
+#define        OUR_O_LARGEFILE 0
+#endif
+
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat)
+{
+  return gr_wavfile_source_sptr (new gr_wavfile_source (filename, repeat));
+}
+
+
+gr_wavfile_source::gr_wavfile_source (const char *filename, bool repeat)
+  : gr_sync_block ("wavfile_source",
+                  gr_make_io_signature (0, 0, 0),
+                  gr_make_io_signature (1, 2, sizeof(float))),
+    d_fp(NULL), d_repeat(repeat),
+    d_sample_rate(1), d_nchans(1), d_bytes_per_sample(2), 
d_first_sample_pos(0),
+    d_samples_per_chan(0), d_sample_idx(0)
+{
+  // we use "open" to use to the O_LARGEFILE flag
+
+  int fd;
+  if ((fd = open (filename, O_RDONLY | OUR_O_LARGEFILE | OUR_O_BINARY)) < 0) {
+    perror (filename);
+    throw std::runtime_error ("can't open file");
+  }
+
+  if ((d_fp = fdopen (fd, "rb")) == NULL) {
+    perror (filename);
+    throw std::runtime_error ("can't open file");
+  }
+
+  // Scan headers, check file validity
+  if (!gri_wavheader_parse(d_fp,
+                          d_sample_rate,
+                          d_nchans,
+                          d_bytes_per_sample,
+                          d_first_sample_pos,
+                          d_samples_per_chan)) {
+    throw std::runtime_error("is not a valid wav file");
+  }
+  
+  if (d_samples_per_chan == 0) {
+    throw std::runtime_error("WAV file does not contain any samples");
+  }
+
+  if (d_bytes_per_sample == 1) {
+    d_normalize_fac   = 128;
+    d_normalize_shift = 1;
+  } else {
+    d_normalize_fac   = 0x7FFF;
+    d_normalize_shift = 0;
+  }
+
+  // Re-set the output signature
+  set_output_signature(gr_make_io_signature(1, d_nchans, sizeof(float)));
+}
+
+
+gr_wavfile_source::~gr_wavfile_source ()
+{
+  fclose(d_fp);
+}
+
+
+int
+gr_wavfile_source::work(int noutput_items,
+                       gr_vector_const_void_star &input_items,
+                       gr_vector_void_star &output_items)
+{
+  float **out = (float **) &output_items[0];
+  int n_out_chans = output_items.size();
+
+  int i;
+  short sample;
+
+  for (i = 0; i < noutput_items; i++) {
+    if (d_sample_idx >= d_samples_per_chan) {
+      if (!d_repeat) {
+       // if nothing was read at all, say we're done.
+       return i ? i : -1;
+      }
+
+      if (fseek (d_fp, d_first_sample_pos, SEEK_SET) == -1) {
+       fprintf(stderr, "[%s] fseek failed\n", __FILE__);
+       exit(-1);
+      }
+
+      d_sample_idx = 0;
+    }
+    
+    for (int chan = 0; chan < d_nchans; chan++) {
+      sample = gri_wav_read_sample(d_fp, d_bytes_per_sample);
+
+      if (chan < n_out_chans) {
+       out[chan][i] = convert_to_float(sample);
+      }
+    }
+
+    d_sample_idx++;
+    
+    // OK, EOF is not necessarily an error. But we're not going to
+    // deal with handling corrupt wav files, so if they give us any
+    // trouble they won't be processed. Serves them bloody right.
+    if (feof(d_fp) || ferror(d_fp)) {
+      if (i == 0) {
+       fprintf(stderr, "[%s] WAV file has corrupted header or i/o error\n", 
__FILE__);
+       return -1;
+      }
+      return i;
+    }
+  }
+  
+  return noutput_items;
+}
+
+
+float
+gr_wavfile_source::convert_to_float(short int sample)
+{
+  float sample_out = (float) sample;
+  sample_out /= d_normalize_fac;
+  sample_out -= d_normalize_shift;
+  return sample_out;
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.h (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_source.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.h                 
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.h 2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_WAVFILE_SOURCE_H
+#define INCLUDED_GR_WAVFILE_SOURCE_H
+
+#include <gr_sync_block.h>
+
+class gr_wavfile_source;
+typedef boost::shared_ptr<gr_wavfile_source> gr_wavfile_source_sptr;
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename, bool repeat = false);
+
+/*!
+ * \brief Read stream from a Microsoft PCM (.wav) file, output floats
+ *
+ * Unless otherwise called, values are within [-1;1].
+ * Check gr_make_wavfile_source() for extra info.
+ *
+ * \ingroup source
+ */
+
+class gr_wavfile_source : public gr_sync_block
+{
+private:
+  friend gr_wavfile_source_sptr gr_make_wavfile_source (const char *filename,
+                                                             bool repeat);
+  gr_wavfile_source(const char *filename, bool repeat);
+
+  FILE *d_fp;
+  bool d_repeat;
+  
+  unsigned d_sample_rate;
+  int d_nchans;
+  int d_bytes_per_sample;
+  int d_first_sample_pos;
+  unsigned d_samples_per_chan;
+  unsigned d_sample_idx;
+  int d_normalize_shift;
+  int d_normalize_fac;
+  
+  /*!
+   * \brief Convert an integer sample value to a float value within [-1;1]
+   */
+  float convert_to_float(short int sample);
+
+public:
+  ~gr_wavfile_source ();
+  
+  int work(int noutput_items,
+          gr_vector_const_void_star &input_items,
+          gr_vector_void_star &output_items);
+
+  /*!
+   * \brief Read the sample rate as specified in the wav file header
+   */
+  unsigned int sample_rate() const { return d_sample_rate; };
+
+  /*!
+   * \brief Return the number of bits per sample as specified in the wav
+   * file header. Only 8 or 16 bit are supported here.
+   */
+  int bits_per_sample() const { return d_bytes_per_sample * 8; };
+  
+  /*!
+   * \brief Return the number of channels in the wav file as specified in
+   * the wav file header. This is also the max number of outputs you can
+   * have.
+   */
+  int channels() const { return d_nchans; };
+};
+
+#endif /* INCLUDED_GR_WAVFILE_SOURCE_H */

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.i (from rev 
7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gr_wavfile_source.i)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.i                 
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gr_wavfile_source.i 2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+GR_SWIG_BLOCK_MAGIC(gr,wavfile_source);
+
+gr_wavfile_source_sptr
+gr_make_wavfile_source (const char *filename,
+                        bool repeat = false) throw (std::runtime_error);
+
+class gr_wavfile_source : public gr_sync_block
+{
+private:
+  gr_wavfile_source(const char *filename,
+                   bool repeat) throw (std::runtime_error);
+
+public:
+  ~gr_wavfile_source();
+
+  unsigned int sample_rate();
+  int bits_per_sample();
+  int channels();
+};
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.cc (from rev 7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gri_wavfile.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.cc                      
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.cc      2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,312 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gri_wavfile.h>
+#include <cstring>
+#include <stdint.h>
+
+# define VALID_COMPRESSION_TYPE 0x0001
+
+// WAV files are always little-endian, so we need some byte switching macros
+
+// FIXME: These need to be refactored into a separate endianess header file
+// as they duplicate routines defined in usrp/host/lib/legacy/usrp_bytesex.h
+
+#ifdef WORDS_BIGENDIAN
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+#warning Using non-portable code (likely wrong other than ILP32).
+
+static inline short int
+bswap_16 (unsigned short int x)
+{
+  return ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8));
+}
+
+static inline unsigned int
+bswap_32 (unsigned int x)
+{
+  return ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8)      \
+         | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
+}
+#endif // HAVE_BYTESWAP_H
+
+static inline uint32_t
+host_to_wav(uint32_t x)
+{
+  return bswap_32(x);
+}
+
+static inline uint16_t
+host_to_wav(uint16_t x)
+{
+  return bswap_16(x);
+}
+
+static inline int16_t
+host_to_wav(int16_t x)
+{
+  return bswap_32(x);
+}
+
+static inline uint32_t
+wav_to_host(uint32_t x)
+{
+  return bswap_32(x);
+}
+
+static inline uint16_t
+wav_to_host(uint16_t x)
+{
+  return bswap_16(x);
+}
+
+static inline int16_t
+wav_to_host(int16_t x)
+{
+  return bswap_32(x);
+}
+
+#else
+
+static inline uint32_t
+host_to_wav(uint32_t x)
+{
+  return x;
+}
+
+static inline uint16_t
+host_to_wav(uint16_t x)
+{
+  return x;
+}
+
+static inline int16_t
+host_to_wav(int16_t x)
+{
+  return x;
+}
+
+static inline uint32_t
+wav_to_host(uint32_t x)
+{
+  return x;
+}
+
+static inline uint16_t
+wav_to_host(uint16_t x)
+{
+  return x;
+}
+
+static inline int16_t
+wav_to_host(int16_t x)
+{
+  return x;
+}
+
+#endif // WORDS_BIGENDIAN
+
+
+bool
+gri_wavheader_parse(FILE *fp,
+                   unsigned int &sample_rate_o,
+                   int &nchans_o,
+                   int &bytes_per_sample_o,
+                   int &first_sample_pos_o,
+                   unsigned int &samples_per_chan_o)
+{
+  // _o variables take return values
+  char str_buf[8] = {0};
+  
+  uint32_t file_size;
+  uint32_t fmt_hdr_skip;
+  uint16_t compression_type;
+  uint16_t nchans;
+  uint32_t sample_rate;
+  uint32_t avg_bytes_per_sec;
+  uint16_t block_align;
+  uint16_t bits_per_sample;
+  uint32_t chunk_size;
+  
+  size_t fresult;
+
+  fresult = fread(str_buf, 1, 4, fp);
+  if (fresult != 4 || strncmp(str_buf, "RIFF", 4) || feof(fp)) {
+    return false;
+  }
+  
+  fread(&file_size, 1, 4, fp);
+  
+  fresult = fread(str_buf, 1, 8, fp);
+  if (fresult != 8 || strncmp(str_buf, "WAVEfmt ", 8) || feof(fp)) {
+    return false;
+  }
+  
+  fread(&fmt_hdr_skip, 1, 4, fp);
+  
+  fread(&compression_type, 1, 2, fp);
+  if (wav_to_host(compression_type) != VALID_COMPRESSION_TYPE) {
+    return false;
+  }
+  
+  fread(&nchans,            1, 2, fp);
+  fread(&sample_rate,       1, 4, fp);
+  fread(&avg_bytes_per_sec, 1, 4, fp);
+  fread(&block_align,       1, 2, fp);
+  fread(&bits_per_sample,   1, 2, fp);
+  
+  if (ferror(fp)) {
+    return false;
+  }
+  
+  fmt_hdr_skip    = wav_to_host(fmt_hdr_skip);
+  nchans          = wav_to_host(nchans);
+  sample_rate     = wav_to_host(sample_rate);
+  bits_per_sample = wav_to_host(bits_per_sample);
+  
+  if (bits_per_sample != 8 && bits_per_sample != 16) {
+    return false;
+  }
+  
+  fmt_hdr_skip -= 16;
+  if (fmt_hdr_skip) {
+    fseek(fp, fmt_hdr_skip, SEEK_CUR);
+  }
+  
+  // data chunk
+  fresult = fread(str_buf, 1, 4, fp);
+  if (strncmp(str_buf, "data", 4)) {
+    return false;
+  }
+
+  fread(&chunk_size, 1, 4, fp);
+  if (ferror(fp)) {
+    return false;
+  }
+  
+  // More byte swapping
+  chunk_size = wav_to_host(chunk_size);
+  
+  // Output values
+  sample_rate_o      = (unsigned) sample_rate;
+  nchans_o           = (int) nchans;
+  bytes_per_sample_o = (int) (bits_per_sample / 8);
+  first_sample_pos_o = (int) ftell(fp);
+  samples_per_chan_o = (unsigned) (chunk_size / (bytes_per_sample_o * nchans));
+  return true;
+}
+
+
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample)
+{
+  int16_t buf = 0;
+  fread(&buf, bytes_per_sample, 1, fp);
+  
+  return (short) wav_to_host(buf);
+}
+
+
+bool
+gri_wavheader_write(FILE *fp,
+                   unsigned int sample_rate,
+                   int nchans,
+                   int bytes_per_sample)
+{
+  const int header_len = 44;
+  char wav_hdr[header_len] = "RIFF\0\0\0\0WAVEfmt 
\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0data\0\0\0";
+  uint16_t nchans_f        = (uint16_t) nchans;
+  uint32_t sample_rate_f   = (uint32_t) sample_rate;
+  uint16_t block_align     = bytes_per_sample * nchans;
+  uint32_t avg_bytes       = sample_rate * block_align;
+  uint16_t bits_per_sample = bytes_per_sample * 8;
+  
+  nchans_f        = host_to_wav(nchans_f);
+  sample_rate_f   = host_to_wav(sample_rate_f);
+  block_align     = host_to_wav(block_align);
+  avg_bytes       = host_to_wav(avg_bytes);
+  bits_per_sample = host_to_wav(bits_per_sample);
+  
+  wav_hdr[16] = 0x10; // no extra bytes
+  wav_hdr[20] = 0x01; // no compression
+  memcpy((void *) (wav_hdr + 22), (void *) &nchans_f,        2);
+  memcpy((void *) (wav_hdr + 24), (void *) &sample_rate_f,   4);
+  memcpy((void *) (wav_hdr + 28), (void *) &avg_bytes,       4);
+  memcpy((void *) (wav_hdr + 32), (void *) &block_align,     2);
+  memcpy((void *) (wav_hdr + 34), (void *) &bits_per_sample, 2);
+  
+  fwrite(&wav_hdr, 1, header_len, fp);
+  if (ferror(fp)) {
+    return false;
+  }
+  
+  return true;
+}
+
+
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample)
+{
+  void *data_ptr;
+  unsigned char buf_8bit;
+  int16_t       buf_16bit;
+  
+  if (bytes_per_sample == 1) {
+    buf_8bit = (unsigned char) sample;
+    data_ptr = (void *) &buf_8bit;
+  } else {
+    buf_16bit = host_to_wav((int16_t) sample);
+    data_ptr  = (void *) &buf_16bit;
+  }
+  
+  fwrite(data_ptr, 1, bytes_per_sample, fp);
+}
+
+
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count)
+{
+  uint32_t chunk_size = (uint32_t) byte_count;
+  chunk_size = host_to_wav(chunk_size);
+  
+  fseek(fp, 40, SEEK_SET);
+  fwrite(&chunk_size, 1, 4, fp);
+  
+  chunk_size = (uint32_t) byte_count + 36; // fmt chunk and data header
+  chunk_size = host_to_wav(chunk_size);
+  fseek(fp, 4, SEEK_SET);
+  
+  fwrite(&chunk_size, 1, 4, fp);
+  
+  if (ferror(fp)) {
+    return false;
+  }
+  
+  return true;
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.h (from rev 7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/lib/io/gri_wavfile.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.h                       
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/gri_wavfile.h       2008-02-18 
06:27:50 UTC (rev 7730)
@@ -0,0 +1,100 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// This file stores all the RIFF file type knowledge for the gr_wavfile_*
+// blocks.
+
+#include <cstdio>
+
+/*!
+ * \brief Read signal information from a given WAV file.
+ *
+ * \p fp File pointer to an opened, empty file.
+ * \p sample_rate Stores the sample rate [S/s]
+ * \p nchans      Number of channels
+ * \p bytes_per_sample Bytes per sample, can either be 1 or 2 (corresponding to
+ *         8 or 16 bit samples, respectively)
+ * \p first_sample_pos Number of the first byte containing a sample. Use this
+ *         with fseek() to jump from the end of the file to the first sample
+ *         when in repeat mode.
+ * \p samples_per_chan Number of samples per channel
+ * \p normalize_fac The normalization factor with which you need to divide the
+ *         integer values of the samples to get them within [-1;1]
+ * \p normalize_shift The value by which the sample values need to be shifted
+ *         after normalization (reason being, 8-bit WAV files store samples as
+ *         unsigned char and 16-bit as signed short int)
+ * \return True on a successful read, false if the file could not be read or is
+ *         not a valid WAV file.
+ */
+bool
+gri_wavheader_parse(FILE *fp,
+                   unsigned int &sample_rate,
+                   int &nchans,
+                   int &bytes_per_sample,
+                   int &first_sample_pos,
+                   unsigned int &samples_per_chan);
+
+
+/*!
+ * \brief Read one sample from an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+short int
+gri_wav_read_sample(FILE *fp, int bytes_per_sample);
+
+
+/*!
+ * \brief Write a valid RIFF file header
+ *
+ * Note: Some header values are kept blank because they're usually not known
+ * a-priori (file and chunk lengths). Use gri_wavheader_complete() to fill
+ * these in.
+ */
+bool
+gri_wavheader_write(FILE *fp,
+                unsigned int sample_rate,
+                int nchans,
+                int bytes_per_sample);
+
+/*!
+ * \brief Write one sample to an open WAV file at the current position.
+ *
+ * Takes care of endianness.
+ */
+void
+gri_wav_write_sample(FILE *fp, short int sample, int bytes_per_sample);
+
+
+/*!
+ * \brief Complete a WAV header
+ *
+ * Note: The stream position is changed during this function. If anything
+ * needs to be written to the WAV file after calling this function (which
+ * shouldn't happen), you  need to fseek() to the end of the file (or 
+ * whereever).
+ *
+ * \p fp File pointer to an open WAV file with a blank header
+ * \p byte_count Length of all samples written to the file in bytes.
+ */
+bool
+gri_wavheader_complete(FILE *fp, unsigned int byte_count);

Modified: gnuradio/trunk/gnuradio-core/src/lib/io/io.i
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/io/io.i        2008-02-18 06:02:59 UTC 
(rev 7729)
+++ gnuradio/trunk/gnuradio-core/src/lib/io/io.i        2008-02-18 06:27:50 UTC 
(rev 7730)
@@ -36,6 +36,8 @@
 #include <gr_message_sink.h>
 #include <gr_udp_sink.h>
 #include <gr_udp_source.h>
+#include <gr_wavfile_sink.h>
+#include <gr_wavfile_source.h>
 
 %}
 
@@ -54,4 +56,6 @@
 %include "gr_message_sink.i"
 %include "gr_udp_sink.i"
 %include "gr_udp_source.i"
+%include "gr_wavfile_sink.i"
+%include "gr_wavfile_source.i"
 

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am     
2008-02-18 06:02:59 UTC (rev 7729)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/Makefile.am     
2008-02-18 06:27:50 UTC (rev 7730)
@@ -21,9 +21,10 @@
 
 include $(top_srcdir)/Makefile.common
 
-EXTRA_DIST = run_tests.in
+EXTRA_DIST =                   \
+       run_tests.in            \
+       test_16bit_1chunk.wav
 
-
 TESTS =                        \
        run_tests
 

Copied: gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py 
(from rev 7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py          
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_wavefile.py  
2008-02-18 06:27:50 UTC (rev 7730)
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright 2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+from gnuradio import gr, gr_unittest
+
+import os
+from os.path import getsize
+
+class qa_wavefile(gr_unittest.TestCase):
+
+    def setUp (self):
+        self.tb = gr.top_block ()
+
+    def tearDown (self):
+        self.tb = None
+
+    def test_001_checkwavread (self):
+       wf = gr.wavfile_source("./test_16bit_1chunk.wav")
+       self.assertEqual(wf.sample_rate(), 8000)
+
+    def test_002_checkwavcopy (self):
+       infile  = "test_16bit_1chunk.wav"
+       outfile = "test_out.wav"
+
+       wf_in  = gr.wavfile_source(infile)
+       wf_out = gr.wavfile_sink(outfile,
+                                wf_in.channels(),
+                                wf_in.sample_rate(),
+                                wf_in.bits_per_sample())
+       self.tb.connect(wf_in, wf_out)
+       self.tb.run()
+       wf_out.close()
+
+       self.assertEqual(getsize(infile), getsize(outfile))
+
+       in_f  = file(infile,  'rb')
+       out_f = file(outfile, 'rb')
+
+       in_data  = in_f.read(getsize(infile))
+       out_data = out_f.read(getsize(outfile))
+       os.remove(outfile)
+       
+       self.assertEqual(in_data, out_data)
+
+
+if __name__ == '__main__':
+    gr_unittest.main ()

Copied: 
gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav (from 
rev 7729, 
gnuradio/branches/developers/jcorgan/wav/gnuradio-core/src/python/gnuradio/gr/test_16bit_1chunk.wav)
===================================================================
(Binary files differ)

Modified: gnuradio/trunk/gnuradio-examples/python/audio/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/audio/Makefile.am   2008-02-18 
06:02:59 UTC (rev 7729)
+++ gnuradio/trunk/gnuradio-examples/python/audio/Makefile.am   2008-02-18 
06:27:50 UTC (rev 7730)
@@ -27,6 +27,7 @@
        audio_play.py           \
        audio_to_file.py        \
        dial_tone.py            \
+       dial_tone_wav.py        \
        mono_tone.py            \
        multi_tone.py           \
        noise.py                \

Added: gnuradio/trunk/gnuradio-examples/python/audio/dial_tone_wav.py
===================================================================
--- gnuradio/trunk/gnuradio-examples/python/audio/dial_tone_wav.py              
                (rev 0)
+++ gnuradio/trunk/gnuradio-examples/python/audio/dial_tone_wav.py      
2008-02-18 06:27:50 UTC (rev 7730)
@@ -0,0 +1,61 @@
+#!/usr/bin/env python
+#
+# Copyright 2004,2005,2007,2008 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+# GNU Radio example program to record a dial tone to a WAV file
+
+from gnuradio import gr
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+
+class my_top_block(gr.top_block):
+
+    def __init__(self):
+        gr.top_block.__init__(self)
+
+       usage = "%prog: [options] filename"
+        parser = OptionParser(option_class=eng_option, usage=usage)
+        parser.add_option("-r", "--sample-rate", type="eng_float", 
default=48000,
+                          help="set sample rate to RATE (48000)")
+       parser.add_option("-N", "--samples", type="eng_float", default=None,
+                         help="number of samples to record")
+        (options, args) = parser.parse_args ()
+        if len(args) != 1 or options.samples is None:
+            parser.print_help()
+            raise SystemExit, 1
+
+        sample_rate = int(options.sample_rate)
+        ampl = 0.1
+
+        src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
+        src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)
+       head0 = gr.head(gr.sizeof_float, int(options.samples))
+       head1 = gr.head(gr.sizeof_float, int(options.samples))
+       dst = gr.wavfile_sink(args[0], 2, int(options.sample_rate), 16)
+
+        self.connect(src0, head0, (dst, 0))
+        self.connect(src1, head1, (dst, 1))
+
+if __name__ == '__main__':
+    try:
+        my_top_block().run()
+    except KeyboardInterrupt:
+        pass


Property changes on: 
gnuradio/trunk/gnuradio-examples/python/audio/dial_tone_wav.py
___________________________________________________________________
Name: svn:executable
   + *





reply via email to

[Prev in Thread] Current Thread [Next in Thread]